欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringMVC入门 -- 参数绑定

程序员文章站 2022-05-26 15:17:44
一、REST与RESTful 1、简介 (1)REST(Representational State Transfer):表现层状态转移,一种软件架构风格,不是标准。REST描述的是在网络中client和server的一种交互形式,即资源在网络中以某种表现形式进行状态转移。(2)基于REST构建的A ......

一、rest与restful

1、简介

(1)rest(representational state transfer):表现层状态转移,一种软件架构风格,不是标准。rest描述的是在网络中client和server的一种交互形式,即资源在网络中以某种表现形式进行状态转移。
(2)基于rest构建的api就是restful风格。

2、相关概念

(1)资源(resources):指的是网络上的一个具体的信息(文本、图片等),通过一个url可以唯一的指向它。
(2)表现层(representational ):将信息表现出来的形式,比如使用txt表示文本,或者html表示文本。
(3)状态转移(state transfer):客户端每发送一次请求到服务器,服务器响应会涉及到数据以及状态的切换。而http属于一种无状态的协议,所有状态均保存在服务端,客户端想要去操作服务端,则需要通过某种手段(http协议里的动词)使服务端发生状态转移,且显示在表现层。

3、常见http动词

(1)get(select): 从服务器获取资源(一项或多项)
(2)post(create): 在服务器新建一个资源
(3)put(update): 在服务器更新资源(客户端提供改变后的完整资源)
(4)delete(delete):从服务器删除资源。

4、使用样例

(1)浏览器的 form 表单只支持 get 与 post请求,不支持 delete、put 请求。
(2)spring 3.0后,添加了一个过滤器(hiddenhttpmethodfilter),可以将post请求转为delete、put请求,从而整体支持 delete、put、get、post。
(3)发送 put 请求和 delete 请求的实现步骤:
  step1:需要在web.xml配置 hiddenhttpmethodfilter
  step2:需要发送 post 请求
  step3:需要在发送 post 请求时携带一个 name="_method" 的隐藏域, 值为 delete 或 put

【主要操作:】

【web.xml中配置 过滤器】
<filter>
    <filter-name>hiddenhttpmethodfilter</filter-name>
    <filter-class>org.springframework.web.filter.hiddenhttpmethodfilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>hiddenhttpmethodfilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

【即web.xml】
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
         xsi:schemalocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.dispatcherservlet</servlet-class>
        <init-param>
            <param-name>contextconfiglocation</param-name>
            <param-value>classpath:dispatcher-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--配置过滤器,将post请求转为delete,put-->
    <filter>
        <filter-name>hiddenhttpmethodfilter</filter-name>
        <filter-class>org.springframework.web.filter.hiddenhttpmethodfilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>hiddenhttpmethodfilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

【index.jsp中配置 请求】
<%@ page language="java" contenttype="text/html; charset=utf-8"
         pageencoding="utf-8" iserrorpage="true"%>
<html>
  <head>
    <title>首页</title>
  </head>
  <body>
    <%--测试get请求--%>
    <form action="/testrestful/1">
      <input type="submit" value="test get"/>
    </form>

    <%--测试post请求--%>
    <form action="/testrestful" method="post">
      <input type="submit" value="test post"/>
    </form>

    <%--测试post请求,不转为delete、put请求--%>
    <form action="/testrestful/1" method="post">
      <input type="submit" value="test post2"/>
    </form>

    <%--测试post请求,转为put请求--%>
    <form action="/testrestful/1" method="post">
      <input type="hidden" name="_method" value="put"/>
      <input type="submit" value="test put"/>
    </form>

    <%--测试post请求,转为delete请求--%>
    <form action="/testrestful/1" method="post">
      <input type="hidden" name="_method" value="delete"/>
      <input type="submit" value="test delete"/>
    </form>
  </body>
</html>

【hellocontroller.java 中处理请求:】
package com.lyh.controller;

import org.springframework.stereotype.controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.modelandview;

@controller
public class hellocontroller {

    // 测试get请求,获取某条数据
    @requestmapping(value = "/testrestful/{id}", method = requestmethod.get)
    public modelandview testget(@pathvariable("id") integer id) {
        modelandview model = new modelandview("hello");
        model.getmodel().put("msg", id);
        model.getmodel().put("message", "test get");
        return model;
    }

    // 测试post请求,插入某条数据
    @requestmapping(value = "/testrestful", method = requestmethod.post)
    public modelandview testpost() {
        modelandview model = new modelandview("hello");
        model.getmodel().put("message", "test post");
        return model;
    }

