首页 > 编程语言 > 详细

SpringMVC--二、SpringMVC请求参数绑定和常用注解

时间:2021-02-24 23:12:37      阅读:33      评论:0      收藏:0      [点我收藏+]

请求参数绑定

绑定机制

我们都知道,表单中请求参数都是基于key=value的。 SpringMVC绑定请求参数的过程是通过把表单提交请求参数,作为控制器中方法参数进行绑定的。

支持的数据类型

基本类型参数: 包括基本类型和String类型

我们在表单中的参数名称必须和控制器中方法的形参名称保持一致。(严格区分大小写)

index.jsp文件

<form method="post" action="param/test">
    姓名:<input type="text" name="name"><br>
    密码:<input type="text" name="password"><br>
    年龄:<input type="text" name="age"><br>
    <input type="submit" value="提交">
</form>

Controller类

@Controller
@RequestMapping("/param")
public class ParamController {
    @RequestMapping("/test")
    public String ParamTest(String name, User user){
        System.out.println(name + ‘\t‘ + user);
        return "success";
    }
}

User类

public class User implements Serializable {
    String password;
    Integer age;
    @Override
    public String toString() {
        return "User{" +
                "password=‘" + password + ‘\‘‘ +
                ", age=" + age +
                ‘}‘;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
}

这里直接使用实体类的时候,表单中的name命名可以当作基本类型,但是当实体类中使用其他实体类,要使用如下命名方式

POJO类型参数: 包括实体类,以及关联的实体类

中文释义为简单的java对象,其实就是Java bean,好像是为了避免和EJB混淆所创造的简称
要求表单中参数名称和POJO类的属性名称保持一致。并且控制器方法的参数类型是POJO类型。例如:name.firstname
用于这里的实体类都要实现Serializable接口

index.jsp

<form method="post" action="param/test">
    姓:<input type="text" name="name.firstname"><br>
    名:<input type="text" name="name.secondname"><br>
    密码:<input type="text" name="password"><br>
    年龄:<input type="text" name="age"><br>
    <input type="submit" value="提交">
</form>

Controller类

@Controller
@RequestMapping("/param")
public class ParamController {
    @RequestMapping("/test")
    public String ParamTest(User user){
        System.out.println(user);
        return "success";
    }
}

User类

public class User implements Serializable {
    String password;
    Name name;//自定义类型JavaBean
    Integer age;
    
    @Override
    public String toString() {
        return "User{" +
                "password=‘" + password + ‘\‘‘ +
                ", name=" + name +
                ", age=" + age +
                ‘}‘;
    }
    public Name getName() {
        return name;
    }
    public void setName(Name name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
}

Name类

public class Name implements Serializable {
    @Override
    public String toString() {
        return "Name{" +
                "firstname=‘" + firstname + ‘\‘‘ +
                ", secondname=‘" + secondname + ‘\‘‘ +
                ‘}‘;
    }

    private String firstname, secondname;

    public String getFirstname() {
        return firstname;
    }
    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }
    public String getSecondname() {
        return secondname;
    }
    public void setSecondname(String secondname) {
        this.secondname = secondname;
    }
}

数组和集合类型参数: 包括List结构和Map结构的集合(包括数组)

  • 要求集合类型的请求参数必须在POJO中。在表单中请求参数名称要和POJO中集合属性名称相同。
    给List集合中的元素赋值,使用下标。 例如:list[0].user
    给Map集合中的元素赋值,使用键值对。例如:map[‘one‘].user
  • 接收的请求参数是json格式数据。需要借助一个注解实现。

index.jsp

<form method="post" action="param/test">
    姓一:<input type="text" name="nameList[0].firstname"><br>
    名一:<input type="text" name="nameList[0].secondname"><br>
    姓二:<input type="text" name="nameList[1].firstname"><br>
    名二:<input type="text" name="nameList[1].secondname"><br>
    姓三:<input type="text" name="nameMap[‘one‘].firstname"><br>
    名三:<input type="text" name="nameMap[‘one‘].secondname"><br>
    密码:<input type="text" name="password"><br>
    年龄:<input type="text" name="age"><br>
    <input type="submit" value="提交">
