你未看此花时,则此花与汝心同归于寂, 你来看此花时,此花颜色一时明白起来,便知此花不在你的心外。


一. 数据绑定

从前端特别是表单传递过来的数据,需要在后端进行接收。 接收时可以有不同的形式,也可以接收各种各样的类型。

二. 数据乱码

二.一 POST提交

1 . 前端html 代码

<!-- 采用的是post提交的方式 -->
<form action="/SpringMVC02/user/register.action" method="post">
用户名: <input type="text" name="name"/> <br/>
年龄:<input type="text" name="age"><br/>
性别:<input type="text" name="sex"><br/>
描述:<input type="text" name="description"><br/>
<input type="submit" value="提交">
</form>

2 . 页面输入值

SpringMVC的请求乱码解决和接收前端常用类型(五)_SpringMVC后端接收Map参数

3 .后端接收代码 用 @RequestParam 注解接收。

4 . 控制台打印输出

SpringMVC的请求乱码解决和接收前端常用类型(五)_SpringMVC后端接收Map参数_02

发现,接收过来的name 是乱码的形式。 而前台传入中文是一种很常见的方式。

二.二 POST提交乱码解决方式

SpringMVC 针对 中文乱码提供了一个过滤器, CharacterEncodingFilter, 只需要将这个过滤器配置在web.xml 中即可。放置在servlet 之前。

public class CharacterEncodingFilter
extends OncePerRequestFilter
{
private String encoding;
private boolean forceEncoding = false;
}

web.xml 中配置:

<!--配置中文乱码过滤器-->
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<!-- 类里面有一个属性 encoding,来动态注入编码 -->
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

这个时候,重启服务器,再传入时,后端接收。

SpringMVC的请求乱码解决和接收前端常用类型(五)_SpringMVC后端接收Map参数_03

有时候,为了强制转换,通常还会再添加一个参数 forceEncoding 来决定是否强制使用 encoding 属性设置的编码格式。

<!--配置中文乱码过滤器-->
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<!-- 类里面有一个属性 encoding,来动态注入编码 -->
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<!-- 是否强制使用encoding的编码方式。 默认为false -->
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

当然,也可以像Servlet 时代那样,用请求 request 来处理乱码。 但不建议这么写。

request.setCharacterEncoding("UTF-8");
//或者是

String str=newString((request.getParameter("name")).getBytes("iso-8859-1"),"utf-8")

二.三 GET 方式提交乱码的问题

即使上面配置了CharacterEncodingFilter 过滤器,当get 提交时也会出现乱码。 因为 get提交时,是tomcat 在决定的。

1 . html前端页面设置成 get提交

<form action="/SpringMVC02/user/register.action" method="get">

2 . 前端输入

SpringMVC的请求乱码解决和接收前端常用类型(五)_数据_04

3 . 后端控制台接收打印

SpringMVC的请求乱码解决和接收前端常用类型(五)_数据_05

二.四 Get方式提交乱码解决

1 .找到Tomcat的安装路径 conf/server.xml 文件里面的

SpringMVC的请求乱码解决和接收前端常用类型(五)_数据_06

添加: URIEncoding=“UTF-8” .

<Connector connectionTimeout="20000" port="8090" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>

2 . 重启tomcat,进行打印输出。

SpringMVC的请求乱码解决和接收前端常用类型(五)_SpringMVC后端接收Map参数_07

三. 数据绑定

三.一 绑定单个基本的参数

绑定单个参数时与上面的例子一样。

1 . 前台

<!-- 采用的是post提交的方式 -->
<form action="/SpringMVC02/user/register.action" method="post">
用户名: <input type="text" name="name"/> <br/>
年龄:<input type="text" name="age"><br/>
性别:<input type="text" name="sex"><br/>
描述:<input type="text" name="description"><br/>
<input type="submit" value="提交">
</form>

2 . 后端接收

@RequestMapping(value="/register")
public String register(@RequestParam(value="name") String name,
@RequestParam(value="age") Integer age,HttpServletResponse response){
response.setCharacterEncoding("utf-8");
System.out.println("name:"+name);
System.out.println("age:"+age);
return "user/list";
}

3 . 前台参数写入