    // 测试post请求,不转为delete、put请求
    @requestmapping(value = "/testrestful/{id}", method = requestmethod.post)
    public modelandview testpost2(@pathvariable("id") integer id) {
        modelandview model = new modelandview("hello");
        model.getmodel().put("msg", id);
        model.getmodel().put("message", "test post2");
        return model;
    }

    // 测试post请求,转为put请求,更新某条数据
    @requestmapping(value = "/testrestful/{id}", method = requestmethod.put)
    public modelandview testput(@pathvariable("id") integer id) {
        modelandview model = new modelandview("hello");
        model.getmodel().put("msg", id);
        model.getmodel().put("message", "test put");
        return model;
    }

    // 测试post请求,转为delete请求,删除某条数据
    @requestmapping(value = "/testrestful/{id}", method = requestmethod.delete)
    public modelandview testdelete(@pathvariable("id") integer id) {
        modelandview model = new modelandview("hello");
        model.getmodel().put("msg", id);
        model.getmodel().put("message", "test delete");
        return model;
    }
}

【hello.jsp 跳转的页面】
<%@ page language="java" contenttype="text/html; charset=utf-8"
         pageencoding="utf-8" iserrorpage="true"%>
<html>
  <head>
    <title>test restful</title>
  </head>
  <body>
    <h2>${message}</h2>
    <h2>${msg}</h2>
  </body>
</html>

【dispatcher-servlet.xml】
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemalocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <context:component-scan base-package="com.lyh.controller"/>
    <mvc:default-servlet-handler/>
    <mvc:annotation-driven />
    <bean id="defaultviewresolver" class="org.springframework.web.servlet.view.internalresourceviewresolver">
        <property name="prefix" value="/web-inf/"/><!--设置jsp文件的目录位置-->
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

项目结构如下:其余操作可以参考 https://www.cnblogs.com/l-y-h/p/11502440.html

SpringMVC入门 -- 参数绑定

 

 

 

若访问delete、put请求出现405问题,在当前 jsp 页面的 头部添加 iserrorpage="true"。

<%@ page language="java" contenttype="text/html; charset=utf-8" pageencoding="utf-8" iserrorpage="true"%>

 

SpringMVC入门 -- 参数绑定

 

 

 

二、方法参数常用注解

1、@requestmapping

(1)简介
  springmvc提供的一个注解,用于处理指定的请求。
  请求经过dispatcherservlet后,通过@requestmapping的映射信息确定所需对应的处理方法。
  @requestmapping可以在控制器 的类名前、方法名前定义。

【用法样例:】

package com.lyh.controller;

import org.springframework.stereotype.controller;
import org.springframework.web.bind.annotation.requestmapping;

@controller
@requestmapping("/test")
public class hellocontroller {

  @requestmapping("/hello")
  public string show(){
    return "hello";
  }
}

(2)参数
  value:表示请求的url。
  method:表示请求方法(get、post、delete、put)。
  params:表示请求参数。
  headers:表示请求头的映射条件。

