SpringMVC框架学习笔记(二)
- 四、控制器
- 4.1 `@Controller`注解
- 4.2 `@RequestMapping`注解
- (1)URL常用映射
- (2)URL映射可以支持通配符`*`(不推荐)和占位符`{名称}`
- 重点:使用`RestFul`传递数据的形式和传统形式的对比
- (3)区分相同映射路径的方案
- 解决方案1:类似Struts2的方式,通过传递从`?`参数进行区分(个人不推荐)
- 解决方案2:通过请求方式区分不同的操作,但是HTML只能支持GET/POST请求,那么我们需要对其进行请求的转换(把某种请求方式转换成支持请求方式)
- 4.3 控制器中形参
- (1)Servlet API相关的对象(@Autowired)
- (2Java类的实例化情况
- 五、返回值类型
- 5.1 跳转JSP页面的方式
- 5.2 页面的输出
- 5.3 下载文件
- 5.4 输出JSON格式
- (1) 启动SpringMVC的内容数据转换
- (2) 引入转换工具类
- (3) 代码
Spring框架的帮助文档:Spring Web MVC只是Spring框架的一个模块而已,需要由Spring底层的支持才能使用。
SpringMVC官方介绍:
Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, “Spring Web MVC,” comes from the name of its source module (spring-webmvc), but it is more commonly known as “Spring MVC”.
Spring MVC, as many other web frameworks, is designed around the front controller pattern where a centralServlet
, theDispatcherServlet
, provides a shared algorithm for request processing, while actual work is performed by configurable delegate components. This model is flexible and supports diverse workflows.
DispatcherServlet
:前端控制器,所有的请求都经过其处理,根据映射URL找到对应的处理器(Controller),该前端控制器在服务器启动时就进行实例化和初始化操作(读取核心配置文件=>底层对各种类进行实例化操作)
- 默认核心配置文件的位置:
/WEB-INF/[servlet-name]-servlet.xml
-
contextConfigLocation
通过这个属性可以在初始化前端控制器的时候,自定义核心配置文件的位置和名称
四、控制器
4.1 @Controller
注解
只能标注类上,就会对该类进行实例化操作(初始化),默认的控制器的名称为类名的首字母小写(保存唯一性),不同包下相同类名,需要设置别名
扫描支持通配符
<!-- 支持通配符**代表任意的子层级 -->
<context:component-scan base-package="com.framework.**.web"/>
倘若出现两个不同包类名却相同并且都用这个注解的时候,会出现如下错误:
Annotation-specified bean name 'userController' for bean class [com.framework.web.UserController] conflicts with existing, non-compatible bean definition of same name and class [com.framework.a.b.c.web.UserController]
这个时候我们就可以用value属性给控制器自定义名称(value可以省略)
package com.framework.a.b.c.web;
import org.springframework.stereotype.Controller;
@Controller(value="myUserController")
public class UserController {
public UserController(){
System.out.println("wukong...myUserController");
}
}
初始化:
package com.framework.web;
import org.springframework.stereotype.Controller;
@Controller
public class UseController {
public UseController(){
System.out.println("九万里...useController..."+this);
}
}
4.2 @RequestMapping
注解
源码:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
- 该注解只能标注在类上或者方法上面
- 属性的说明
-
value
和path
:等价的,用于设置映射的路径,可以映射多个,如果只有该属性,那么可以省略属性的书写 -
method
:处理请求的方式,HTML页面中只能支持GET
和POST
请求 -
headers
:头信息,请求或者响应是设置头信息内容(很少) -
consumes
:设置请求的内容类型 -
produces
:设置响应的内容类型(text/html;charset=UTF-8
) -
params
:设置?
后必须或者不等的参数值,可以用来区分相同的映射路径
(1)URL常用映射
package com.framework.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/user")
public class UseController {
public UseController(){
System.out.println("九万里...useController..."+this);
}
@RequestMapping(value={"/add","/insert"})
public ModelAndView m1(){
System.out.println("用户添加请求");
return null;
}
@RequestMapping(path={"/update","/edit"})
public ModelAndView m2(){
System.out.println("用户更新请求");
return null;
}
@RequestMapping({"/delete","/remove"})
public ModelAndView m3(){
System.out.println("用户删除请求");
return null;
}
@RequestMapping("/get")
public ModelAndView m4(){
System.out.println("用户查询请求");
return null;
}
//访问该list映射只能使用POST请求方式
//不过不是POST请求会报 HTTP ERROR 405 Request method 'GET' not supported
@RequestMapping(value = "/list",method = RequestMethod.POST)
public ModelAndView m5(){
System.out.println("用户查询请求");
return null;
}
}
(2)URL映射可以支持通配符*
(不推荐)和占位符{名称}
为了满足RESTFUL
的路径的设计风格,Spring MVC通过占位符的方式可以实现RestFul的路径风格,并且可以传递数据。
RESTFUL特点包括:
1、每一个URI代表1种资源;
2、客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源;
3、通过操作资源的表现形式来操作资源;
4、资源的表现形式是XML或者HTML;
5、客户端与服务端之间的交互在请求之间是无状态的,从客户端到服务端的每个请求都必须包含理解请求所必需的信息。
映射路径的规则:
通配符<占位符<更加精确的值
注意:
谁描述的更加准确就使用谁
重点:使用RestFul
传递数据的形式和传统形式的对比
传统方式
@RequestMapping("/update")
public ModelAndView m3(HttpServletRequest request){
String id = request.getParameter("id");
int useId = Integer.parseInt(id);
System.out.println("useId = " + useId);
String name = request.getParameter("name");
System.out.println("name = " + name);
String sex = request.getParameter("sex");
System.out.println("sex = " + sex);
return null;
}
占位符方式;
@RequestMapping("/mod/{id}/{name}/{sex}")//定义了三个容器中已经有值,但是你没有告知给哪个形参
public ModelAndView m4(
@PathVariable("name") String userName,//userName=name
@PathVariable("sex") String userSex,//userSex=sex
@PathVariable/*("id")*/ Integer id//注解不能省略
//传递的数据转变失败:HTTP ERROR 400
){
System.out.println("userName = " + userName);
System.out.println("userSex = " + userSex);
System.out.println("id = " + id);
return null;
}
(3)区分相同映射路径的方案
@Controller
public class MenuController {
@RequestMapping("/menu")
public ModelAndView m1(){
System.out.println("添加操作");
return null;
}
@RequestMapping("/menu")
public ModelAndView m2(){
System.out.println("更新操作");
return null;
}
}
如果两个方法路径相同会报错:
模糊的映射(模棱两可)的映射
Ambiguous mapping. Cannot map ‘menuController’ method
com.framework.web.MenuController#m2()
to { /menu}: There is already ‘menuController’ bean method
com.framework.web.MenuController#m1() mapped
解决方案1:类似Struts2的方式,通过传递从?
参数进行区分(个人不推荐)
package com.framework.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
@Controller
public class MenuController {
//http://127.0.0.1:8080/mvc/menu?method=add&name=tomcat
@RequestMapping(value = "/menu",params = "method=add")
public ModelAndView m1(){
System.out.println("添加操作");
return null;
}
@RequestMapping(value = "/menu",params = "method=update")
public ModelAndView m2(){
System.out.println("更新操作");
return null;
}
@RequestMapping(value = "/menu",params = "m=get")
public ModelAndView m3(){
System.out.println("查询操作");
return null;
}
@RequestMapping(value = "/menu",params = "m=delete")
public ModelAndView m4(){
System.out.println("删除操作");
return null;
}
}
如果?
后面传递的值在属性中没有会报错
解决方案2:通过请求方式区分不同的操作,但是HTML只能支持GET/POST请求,那么我们需要对其进行请求的转换(把某种请求方式转换成支持请求方式)
帮助文档:
HTTP Method Conversion:HTTP请求的转换
A key principle of REST is the use of the “Uniform Interface”. This means that all resources (URLs) can be manipulated by using the same four HTTP methods: GET, PUT, POST, and DELETE. For each method, the HTTP specification defines the exact semantics. For instance, a GET should always be a safe operation, meaning that it has no side effects, and a PUT or DELETE should be idempotent, meaning that you can repeat these operations over and over again, but the end result should be the same. While HTTP defines these four methods, HTML only supports two: GET and POST. Fortunately, there are two possible workarounds: you can either use JavaScript to do your PUT or DELETE, or you can do a POST with the “real” method as an additional parameter (modeled as a hidden input field in an HTML form). Spring’sHiddenHttpMethodFilter
uses this latter trick. This filter is a plain Servlet filter and, therefore, it can be used in combination with any web framework (not just Spring MVC). Add this filter to your web.xml, and a POST with a hiddenmethod
parameter is converted into the corresponding HTTP method request.
- 使用JavaScript的Ajax方式发送
GET
/POST
/PUT
/DELETE
但是后两种只有部分浏览器支持(不推荐) - 使用
HiddenHttpMethodFilter
过滤器转换请求方式
- 设置真正的请求方式为
post
- 设置控件的
name="_method"
,在设置value=“请求方式”
- 设置
HiddenHttpMethodFilter
,该过滤器为Servlet filter
过滤器的是前端控制器
web.xml文件中:
<!--注册过滤器-->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<!--建立过滤器的映射FontServlrt-->
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<servlet-name>springmvc</servlet-name>
</filter-mapping>
<form action="dict" method="get">
<button>GET请求</button>
</form>
<hr/>
<form action="dict" method="post">
<button>POST请求</button>
</form>
<hr/>
<form action="dict" method="post">
<button>PUT请求</button>
<input type="hidden" name="_method" value="put">
</form>
<hr/>
<form action="dict" method="post">
<button>DELETE请求</button>
<input type="hidden" name="_method" value="delete">
</form>
有些公司只使用GET/POST
4.3 控制器中形参
SpringMVC的底层是使用Spring框架,Spring框架可以对各种类进行实例化,可以对JavaEE或者JavaSE提供的类型在形参上进行注入(
赋值
)
(1)Servlet API相关的对象(@Autowired)
- 形参中设置ServletAPI
@GetMapping("/test02")和@RequestMapping(path = “/test01”,method = RequestMethod.GET)等价
@Controller
@RequestMapping("/param")
public class MethodParamController01 {
//在别的地方已经实例化好一个HttpServletRequest类型的对象,@Autowired request=引用其他地方对象的地址
@RequestMapping(path = "/test01",method = RequestMethod.GET)
public ModelAndView m1(@Autowired HttpServletRequest request,@Autowired HttpServletResponse response){
System.out.println("request1 = " + request);
System.out.println("response1 = " + response);
return null;//空白页面
}
//@RequestMapping(path = "/test02",method = RequestMethod.GET)
@GetMapping("/test02")
public ModelAndView m2(HttpServletRequest request,HttpServletResponse response){//@Autowired可以省略
System.out.println("request2 = " + request);
System.out.println("response2 = " + response);
return null;//空白页面
}
@GetMapping("/test03")
public ModelAndView m2(HttpSession session){
System.out.println("session = " + session);
return null;//空白页面
}
@GetMapping(value = "/test04",produces = "text/html;charset=UTF-8")
public ModelAndView m2(PrintWriter out){
out.print(out);
out.write("悟空");//中文是乱码
return null;//空白页面
}
}
ServletContext
无法注入:没有提供默认的构造方法,在服务器启动的时候就实例化
//No primary or default constructor found for interface javax.servlet.ServletContext
@GetMapping("/test05")
public ModelAndView m2(ServletContext application){//无法注入:没有提供默认的构造方法,在服务器启动的时候就实例化
System.out.println("application = " + application);
return null;//空白页面
}
- 在形参中设置ServletAPI比较麻烦,提供了简化的写法,通过继承做到复用性
@Controller
@RequestMapping("/param")
public class MethodParamController02 {
@Autowired
private HttpServletRequest request;
@Autowired
private HttpServletResponse response;
@Autowired
private HttpSession session;
@Autowired
private ServletContext application;
@GetMapping("/test06")
public ModelAndView m2(){
System.out.println("request = " + request);
System.out.println("response = " + response);
System.out.println("session = " + session);
System.out.println("application = " + application);
return null;//空白页面
}
}
(2Java类的实例化情况
注意:
形参提供了构造方法无论是否可以访问,都可以被自动实例化(创建了对象)
- 接口
接口不能被实例化,但是如果提供了默认的实现类,该接口是可以被实例化
其中map接口和HashMap默认实现类都为:class org.springframework.validation.support.BindingAwareModelMap
@Controller
@RequestMapping("/param")
public class MethodParamController03 {
@GetMapping("/test07")
public ModelAndView m2(Map<String,Object> tempMap){//Map接口
//Map堆内存中的类型:class org.springframework.validation.support.BindingAwareModelMap
System.out.println("Map堆内存中的类型:"+tempMap.getClass());
return null;//空白页面
}
/**报错:No primary or default constructor found for interface java.util.List*/
@GetMapping("/test08")
public ModelAndView m2(List<String> tempList){//List接口
System.out.println("List堆内存中的类型:"+tempList.getClass());
return null;//空白页面
}
/** No primary or default constructor found for interface java.util.Set*/
@GetMapping("/test09")
public ModelAndView m2(Set<String> tempSet){//Set接口
System.out.println("Set 堆内存中的类型:"+tempSet.getClass());
return null;//空白页面
}
- 实现类
@GetMapping("/test10")
public ModelAndView m2(HashMap<String,Object> tempMap){
//HashMap 堆内存中的类型:class org.springframework.validation.support.BindingAwareModelMap
System.out.println("HashMap 堆内存中的类型:"+tempMap.getClass());
return null;//空白页面
}
/**ArrayList 堆内存中的类型:class java.util.ArrayList*/
@GetMapping("/test11")
public ModelAndView m2(ArrayList<String> tempList){
System.out.println("ArrayList 堆内存中的类型:"+tempList.getClass());
return null;//空白页面
}
/**HashSet 堆内存中的类型:class java.util.HashSet*/
@GetMapping("/test12")
public ModelAndView m2(HashSet<String> tempSet){
System.out.println("HashSet 堆内存中的类型:"+tempSet.getClass());
return null;//空白页面
}
/*
私有的构造方法,无法被外部实例化,但是通过反射可以进行实例化
com.framework.model.Cat@3038e7ce
狗的实例化
com.framework.model.Dog@61933af9
* */
@GetMapping("/test13")
public ModelAndView m2(Cat cat, Dog dog){//Set接口
System.out.println("HashSet 堆内存中的类型:"+cat.getClass()+","+dog.getClass());
return null;//空白页面
}
}
五、返回值类型
5.1 跳转JSP页面的方式
package com.framework.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;
@Controller
@RequestMapping("/page")
public class PageController {
/**ModelAndView请求转发JSP页面*/
@GetMapping("/forword01")//等价:@RequestMapping(method = RequestMethod.GET)
public ModelAndView jsp01_forword(){
ModelAndView mav = new ModelAndView("result01");
return null;
}
/**ModelAndView重定向JSP页面:跟JSP视图解析器无关*/
@GetMapping("/redirect01")
public ModelAndView jsp02_redirect(){
ModelAndView mav = new ModelAndView();
mav.setViewName("redirect:/view/result02.jsp");
return mav;
}
/**String:请求转发JSP页面*/
@GetMapping("/forward02")
public String jsp03_forward(){
//默认使用JSP视图解析器处理
return "result01";//如果没有设置 `redirect:重定向到JSP或者Controller` 或者 `forward:请求转发到Controller`
}
/**String:重定向JSP页面*/
@GetMapping("/redirect02")
public String jsp04_redirect(){
return UrlBasedViewResolver.REDIRECT_URL_PREFIX+ "/view/result02.jsp";//等价前缀设置rediewct
}
/**当你使用void没有经过特殊的处理,默认情况下是按照路径请求转发操作JSP页面*/
@GetMapping("/forward03")// /WEB-INF/jsp/page/forward03.jsp
public void jsp05_foward(){
System.out.println("VOID请求转发JSP页面");
}
}
我们跳转JSP的目的就是为了动态的生成HTML页面,JSP(模版引擎,还有一些其他的模版引擎)
5.2 页面的输出
当我们输出内容到页面的时候,也是一种数据的传递(out.writer(数据字符串)
)
- Java Web的写法
package com.framework.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@Controller
@RequestMapping("/out")
public class OutController {
@Autowired
private HttpServletRequest request;
@Autowired
private HttpServletResponse response;
@GetMapping("/test01")
public ModelAndView out01() throws IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write("<h3>月色</h3>");
out.write("<script>alert('如遇')</script>");
out.write("<script>window.location.href='http://www.4399.com'</script>");
out.close();
return null;//空白页面
}
- 使用SpringMVC完成等价的写法,
@GetMapping("/test02")
public ResponseEntity<String> out02(){
String content = "<h3>服务器绝对路径:"+request.getServletContext().getRealPath("")+"</h3>";
content+="<script>alert('客户端的IP地址:"+request.getRemoteAddr()+"')</script>";
content+="<script>alert('请求的路径:"+request.getRequestURI()+"')</script>";
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.valueOf("text/html;charset=UTF-8"));
return new ResponseEntity<>(content,httpHeaders, HttpStatus.OK);
}
- 另一种简洁的写法
使ResponseEntity返回值类型
ResponseEntity可以对任何的数据类型进行处理@ResponseBody
:被它注解的返回值类型的数据被会ResponseEntity处理可以写在形参前面:
public /*@ResponseBody*/ String out03(){}
也可以写在方法上:@ResponseBody
public String out03(){}
注意:
中文乱码解决方法:
在@GetMapping
注解属性produces
中设置@GetMapping(value ="/test03",produces = "text/html;charset=UTF-8")
@GetMapping(value = "/test03",produces = "text/html;charset=UTF-8")//设置响应内容类型和编码格式
@ResponseBody
public /*@ResponseBody*/ String out03(){//@ResponseBody返回值类型的数据被会ResponseEntity处理
//手动拼接JSON数据
StringBuilder builder = new StringBuilder();
builder.append("{");
builder.append("\"url\":"+request.getServletContext().getRealPath("")+",");
builder.append("\"name\":\"月色\",");
builder.append("\"age\":18");
builder.append("}");
return builder.toString();
}
5.3 下载文件
关于页面输出的类型text/html
,application/json
(IE浏览器不识别)、multipart/form
(二进制流的方式)
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
httpHeaders.setContentDispositionFormData("attachment",fileName);//下载的文件名称
作用:解决下载文件名称中文乱码问题
@Controller
public class DownloadController {
@Autowired
private HttpServletResponse response;
@Autowired
private HttpServletRequest request;
@RequestMapping("/download")
public ResponseEntity<byte[]> download() throws IOException {
//1.获取服务器的绝对路径和资源目录
//String path = request.getServletContext().getRealPath("/attr/");
//2.跟磁盘中的文件建立联系
//File file = new File(path+"/aaaa.txt");
File file = new File("D:/安装说明.txt");
//3.响应的内容类型
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);//二进制流
String fileName = "文档.docx";
//解决下载文件名称的中文乱码问题
fileName = new String(fileName.getBytes("UTF-8"),"ISO8859-1");//编码,解码
httpHeaders.setContentDispositionFormData("attachment",fileName);//下载的文件名称
//将文件转换成字节数组
return new ResponseEntity<>(FileUtils.readFileToByteArray(file),httpHeaders, HttpStatus.CREATED);
}
}
5.4 输出JSON格式
需要使用工具使返回值类型自动转换为JSON格式, 需要使用
jackson
的支持
(1) 启动SpringMVC的内容数据转换
<mvc:annotation-driven>
</mvc:annotation-driven>
(2) 引入转换工具类
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.1</version>
</dependency>
(3) 代码
- ResponseEntity
@Controller
public class JsonController {
@Autowired
private HttpServletResponse response;
@Autowired
private HttpServletRequest request;
@RequestMapping("/json01")
public ResponseEntity<Map<String,Object>> download() {
Map<String,Object> map = new HashMap<>();
map.put("bookName","乱");
map.put("price",888.5);
map.put("hobby",new String[]{"篮球","足球"});
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.valueOf("application/json;charset=UTF-8"));//IE浏览器下不支持
return new ResponseEntity<>(map,httpHeaders, HttpStatus.CREATED);
}
}
@ResponseBody
@RequestMapping("/json02")
@ResponseBody//等价//"application/json;charset=UTF-8" IE浏览器下不支持
public Map<String,Object> m2() {
Map<String,Object> map = new HashMap<>();
map.put("bookName","乱");
map.put("price",888.5);
map.put("hobby",new String[]{"篮球","足球"});
map.put("mydate", new Date());
return map;
}
- 此时IE浏览器不支持这种json格式,所以要自己设置核心配置文件的内容数据转换来解决问题:
<!-- 启动SpringMVC的内容数据转换 -->
<mvc:annotation-driven>
<mvc:message-converters>
<!--自己定义转换类-->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="defaultCharset" value="UTF-8"/><!--编码格式-->
<property name="prettyPrint" value="true"/><!--打印设为true-->
<property name="supportedMediaTypes"><!--支持的媒体格式,传递的是一个list-->
<list>
<value>text/html</value>
</list>
</property>
</mvc:annotation-driven>
- 此时返回的日期是一个时间戳,所以要设置核心配置文件来解决日期转换问题:
<!-- 启动SpringMVC的内容数据转换 -->
<!-- 启动SpringMVC的内容数据转换 -->
<mvc:annotation-driven>
<mvc:message-converters>
<!--自己定义转换类-->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="defaultCharset" value="UTF-8"/><!--编码格式-->
<property name="prettyPrint" value="true"/><!--打印设为true-->
<property name="supportedMediaTypes"><!--支持的媒体格式,传递的是一个list-->
<list>
<value>text/html</value>
</list>
</property>
<property name="objectMapper"><!--支解决日期问题-->
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat"><!--对其进行实例化-->
<constructor-arg value="yyyy-MM-dd HH:mm:ss"/>
</bean>
</property>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>