SpringMVC的请求乱码解决和接收前端常用类型(五)_SpringMVC后端接收Map参数_08

4 .控制台打印输出

SpringMVC的请求乱码解决和接收前端常用类型(五)_SpringMVC后端接收Map参数_09

当然,绑定参数除了@RequestParam 注解外,还可以用@pathVariable 注解。 具体可以参数第三章和第四章的注解。

三.二 绑定POJO 对象

需要前端的name中的值与POJO 对象中的属性值保持一致。 与Struts2 的相同。

前端与上面的一致。

后端接收:

@RequestMapping(value="/register")
public String register(User user){
System.out.println("接收的对象:"+user.toString());
return "user/list";
}

前端输入:

SpringMVC的请求乱码解决和接收前端常用类型(五)_SpringMVC后端接收Map参数_10

控制台打印输出:

SpringMVC的请求乱码解决和接收前端常用类型(五)_数据_11

三.三 绑定关联对象

如 User 类中关联一个Dept 部门类,表示一个员工所在的部门的信息。

部门Dept 表:

package com.yjl.pojo;
/**
@author: yuejl
@date: 2019年2月16日 上午10:15:08
@Description 数据库中一的一方 部门实体
*/
public class Dept {
/**
* @param id 部门的编号
* @param name 部门的名称
* @param description 部门的描述
*/
private Integer id;
private String name;
private String description;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "Dept [id=" + id + ", name=" + name + ", description=" + description + "]";
}
}

员工User 表里面添加 Dept的引用,实现setter和getter方法,并且重写User 中的toString() 方法,添加dept的打印。

//关联部门的引用
private Dept dept;

1 . 前端页面展示

<form action="/SpringMVC02/user/register.action" method="post">
用户名: <input type="text" name="name"/> <br/>
年龄:<input type="text" name="age"><br/>
性别:<input type="text" name="sex"><br/>
描述:<input type="text" name="description"><br/>
<!-- 用属性.属性 的形式来接收。 -->
部门名称:<input type="text" name="dept.name"><br/>
部门描述:<input type="text" name="dept.description"><br/>
<input type="submit" value="提交">
</form>

2 . 后端接收与上面的一致。

@RequestMapping(value="/register")
public String register(User user){
System.out.println("接收的对象:"+user.toString());
return "user/list";
}

3 . 前台数据输入

SpringMVC的请求乱码解决和接收前端常用类型(五)_数据_12

4 . 控制台打印输出

SpringMVC的请求乱码解决和接收前端常用类型(五)_数据_13

三.四 绑定数组对象

以老蝴蝶的爱好为例。

1 . 前端界面

<!-- 爱好,数组接收 -->
<input type="checkbox" name="hobby" value="读书">读书
<input type="checkbox" name="hobby" value="编程">编程
<input type="checkbox" name="hobby" value="打游戏">打游戏
<input type="checkbox" name="hobby" value="看电影">看电影

2 . 后台接收处理。 当然也可以放置在user 里面,这里用参数处理。

@RequestMapping(value="/register")
public String register(User user,@RequestParam(value="hobby",required=false) String[] hobby){
System.out.println("接收的对象:"+user.toString());
System.out.println("爱好是:"+Arrays.toString(hobby));
return "user/list";
}

3 .前端输入勾选

SpringMVC的请求乱码解决和接收前端常用类型(五)_SpringMVC后端接收Map参数_14

4 . 后台打印输出,显示数组值。

SpringMVC的请求乱码解决和接收前端常用类型(五)_数据_15

当然,也可以将hobby 数组放置在User 类里面。

5 .在User 类里面 添加 hobby 的数组属性,添加setter和getter方法

private String [] hobby;


public String[] getHobby() {
return hobby;
}

public void setHobby(String[] hobby) {
this.hobby = hobby;
}

6 .后台接收:

@RequestMapping(value="/register")
public String register(User user){
System.out.println("接收的对象:"+user.toString());
String []hobby=user.getHobby();
System.out.println("对象接收爱好是:"+Arrays.toString(hobby));
return "user/list";
}

7 .前端数据输入:

SpringMVC的请求乱码解决和接收前端常用类型(五)_数据_16

8 .后端控制台打印输出

