下面继续回到复合数据的接受,作为数组接收数据固然没有问题,但是大家发现了没有,数组其实用得越来越少了。因为java提供了更加有效的数据结构,就是集合。就可以通过List集合来保存数据。用法其实也差不多,默认以ArrayList来存储数据。区别在于,用List集合接收符合数据,要在前面添加@RequestParam注解 ,下面编写代码:
//通过List来接收表单复合数据 @PostMapping("/apply") @ResponseBody public String apply(String name, String course, @RequestParam List<Integer> purpose){ return name+" "+course+" "+purpose.size(); }
上面对于这些参数都是单独接收的,下面来试试采取对象的形式来接收。
在entity包下面创建一个新的实体类Form
package com.haiexijun.springmvc.entity; import java.util.List; public class Form { private String name; private String course; private List<Integer> purpose; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCourse() { return course; } public void setCourse(String course) { this.course = course; } public List<Integer> getPurpose() { return purpose; } public void setPurpose(List<Integer> purpose) { this.purpose = purpose; } }
对controller里面的apply方法进行修改:
//通过List来接收表单复合数据 @PostMapping("/apply") @ResponseBody public String apply(Form form){ return form.getName()+" "+form.getCourse()+" "+form.getPurpose().size(); }
下面再扩展一个额外的知识点,用Map来接收表单数据。同样要加@RequestParam注解,并且表单传过来的参数不能有复合数据,不然只显示复合数据的第一项。
//通过List来接收表单复合数据 @PostMapping("/apply") @ResponseBody public String apply(@RequestParam Map map){ return (String) map.get("name"); }
4.关联对象赋值
关联对象就是在一个对象中引用了另外一个对象,我们需要对这个被引用的对象进行赋值的操作。
下面用一个案例来了解一下
在我们上网的时候,一些关键性的操作往往是要进行实名认证的,比如我们去12306买票,除了输入用户名和密码以外,你还要去登记你的姓名、身份证号、以及身份证的过期时间。等等这些信息。这时,就要对IdCard对象关联赋值了。
我们要在前端表单进行一下修改,把原有的身份证相关输入的部分变成对象名.属性名的形式。
5.日期类型转换
本节学习一个非常实用的技巧,在SpringMVC中接收日期类型的数据。我们都知道全世界各地,对于日期的表达方式都不同,我们如何接收程序中的日期数据,然后将他转换为日期对象呢?
<form action="/apply" method="post"> <input type="text" name="createTime"> <input type="submit" value="提交"> </form>
上面是前端的一个简单的表单,输入日期,然后再下面的controller里面的方法中进新处理:
@PostMapping("/apply") @ResponseBody public String apply(Date createTime){ return createTime; }
但是上面这样写明显是不行的。spring mvc无法将它转换成日期类型
必须要加上@DateTimeFormat这个注解。 这个注解专用于将前台传入的日期字符串转换为日期格式。注解里面pattern要传入特定的日期格式。
@PostMapping("/apply") @ResponseBody public String apply(@DateTimeFormat(pattern = "yyyy-MM-dd") Date createTime){ return createTime.toString(); }
下面运行测试一下:
如果要javaBean里面接收参数的话,就要再Bean中的Date类型的参数上面添加@DateFormat注解。
三.解决中文乱码问题
本节来学习如何在Spring MVC中解决中文乱码的问题。
Tomcat默认使用的字符集是ISO-8859-1,属于西欧字符集。解决乱码的核心思路就是将ISO-8859-1转换为UTF-8。Controller中请求与响应都要设置UTF-8字符集。
中文乱码的配置:
Get请求乱码—server.xml(tomcat里面的)中添加URIEncoding属性。
Post请求乱码—web.xml(项目的)中配置CharacterEncodingFilter这个过滤器,通过spring提供的这个过滤器来解决post请求当中中文乱码的问题。
<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"> ··············· ················ <filter> <filter-name>characterFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web app>
Response响应乱码—Spring配置StringHttpMessageConverter这个消息转换器来往成响应输出的中文解决。
打开applicationContext.xml文件,在<mvc:annotation-driven>里面添加如下的代码:
<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-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd"> <!--自动扫描组件,自动扫描符合条件的bean--> <context:component-scan base-package="com.haiexijun.springmvc"></context:component-scan> <!--启用Spring MVC的注解开发模式--> <mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=utf-8</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> <!--将图片/JS/CSS等静态资源排除在外,可提高执行效率--> <mvc:default-servlet-handler/> </beans>
基本上在我们任何一个项目中,这三部都要进行设置。
四.响应输出
前面一直在学习请求中如何接收数据,如何URL映射,本节学习响应是如何对外输出结果的。
在响应中产生结果主要有两种方式,第一种是在我们Controller的方法上增加@ResponseBody注解,来产生响应文本。我们光产生文本很多时候是不够的,往往是需要显示对应的页面。就要用到ModelAndView对象,在利用模板引擎渲染输出。
1.@ResponseBody
@ResponseBody直接产生响应体的数据,过程不涉及任何视图,@ResponseBody可产生标准字符串/JSON/XML等格式数据。@ResponseBody被StringHttpMessageConverter所影响。
2.ModelAndView对象的用法
在我们项目开发的时候,很多时候都是需要进行页面展现的,那如果要在SpringMVC中进行页面展现的话,就要实用ModelAndView这个对象了。所谓ModelAndView对象是指“模型(数据)与视图(界面)”对象,这个对象的作用呢就是将模型和视图进行绑定。通过ModelAndView对象可以将包含数据对象与模板引擎进行绑定。Spring MVC中默认的View是JSP,也可以配置其他模板引擎。
下面来小小的演示一下:
//返回值类型为ModelAndView @GetMapping("/view") public ModelAndView showView(){ //构造函数里面传入一个jsp页面 ModelAndView mav=new ModelAndView("view.jsp"); return mav; }
然后创建view.jsp页面。
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>I am view page</h1> </body> </html>
浏览器输入URL地址后:
上面的案例你可能会觉得也没什么了不起嘛,其实可以将方法中传入的参数进行在里面渲染后输出的。
下面对进行更改讲解
@GetMapping("/view") public ModelAndView showView(Integer userId){ //构造函数里面传入一个jsp页面 ModelAndView mav=new ModelAndView("view.jsp"); User user=new User(); if (userId==1){ user.setUsername("lily"); }else if (userId==2){ user.setUsername("smith"); } mav.addObject("u",user); return mav; }
上面接收一个get请求的参数,然后把参数传进JSP内渲染。
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>I am view page</h1> <hr/> <h2>uaername:${u.username}</h2> </body> </html>
但是这些还是远远不够的,下面就来对ModelAndView进行深入的学习。
作为数据绑定,ModelAndView对象提供了一个addObject()方法,addObject()方法设置的属性默认存放在当前请求中。里面存入的对象可以是任何java对象。ModelAndView对象默认使用请求转发(forward)至页面。
如果要使用响应重定向,就要使用 new ModelAndView(“redirect:/xxx.jsp”) ,即添加redirect
ModelAndView可以不在创建对象时,在构造方法里面写跳转的地址,可以在创建对象后,通过ModelAndView对象的setViewName()方法来设置跳转的视图的地址。
ModelAndView mav=new ModelAndView(); mav.setViewName("/view.jsp")
下面再来扩展一个知识点,就是利用String与ModelMap这两个对象来实现与 ModelAndView类似的一个功能。
Controller方法返回String的情况:
1.方法被@ResponseBody注解,SpringMVC注解响应String字符串本身。
2.方法不存在@ResponseBody注解,SpringMVC处理String为视图(页面)
@GetMapping("/view") public String showView(Integer userId, ModelMap modelMap){ String view="/view.jsp"; User user=new User(); if (userId==1){ user.setUsername("lily"); }else if (userId==2){ user.setUsername("smith"); } //与ModelAndView的addObject完全相同 modelMap.addAttribute("u",user); return view; }
五.Spring MVC整合FreeMarker
整合的步骤主要分为3步:
1.pox.xml中引入freemarker的maven依赖和一个Spring上下文的支持包。 Spring上下文的支持包要与spring-webmvc版本一致。
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.13</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.31</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>5.3.13</version> </dependency> </dependencies>
2.启用Freemarker模板引擎
在applicationContext.xml中添加如下配置:
<bean id="ViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"> <!--设置响应输出,解决中文乱码--> <property name="contentType" value="text/html;charset=utf-8"/> <!--指定FreeMarker模板文件拓展名--> <property name="suffix" value=".ftl"/> </bean>
3.配置Freemarker参数
在applicationContext.xml中添加如下配置:
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <!--设置模板保存的目录--> <property name="templateLoaderPath" value="/WEB-INF/ftl"/> <!--其他设置--> <property name="freemarkerSettings"> <props> <!--设置Freemarker脚本与数据渲染时使用的字符集--> <prop key="defaultEncoding">UTF-8</prop> </props> </property> </bean>
具体使用,以后案例用到在演示。