注:
    param1:表示请求必须包含名为 param1 的请求参数。
    !param2:表示请求不能包含名为 parma2 的请求参数。
    param1 != value1: 表示请求包含名为 param1 的请求参数,且其值不为 value1。
    {"param1 = value1", "param2"}:表示请求必须包含param1,param2,且param1的值为value1。
    
    value 地址支持通配符。
    ? :表示匹配文件名中的一个字符。比如:/hello/?  ,可以获取 /hello/2,不能获取/hello/22
    * :表示匹配文件名中任意一个字符。比如:/hello/*  ,可以获取 /hello/2, 可以获取/hello/22,不能获取/hello/2/2
    ** :表示匹配多层路径。比如:/hello/**,可以获取/hello/2,可以获取/hello/22,可以获取/hello/2/2.
    
    
【用法样例:】

package com.lyh.controller;

import org.springframework.stereotype.controller;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.requestmethod;

@controller
@requestmapping("/test")
public class hellocontroller {

  @requestmapping(value = "/hello", params = {"username", "age != 10"}, method = requestmethod.get, headers = "referer: https://www.baidu.com/")
  public string show(){
    return "hello";
  }
}

 

2、@pathvariable

(1)简介
  springmvc提供的一个注解,在方法参数中使用,用于获取参数。
  spring3.0后支持 带占位符的url,即相当于 /get/{id} 的形式。通过@pathvariable 可以将url中的占位符参数绑定到方法的参数中。

【用法样例:】

package com.lyh.controller;

import org.springframework.stereotype.controller;
import org.springframework.web.bind.annotation.pathvariable;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.requestmethod;

@controller
public class hellocontroller {

  @requestmapping("/get/{id}")
  public string show(@pathvariable("id") integer id){
    return "hello";
  }
}

 

3、@requestparam

(1)简介
  springmvc提供的一个注解,在方法参数中使用,用于获取参数。
  @requestparam 用于获取表单参数。等价于request.getparameter("name")。而@pathvariable 用于获取 url 中的占位符。

(2)参数
  value:用于获取参数。
  required :表示是否需要该数据,默认为true,若不存在,则会抛出异常。
  defaultvalue :表示默认的值,对于包装类型,默认为null,可以不设值,对于基本类型数据,需要设个初始值。

【举例:】
【index.jsp】
<%@ page language="java" contenttype="text/html; charset=utf-8"
         pageencoding="utf-8" iserrorpage="true"%>
<html>
  <head>
    <title>首页</title>
  </head>
  <body>
      <form action="/testrequestparam/1">
          <label for="nickname">姓名</label>
          <input type="text" id="nickname" name ="nickname" placeholder="请输入姓名..." />

          <label for="password">密码</label>
          <input type="password" id="password" name ="password" placeholder="请输入密码..." />

          <label for="age">年龄</label>
          <input type="text" id="age" name ="age" placeholder="请输入年龄..." />

          <label for="salary">工资</label>
          <input type="text" id="salary" name ="salary" placeholder="请输入工资..." />
         <input type="submit" value="test requestparam"/>
      </form>
  </body>
</html>

【hello.jsp】
<%@ page language="java" contenttype="text/html; charset=utf-8"
         pageencoding="utf-8" iserrorpage="true"%>
<html>
  <head>
    <title>test requestparam</title>
  </head>
  <body>
    <h2>${message}</h2>
    <h2>${msg}</h2>
  </body>
</html>

【hellocontroller.java】
package com.lyh.controller;

import org.springframework.stereotype.controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.modelandview;

@controller
public class hellocontroller {

    @requestmapping(value = "/testrequestparam/{id}")
    public modelandview testrequestparam(@pathvariable("id") integer id, @requestparam(value = "nickname") string nickname,
                                         @requestparam(value = "password") string password, @requestparam(value = "age", required = false) integer age,
                                         @requestparam(value = "salary", required = false, defaultvalue = "0.0") double salary) {
        modelandview model = new modelandview("hello");
        model.getmodel().put("msg", id + "," + nickname + "," + password + "," + age + "," + salary);
        model.getmodel().put("message", "test requestparam");
        return model;
    }

}

SpringMVC入门 -- 参数绑定

 

 SpringMVC入门 -- 参数绑定

 

 

4、@requestheader

(1)简介
  springmvc提供的一个注解,在方法参数中使用,用于获取请求头参数。

【index.jsp】
<%@ page language="java" contenttype="text/html; charset=utf-8"
         pageencoding="utf-8" iserrorpage="true"%>
<html>
  <head>
    <title>首页</title>
  </head>
  <body>
    <a href="/testrequestheader/1">testrequestheader</a>
  </body>
</html>

【hello.jsp】
<%@ page language="java" contenttype="text/html; charset=utf-8"
         pageencoding="utf-8" iserrorpage="true"%>
<html>
  <head>
    <title>test requestheader</title>
  </head>
  <body>
    <h2>${message}</h2>
    <h2>${msg}</h2>
  </body>
</html>

【hellocontroller.java】
package com.lyh.controller;

import org.springframework.stereotype.controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.modelandview;

@controller
public class hellocontroller {

    @requestmapping(value = "/testrequestheader/{id}")
    public modelandview testrequestheader(@pathvariable("id") integer id, @requestheader("accept-language") string language) {
        modelandview model = new modelandview("hello");
        model.getmodel().put("msg", id + "," + language);
        model.getmodel().put("message", "test requestheader");
        return model;
    }
}

SpringMVC入门 -- 参数绑定

 

 

SpringMVC入门 -- 参数绑定

 

 

SpringMVC入门 -- 参数绑定

 

 

 

5、@cookievalue

(1)简介
  springmvc提供的一个注解,在方法参数中使用,用于获取cookie参数。

【index.jsp】
<%@ page language="java" contenttype="text/html; charset=utf-8"
         pageencoding="utf-8" iserrorpage="true"%>
<html>
<head>
    <title>首页</title>
</head>
<body>
<a href="/testcookievalue/1">testcookievalue</a>
</body>
</html>

【hello.jsp】
<%@ page language="java" contenttype="text/html; charset=utf-8"
         pageencoding="utf-8" iserrorpage="true"%>
<html>
  <head>
    <title>test cookievalue</title>
  </head>
  <body>
    <h2>${message}</h2>
    <h2>${msg}</h2>
  </body>
</html>

【hellocontroller.java】
package com.lyh.controller;

import org.springframework.stereotype.controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.modelandview;

@controller
public class hellocontroller {

    @requestmapping(value = "/testcookievalue/{id}")
    public modelandview testcookievalue(@pathvariable("id") integer id, @cookievalue("jsessionid") string jsessionid) {
        modelandview model = new modelandview("hello");
        model.getmodel().put("msg", id + "," + jsessionid);
        model.getmodel().put("message", "test cookievalue");
        return model;
    }

}

SpringMVC入门 -- 参数绑定

 

 

SpringMVC入门 -- 参数绑定

 

 

6、自动给对象绑定请求参数值

(1)简介
  springmvc可以根据请求参数名以及对象(pojo,plain ordinary java object)的属性名 自动匹配,自动为该对象绑定属性值,同时支持级联属性(如:"dept.salary")。

【新建实体类:deptentity.java】
package com.lyh.entity;

public class deptentity {
    private string deptname;
    private double salary;

    public string getdeptname() {
        return deptname;
    }

    public void setdeptname(string deptname) {
        this.deptname = deptname;
    }

    public double getsalary() {
        return salary;
    }

    public void setsalary(double salary) {
        this.salary = salary;
    }

    @override
    public string tostring() {
        return "deptentity{" +
                "deptname='" + deptname + '\'' +
                ", salary=" + salary +
                '}';
    }
}

【新建实体类:personentity.java】
package com.lyh.entity;

public class personentity {
    private string name;
    private string password;
    private deptentity dept;

    public string getname() {
        return name;
    }

    public void setname(string name) {
        this.name = name;
    }

    public string getpassword() {
        return password;
    }

    public void setpassword(string password) {
        this.password = password;
    }

    public deptentity getdept() {
        return dept;
    }

    public void setdept(deptentity dept) {
        this.dept = dept;
    }

    @override
    public string tostring() {
        return "personentity{" +
                "name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", dept=" + dept +
                '}';
    }
}

【index.jsp】
<%@ page language="java" contenttype="text/html; charset=utf-8"
         pageencoding="utf-8" iserrorpage="true"%>
<html>
<head>
    <title>首页</title>
</head>
<body>
<form action="/testpojo/1">
    <label for="name">姓名</label>
    <input type="text" id="name" name ="name" placeholder="请输入姓名..." />

    <label for="password">密码</label>
    <input type="password" id="password" name ="password" placeholder="请输入密码..." />

    <label for="deptname">部门名</label>
    <input type="text" id="deptname" name ="dept.deptname" placeholder="请输入部门名..." />

    <label for="salary">工资</label>
    <input type="text" id="salary" name ="dept.salary" placeholder="请输入工资..." />
    <input type="submit" value="test pojo"/>
</form>
</body>
</html>

【hello.jsp】
<%@ page language="java" contenttype="text/html; charset=utf-8"
         pageencoding="utf-8" iserrorpage="true"%>
<html>
  <head>
    <title>test pojo</title>
  </head>
  <body>
    <h2>${message}</h2>
    <h2>${msg}</h2>
  </body>
</html>

【hellocontroller.java】
package com.lyh.controller;

import com.lyh.entity.personentity;
import org.springframework.stereotype.controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.modelandview;

@controller
public class hellocontroller {

    @requestmapping(value = "/testpojo/{id}")
    public modelandview testpojo(@pathvariable("id") integer id, personentity person) {
        modelandview model = new modelandview("hello");
        model.getmodel().put("msg", id + "," + person);
        model.getmodel().put("message", "test pojo");
        return model;
    }

}

SpringMVC入门 -- 参数绑定

 

 SpringMVC入门 -- 参数绑定

 

 SpringMVC入门 -- 参数绑定

 

 对于能映射到的属性,会自动赋值,否则为默认值。使用级联赋值时,需要注意变量名不能写错了。

SpringMVC入门 -- 参数绑定

 

 SpringMVC入门 -- 参数绑定