SpringMVC的请求乱码解决和接收前端常用类型(五)_数据_17

三.五 绑定List 集合对象

与数组接收基本是一致的。

1 . 后台接收处理

@RequestMapping(value="/register")
public String register(User user,@RequestParam(value="hobby",required=false) List<String> hobby){
System.out.println("接收的对象:"+user.toString());
System.out.println("爱好是:"+Arrays.toString(hobby.toArray(new String[]{})));
return "user/list";
}

2 . 后台显示处理

前端多传入 一个 读书 (老蝴蝶不要脸一次) 的选项。

SpringMVC的请求乱码解决和接收前端常用类型(五)_数据_18

当然,也是可以将集合放置在User 对象里面的。

3 . 在User 对象中添加一个 List 集合属性,实现setter和getter方法。

private List<String> hobby;


public List<String> getHobby() {
return hobby;
}

public void setHobby(List<String> hobby) {
this.hobby = hobby;
}

4 . 后端控制台接收

@RequestMapping(value="/register")
public String register(User user){
System.out.println("接收的对象:"+user.toString());
List<String> hobby=user.getHobby();
System.out.println("对象接收List爱好是:"+Arrays.toString(hobby.toArray(new String[]{})));
return "user/list";
}

5 .前端传入数据

SpringMVC的请求乱码解决和接收前端常用类型(五)_SpringMVC后端接收Map参数_19

6 . 后端控制台打印输出

SpringMVC的请求乱码解决和接收前端常用类型(五)_数据_20

三.六 绑定Map 对象。

将前台传入的值,当成一个Map传入进去。 继续接着上面的前端代码往下写。

前端代码:

职业1: <input type="text" name="love1" value=""> <br/>
职业2: <input type="text" name="love2" value=""><br/>
职业3: <input type="text" name="love3" value=""><br/>

2 . 后端接收。

@RequestMapping(value="/register")
public String register(User user,@RequestParam Map<String,String> map){ //此时,requestParam注解里面不能写任何值。
System.out.println("接收的对象:"+user.toString());
for(Map.Entry<String,String> entry:map.entrySet()){
System.out.print("输出值:"+entry.getKey());
System.out.print(",输出值:"+entry.getValue());
System.out.println("\n");
}
return "user/list";
}

3 . 前端数据写入

SpringMVC的请求乱码解决和接收前端常用类型(五)_SpringMVC后端接收Map参数_21

4 . 控制台打印输出

SpringMVC的请求乱码解决和接收前端常用类型(五)_SpringMVC后端接收Map参数_22

会发现,把所有的请求参数都放置在了Map 里面。 如果想,仅仅把 参数为love1,love2,love3的放置进去呢?

5 .将集合Map属性 写入到User 类中,并实现setter和getter方法。

private Map<String,String> loveMap;

public Map<String, String> getLoveMap() {
return loveMap;
}

public void setLoveMap(Map<String, String> loveMap) {
this.loveMap = loveMap;
}

6 . 前台代码。 注意,这个时候有一个变化了。

<!--name便为属性.key值-->
职业1: <input type="text" name="loveMap['love1']" value=""> <br/>
职业2: <input type="text" name="loveMap['love2']" value=""><br/>
职业3: <input type="text" name="loveMap['love3']" value=""><br/>

7 .后端代码接收

@RequestMapping(value="/register")
public String register(User user){
System.out.println("接收的对象:"+user.toString());
Map<String,String> loveMap=user.getLoveMap();
for(Map.Entry<String,String> entry:loveMap.entrySet()){
System.out.print("输出值:"+entry.getKey());
System.out.print(",输出值:"+entry.getValue());
System.out.println("\n");
}
return "user/list";
}

8 .前台传入数据

SpringMVC的请求乱码解决和接收前端常用类型(五)_数据_23

9 . 后端控制台打印输出

SpringMVC的请求乱码解决和接收前端常用类型(五)_SpringMVC后端接收Map参数_24

可知,前端仅love1,love2,love3放置在了Map集合里面。
所以,最好把前端的数据放置在对象里面,便于接收。 当然,实际开发中,并不能改变User类,而应该添加一个User类的扩展 UserVo 类,在UserVo 类中添加扩展的属性。

谢谢!!!