一. 数据绑定
从前端特别是表单传递过来的数据,需要在后端进行接收。 接收时可以有不同的形式,也可以接收各种各样的类型。
二. 数据乱码
二.一 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 . 页面输入值
3 .后端接收代码 用 @RequestParam 注解接收。
4 . 控制台打印输出
发现,接收过来的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>
这个时候,重启服务器,再传入时,后端接收。
有时候,为了强制转换,通常还会再添加一个参数 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 . 前端输入
3 . 后端控制台接收打印
二.四 Get方式提交乱码解决
1 .找到Tomcat的安装路径 conf/server.xml 文件里面的
添加: URIEncoding=“UTF-8” .
<Connector connectionTimeout="20000" port="8090" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>
2 . 重启tomcat,进行打印输出。
三. 数据绑定
三.一 绑定单个基本的参数
绑定单个参数时与上面的例子一样。
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 . 前台参数写入
4 .控制台打印输出
当然,绑定参数除了@RequestParam 注解外,还可以用@pathVariable 注解。 具体可以参数第三章和第四章的注解。
三.二 绑定POJO 对象
需要前端的name中的值与POJO 对象中的属性值保持一致。 与Struts2 的相同。
前端与上面的一致。
后端接收:
@RequestMapping(value="/register") public String register(User user){ System.out.println("接收的对象:"+user.toString()); return "user/list"; }
前端输入:
控制台打印输出:
三.三 绑定关联对象
如 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 . 前台数据输入
4 . 控制台打印输出
三.四 绑定数组对象
以老蝴蝶的爱好为例。
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 .前端输入勾选
4 . 后台打印输出,显示数组值。
当然,也可以将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 .前端数据输入:
8 .后端控制台打印输出
三.五 绑定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 . 后台显示处理
前端多传入 一个 读书 (老蝴蝶不要脸一次) 的选项。
当然,也是可以将集合放置在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 .前端传入数据
6 . 后端控制台打印输出
三.六 绑定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 . 前端数据写入
4 . 控制台打印输出
会发现,把所有的请求参数都放置在了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 .前台传入数据
9 . 后端控制台打印输出
可知,前端仅love1,love2,love3放置在了Map集合里面。
所以,最好把前端的数据放置在对象里面,便于接收。 当然,实际开发中,并不能改变User类,而应该添加一个User类的扩展 UserVo 类,在UserVo 类中添加扩展的属性。