</form>

Controller类同上

User类

public class User implements Serializable {
    String password;
    Integer age;
    List<Name> nameList;
    Map<String, Name> nameMap;

    @Override
    public String toString() {
        return "User{" +
                "password=‘" + password + ‘\‘‘ +
                ", age=" + age +
                ", nameList=" + nameList +
                ", nameMap=" + nameMap +
                ‘}‘;
    }
    public List<Name> getNameList() {
        return nameList;
    }
    public void setNameList(List<Name> nameList) {
        this.nameList = nameList;
    }
    public Map<String, Name> getNameMap() {
        return nameMap;
    }
    public void setNameMap(Map<String, Name> nameMap) {
        this.nameMap = nameMap;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
}

Name类同上

请求参数乱码问题

在web.xml中配置Spring提供的过滤器类:

<!-- 配置过滤器,解决中文乱码的问题 -->
<filter>
	<filter-name>characterEncodingFilter</filter-name>
	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filterclass>
	<!-- 指定字符集 -->
	<init-param>
		<param-name>encoding</param-name>
		<param-value>UTF-8</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>characterEncodingFilter</filter-name>
    <!--/*代表拦截所有-->
	<url-pattern>/*</url-pattern>
</filter-mapping>

自定义类型转换器

任何变量从jsp传到控制器用的都是字符串,当其到控制器时,Spring有自定义的类型转换器将其转换为特定的类型的变量,当有些变量无法通过Spring自定义类型转换器转换类型时,我们可以自己定义一个类型转换器来帮助转换。

例如Data类,默认日期格式为1999/10/1,当我们输入1999-10-1时则会发生错误,Spring自定义类型转换器无法转换,此时我们自己定义一个类型转换器,来讲1999-10-1格式的日期字符串转换成Data类。

定义一个类型转换器类

自定义的类型转换器类需要继承一个Converter接口,要看清楚是Spring核心包中的Converter接口:技术分享图片

类中的两个泛型S和T分别写要从类型S转换到类型T

public class StringToData implements Converter<String, Date>{
    @Override
    public Date convert(String source) {
        if (source==null){
            throw new RuntimeException("值空");
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        try {
            return dateFormat.parse(source);
        }catch (Exception e){
            throw new RuntimeException("错误");
        }
    }
}

配置自定义类型转换器

在resources中的xml配置文件中配置自定义类型转换器,就是你配置视图解析器的那个配置文件。

<bean id="conversionServiceFactoryBean"
      class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="com.utils.StringToData"></bean>
        </set>
    </property>
</bean>

<!--配置spring开启注解mvc的支持-->
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"></mvc:annotation-driven>

这里还要修改开启注解mvc的支持,因为在开启注解mvc的支持时是默认开启了处理器映射器、处理器适配器、视图解析器三大组件,而现在想用类型转换器,则必须在这里配置开启。

常用注解

RequestParam

使用说明

作用:把请求中的指定名称的参数传递给控制器中的形参赋值

属性:

  1. value:请求参数中的名称(当你使用了RequestParam注解之后就必须按照value中的命名来传递参数,不能再像请求参数绑定中,把参数命名成相同的名字了。)
  2. required:请求参数中是否必须提供此参数,默认值是true(即必须提供,如果不提供将报错)

示例

index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<a href="anno/testRp?name=haha">testRequestParam</a>
</body>
</html>
Controller
@Controller
@RequestMapping("anno")
public class AnnoController {
    @RequestMapping("/testRp")
    public String testRp(@RequestParam(value = "name", required = false) String username){
        if (username==null)
            System.out.println("无用户名");
        else
            System.out.println(username);

        return "success";
    }
}

在这个例子中我们把required改为false,则当没有参数传递给username时它为null。当使用RequestParam时则必须按照它的value在jsp页面命名,不能像请求参数绑定中命名成相同的名字。例如在这个例子中,jsp页面想要传递参数给控制器中的username,就必须给控制器传递一个名为name的参数,而不能传递一个名为username的参数。

RequestBody

使用说明

作用:用于获取请求体的内容,直接使用得到是key=value&key=value...结构的数据。(注意:get方法不可以,因为get没有请求体,它把参数都封装到地址栏了)

属性:

  1. required:是否必须有请求体,默认值是true。当取值为true时,get请求方式会报错。如果取值为false,get请求得到是null。

示例

index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form method="post" action="anno/testRequestBody">
    用户名:<input type="text" name="username"><br>
    密码:<input type="text" name="password"><br>
    年龄:<input type="text" name="age"><br>
    <input type="submit" value="提交">
</form>
</body>
</html>
Controller
@Controller
@RequestMapping("anno")
public class AnnoController {
    @RequestMapping("/testRequestBody")
    public String testRequestBody(@RequestBody String body){
        System.out.println(body);
        return "success";
    }
}

在本例中的请求体输出示例:username=int64Saturday&password=111&age=111

PathVaribale

使用说明

作用:用于绑定url中的占位符。例如:请求url中 /delete/{id},这个{id}就是url占位符。
url支持占位符是spring3.0之后加入的。是springmvc支持rest风格URL的一个重要标志。

那么什么时rest风格的URL呢,一般rest风格都称为restful风格,它其实就是一种规范,区别于我们平时普通的url,见下图
技术分享图片

(图中的FindById()方法少写了个参数id)从图中可看出普通的url每个方法都会对应一个地址,但是restful风格的url相同类下的每个方法地址都是相同的。restful风格的url是通过http协议的四种方法来寻找要执行的方法,即:

  1. GET 用来获取资源
  2. POST 用来新建资源
  3. PUT 用来更新资源
  4. DELETE 用来删除资源。

但是当遇到相同的方法时,如上图的FindAll()方法和FindById(id)方法,它会通过不同的参数来寻找特定的方法,有些类似函数的重载。上图中的{id}是占位符,当我们想调用FindById(id)方法时,参数id=10,此时的url应该为:/user/10

但是form表单只支持GET和POST方法,而DELETE、PUT等方法并不支持,Spring3.0添加了一个过滤器能帮我们模拟这些方法,但是配置比较麻烦,不如其他的一些类实现容易,这里就不赘述了,想了解的可以自行百度。

属性:

  1. value:用于指定url中占位符名称。
  2. required:是否必须提供占位符。

示例

index.jsp
<body>
<form method="post" action="anno/10">
    用户名:<input type="text" name="username"><br>
    密码:<input type="text" name="password"><br>
    年龄:<input type="text" name="age"><br>
    <input type="submit" value="提交">
</form>
</body>
Controller
@Controller
@RequestMapping("anno")
public class AnnoController {
    @RequestMapping("/{sid}")
    public String testPathVaribale(@PathVariable(value = "sid") String id){
        System.out.println(id);
        return "success";
    }
}

最后控制台输出结果为10。

RequestHeader

使用说明

作用:用于获取请求消息头。http请求头有很多种,详情见百度百科:http请求头

属性:

  1. value:提供消息头名称
  2. required:是否必须有此消息头

注: 在实际开发中一般不怎么用。

示例

index.jsp
<a href="anno/testRequestHeader">testRequestHeader</a>
Controller
@RequestMapping("/testRequestHeader")
public String testRequestHeader(@RequestHeader(value = "Accept") String header){
    System.out.println(header);
    return "success";
}

CookieValue

使用说明

作用:用于把指定 cookie 名称的值传入控制器方法参数。

属性:

  1. value:指定 cookie 的名称。
  2. required:是否必须有此 cookie。

注: 在实际开发中一般不怎么用。

示例

index.jsp
<a href="anno/testCookieValue">testRequestHeader</a>
Controller
@RequestMapping("/testCookieValue")
public String testCookieValue(@CookieValue(value = "JSESSIONID") String cookieValue){
    System.out.println(cookieValue);
    return "success";
}

ModelAttribute

使用说明

作用:该注解是 SpringMVC4.3 版本以后新加入的。它可以用于修饰方法和参数。

  1. 出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法。
  2. 出现在参数上,获取指定的数据给参数赋值。

属性:

  1. value:用于获取数据的 key。key 可以是 POJO 的属性名称,也可以是 map 结构的 key。

应用场景:

当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。

示例1

index.jsp
<form method="post" action="anno/testModelAttribute">
    用户名:<input type="text" name="username"><br>
    密码:<input type="text" name="password"><br>
    年龄:<input type="text" name="age"><br>
    <input type="submit" value="提交">
</form>
Controller
@RequestMapping("/testModelAttribute")
public String testModelAttribute (User user){
    System.out.println("testModelAttribute执行了..." + user.getUsername());
    return "success";
}

@ModelAttribute
public void showUser(){
    System.out.println("showUser执行了...");
}

最后控制台输出结果为:
showUser执行了...
testModelAttribute执行了...int64Saturday

示例2

有返回值,表单中没有输入age的文本框,如果不进行配置,则age为null

index.jsp
<form method="post" action="anno/testModelAttribute">
    用户名:<input type="text" name="username"><br>
    密码:<input type="text" name="password"><br>
    <input type="submit" value="提交">
</form>
Controller
@RequestMapping("/testModelAttribute")
public String testModelAttribute (User user){
    System.out.println("testModelAttribute执行了...");
    System.out.println(user);
    return "success";
}

@ModelAttribute
public User showUser(String username){
    User user = new User();
    //模拟数据库查询
    user.setAge(10);
    user.setPassword("111");
    user.setUsername(username);
    System.out.println("showUser执行了...");
    return user;
}

示例3

无返回值,没有返回值时,需要方法提供一个map结构,将User对象存入map中,然后在控制器方法中用ModelAttribute修饰形参从map中取出该对象。

index.jsp

同上

Controller
@ModelAttribute
public void showUser(String username, Map<String, User> map){
    User user = new User();
    //模拟数据库查询
    user.setAge(10);
    user.setPassword("111");
    user.setUsername(username);
    map.put("user", user);
    System.out.println("showUser执行了...");
}

SessionAttribute

使用说明

作用:用于多次执行控制器方法间的参数共享,作用于类上。

属性:

  1. value:用于指定存入的属性名称
  2. type:用于指定存入的数据类型

示例

index.jsp
<a href="anno/testSaveSessionAttribute">SaveSessionAttribute</a><br>
<a href="anno/testGetSessionAttribute">GetSessionAttribute</a><br>
<a href="anno/testDeleteSessionAttribute">DeleteSessionAttribute</a>
Controller
@Controller
@RequestMapping("anno")
@SessionAttributes(value = {"username", "password"})
public class AnnoController {
    @RequestMapping("/testSaveSessionAttribute")
    public String testSaveSessionAttribute (Model model){
        System.out.println("向session中保存了数据");
        model.addAttribute("username", "root");
        model.addAttribute("password", "1234");
        return "success";
    }
    @RequestMapping("/testGetSessionAttribute")
    public String testGetSessionAttribute (ModelMap modelMap){
        System.out.println("从session中获取了数据");
        String username = (String)modelMap.get("username");
        String password = (String)modelMap.get("password");
        System.out.println("username:" + username + "\tpassword:" + password);
        return "success";
    }
    @RequestMapping("/testDeleteSessionAttribute")
    public String testDeleteSessionAttribute (SessionStatus sessionStatus){
        System.out.println("从session中删除了数据");
        //设置完成,就是这些操作做完了,它会帮你把session中的数据清除
        sessionStatus.setComplete();
        return "success";
    }
}

超链接点击步骤:存值->取值->删除->取值
控制台输出:

向session中保存了数据
从session中获取了数据
username:root password:1234
从session中删除了数据
从session中获取了数据
username:null password:null

SpringMVC--二、SpringMVC请求参数绑定和常用注解

原文:https://www.cnblogs.com/zhangzeff/p/14442470.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!