1,SpringMVC基础
Spring MVC是一款基于MVC架构模式的轻量级Web框架,其目的是将Web开发模块化,对整体架构进行解耦,简化 Web开发流程。Spring MVC基于请求驱动,即使用请求一响应模型。由于Spring MVC遵循MVC架构规范,因此分层开发数据模型层(Model)、响应视图层(View)和控制层(Controller),可以让开发者设计出结构规整的Web层。
1.1 SpringMVC有以下优点:
- Spring MVC本身是与Spring框架结合而成的,它同时拥有Spring 的优点(例如依赖注入(IOC)和切面编程(AOP)等)。
- Spring MVC提供了强大的约定大于配置的契约式编程支持,即提供一种软件设计范式,减少软件开发人员做决定的次数,开发人员仅需规定应用中不符合约定的部分。
- 支持灵活的URL 到页面控制器的映射。
- 可以方便地与其他视图技术(FreeMarker等)进行整合。由于Spring MVC的模型数据往往是放置在Map数据结构中的,因此其可以很方便地被其他框架引用。
- 拥有十分简洁的异常处理机制。
- 可以十分灵活地实现数据验证、格式化和数据绑定机制,可以使用任意对象进行数据绑定操作。
- 支持RESTful风格。
1.2 SpringMVC请求流程
由上图所示,SpringMVC的整体请求流程如下:
第一步,用户单击某个请求路径,发起一个request 请求,此请求会被前端控制器(DispatcherServlet)处理。
第二步,前端控制器(DispatcherServlet) 请求处理器映射器( HandlerMapping)去查找Handler。可以依据注解或者XML配置去查找。
第三步,处理器映射器(HandlerMapping) 根据配置找到相应的Handler (可能包含若千个Interceptor拦截器),返回给前端控制器(DispatcherServlet)。
第四步,前端控制器( DispatcherServlet)请求处理器适配器( HandlerAdapter)去执行相应的Handler (常称为Controller)。
第五步,处理器适配器( HandlerAdapter)执行Handler.
第六步,Handler执行完毕后会返回给处理器适配器( HandlerAdapter)一个ModelAndView对象( Spring MVC底层对象,包括Model数据模型和View视图信息)。
第七步,处理器适配器(HandlerAdapter) 接收到Handler 返回的ModelAndView后,将其返回给前端控制器( DispatcherServlet)。
第八步,前端控制器(DispatcherServlet) 接收到ModelAndView 后,会请求视图解析器( View Resolver)对视图进行解析。
第九步,视图解析器(View Resolver) 根据View信息匹配到相应的视图结果,反馈给前端控制器(DispatcherServlet)。
第十步,前端控制器( DispatcherServlet)收到View具体视图后,进行视图渲染,将Model中的模型数据填充到View视图中的request域,生成最终的视图(View)。
第十一步,前端控制器(DispatcherServlet) 向用户返回请求结果。
以上就是SpringMVC的整个请求处理流程,其中用到的组件有前端控制器(DispatcherServlet)、处理器映射器(HandlerMapping)、 处理器适配器( HandlerAdapter)、处理器(Handler)、 视图解析器(View Resolver)、视图(View)。
流程中出现的各个组件的功能说明如下:
-
前端控制器(DispatcherServlet)。 其作用是接收用户请求,然后给用户反馈结果。它的作用相当于一个转发器或中央处理器,控制整个流程的执行,对各个组件进行统一调度,以降低组件之间的耦合性,有利于组件之间的拓展。.
-
处理器映射器(HandlerMapping)。 其作用是根据请求的URL路径,通过注解或者XML配置,寻找匹配的处理器(Handler) 信息。
-
处理器适配器(HandlerAdapter)。 其作用是根据映射器找到的处理器( Handler)信息,按照特定规则执行相关的处理器(Handler)。
-
处理器(Hander)。 其作用是执行相关的请求处理逻辑,并返回相应的数据和视图信息,将其封装至ModelAndView对象中。
-
视图解析器(View Resolver)。其作用是进行解析操作,通过ModelAndView对象中的View信息将逻辑视图名解析成真正的视图View(如通过一个JSP路径返回一个真正的JSP页面)。
-
视图(View)。 其本身是一个接口,实现类支持不同的View类型(JSP、 FreeMarker、Excel等)。
2,SpringMVC环境搭建
1.2 依赖jar包的添加和前端控制器配置
使用maven管理依赖jar包
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
在项目结构中导入依赖:
由于使用了Spring MVC,请求就要交由Spring MVC来管理。我们知道,在一般的JSP/Servlet开发模式中,请求会被映射到Web.xml中,然后匹配到对应的Servlet配置上,进而调用相应的Servlet类处理请求并反馈结果。那么当使用SpringMVC框架来开发时,就需要将所有符合条件的请求拦截到Spring MVC的专有Servlet上,让Spring MVC框架进行下一步的处理。这里,需要在测试工程的WebRoot文件夹下的web.xml文件中添加Spring MVC的“前端控制器”,用于拦截符合配置的url请求。具体配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!--配置DispatcherServlet:这个是SpringMVC的核心:请求分发器,前端控制器-->
<!--在SpringMVC中,/与/*的区别:
/:只匹配所有的请求,不会去匹配jsp页面
/*:匹配所有的请求,包括jsp页面
-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--DispatcherServlet要绑定springmvc的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--设置启动级别:1-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2.2 编写核心配置文件:springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--spring核心配置文件-->
<!--处理器映射器-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean id="/hello" class="com.mofei.controller.HelloController"/>
<!--处理器适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--视图解析器 模板引擎:Thymeleaf Freemaker-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
现在springmvc.xml配置文件中添加处理器映射器,
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean id="/hello" class="com.mofei.controller.HelloController"/>
根据SpringMVC的请求流程,当处理器映射器HandlerMapping为前端控制器DispatcherServlet返回了控制器Handler的执行链之后,前端控制器接下来会请求处理器适配器HandlerAdapter去执行相关的Handler控制器( Handler会执行自己相应的Controller)。其原理是,DispatcherServlet 根据HandlerMapping传来的Handler ( 或Handler执行链)与配置的处理器适配器HandlerAdapter 进行匹配,找到可以处理此Handler (或Handler 执行链)类型的HandlerAdapter,该HandlerAdapter将会调用自己的handler方法,利用Java 的反射机制去执行具体的Controller方法并获得ModelAndView视图对象。
所以接下来要在springmve.xml中配置一个 处理器适配器HandlerAdapter。在Spring MVC中,常用的处理器适配器有HtpRequestHandlerAdapter,SimpleContollerHandlerAdapter 以及AnnotationMethodHandlerAdapter.这里配置的处理器适配器是SimpleControllerHandlerAdapter。主要配置如下:
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
当处理器适配器HandlerAdapter处理了相关的Handler的具体方法之后,Handler会返回一个视图对象ModelAndView, 该视图对象中包含了需要跳转的视图信息(View) 和需要在视图上显示的数据(Model), 此时前端控制器DispatcherServlet会请求视图解析器ViewResolver来帮助其解析视图对象ModelAndView,并返回相关的绑定有相应数据(Model)的视图View。所以接下来要配置视图解析器ViewResolver。 常用的视图解析器有XMLViewResolver (从xml配置文件解析视图)、ResourceBundleViewResolver (从properties 资源集解析视图)以及InternalResourceViewResolver ( 根据模板名称和位置解析视图),这里使用默认的InternalResourceViewResolver。主要配置如下:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
</bean>
2.3 编写handler处理器与视图
基本配置完成后,接下来的重头戏,就是处理请求逻辑的Handler处理器层。由于我们使用的处理器适配器是SimpleControllerHandlerAdapter,所以Handler只要实现Controller 接口即可。
在com.mofei.controller包下新建一个名为HelloController的类,让其实现Controller接口,然后实现handleRequest方法,并编写具体逻辑。
public class HelloController implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView modelAndView = new ModelAndView();
//业务代码
String result = "啊哈!墨菲";
modelAndView.addObject("msg",result);
//视图跳转
modelAndView.setViewName("test");
return modelAndView;
}
}
由于指定了返回的视图路径,所以在工程的/WEB-INF/jsp路径下创建名为test.jsp的文件,具体内容如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
将该项目部署到Tomcat服务器中,打开浏览器并访问:http://localhost:8080/shmvc/hello
3,使用注解开发SpringMVC
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->
<context:component-scan base-package="com.mofei.controller"/>
<!--让spring mvc 不处理静态资源 : .css .js .html .mp3 .mp4-->
<mvc:default-servlet-handler/>
<!--annotation-driven标签会自动注册处理器映射器和处理器适配器-->
<mvc:annotation-driven/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
使用“<mvc:annotation-driven />”标签来配置。annotation-driven 标签是一种简写模式,使用默认配置代替了一般的手动配置。annotation-driven 标签会自动注册处理器映射器和处理器适配器(Spring 4至Spring 3.1 皆使用RequestMappingHandlerMapping 及RequestMappingHandlerAdapter,而在Spring 3.1之前使用DefaultAnnotationHandlerMapping、AnnotationMethodHandlerAdapter)。并且除此之外还提供了数据绑定支持,例如@NumberFormatannotation支持、@DateTimeFormat支持、@Valid支持、读写XML的支持(JAXB) 和读写JSON的支持(Jackson)。在实际开发中,为了提高开发效率,使用最多的就是基于annotation-driven标签的配置。annotation-driven 标签的配置十分简单,如下所示:
<mvc:annotation-driven/>
下面开发Handler处理器层。由于使用了注解的处理器映射器和适配器,所以不需要在XML文件中配置任何信息,也不需要实现任何接口,只需要在作为Handler处理器的Java类中添加相应的注解即可。
@Controller
public class HelloController {
//@RequestMapping注解的作用是:为控制器指定可以处理哪些URL请求
@RequestMapping("/hello")
public String hello(Model model){
//向模型中添加属性msg与值,可以在jsp页面中取出并渲染
model.addAttribute("msg","你好,SpringMVC");
return "hello";
}
}
web.xml文件配置不变,然后将该项目部署到Tomcat服务器中,打开浏览器并访问:http://localhost:8080/shmvc/hello
测试结果:
3.1 Controller与RequestMapping说明
在使用annotation-driven标签时,处理器Handler的类型要符合annotation-driven 标签指定的处理器映射器和适配器的类型。annotation-driven标签指定的默认处理器映射器和适配器在Spring 3.1之前为DefaultAnnotationHandlerMapping、AnnotationMethodHandlerAdapter, 在Spring 3.1之后为RequestMappingHandlerMapping和RequestMappingHandlerAdapter.
每一个适配器都实现了HandlerMapping接口,而HandlerMapping定义了三个方法:
public interface HandlerAdapter {
boolean supports(Object handler);
@Nullable
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
long getLastModified(HttpServletRequest request, Object handler);
其中的supports方法用来检测Handler是否是支持的类型,下面是RequestMappingHandlerMapping的supports方法的源码:
public final boolean supports(Object handler) {
return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
}
可以看出,RequestMappingHandlerMapping支持HandlerMethod类型的Handler,而HandlerMethod会访问方法参数,方法的返回值及方法的注解,所以它支持含有注解信息的Handler类。
在配置了注解的处理器映射器和适配器的情况下,当使用@Controller注解去标识一个类时,其实就是告诉Spring MVC该类是一个Handler控制器类。在配置了component-scan 标签后,当Spring初始化Bean信息时,会扫描到所有标注了@Controller 注解的类,并将其作为Handler来加载。
@RequestMapping注解的作用是为控制器指定可以处理哪些URL请求,该注解可以放置在类上或者方法上。当放置在类上时,提供初步的URL请求映射信息,即一个前置请求路径(相对于Web应用的根目录)。当放置在方法上时,提供进一步的细分URL映射信息,相对于类定义处的URL。若类定义处未标注@RequestMapping,则方法处标记的URL相对于Web应用的根目录。
注解@RequestMapping可以映射路径,还可以限定请求方法,请求参数,请求头。
对于请求方法,@RequestMapping的method属性可以指定“GET"或“POST"请求类型,表明该URL只能以某种请求方式请求才能获得响应:
@Controller
public class HelloController {
//@RequestMapping注解的作用是:为控制器指定可以处理哪些URL请求,
//并且只能以method中的请求方式才能获得相应
@RequestMapping(value = "/hello",method = RequestMethod.GET)
public String hello(Model model){
//向模型中添加属性msg与值,可以在jsp页面中取出并渲染
model.addAttribute("msg","你好,SpringMVC");
return "hello";
}
}
对于请求参数,@RequestMapping 的param属性可以指定某一种 参数名类型,当请求数据中含有该名称的请求参数时,才能进行响应:
@RequestMapping(value = "/hello",params = "username")
public String hello(Model model){
该配置表示,当一个URL请中不含有名称为“username”的参数时,该方法就拒绝此次请求。
对于请求头,@RequestMapping的headers属性可以指定某一种请求头类型,当请求数据头的类型符合指定的值时,才能进行响应:
@RequestMapping(value = "/hello",headers = "Content-Type:text/html;charset=UTF-8")
public String hello(Model model){
该配置表示,当一个请求头中的Content-Type为“ text/html;charset=UTF-8”的参数时,该方法才会处理此次请求。
还有两个属性,分别是consumes和produces。其中consumes表示处理请求的提交内容类型(Content-Type),例如“application/json, text/html”。而produces 表示返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型时才返回。
consumes:
@RequestMapping(value = "/hello",method = RequestMethod.GET,consumes = "application/json")
public String hello(Model model){
该配置表示,该方法仅处理request的Content-Type为“application/json”类型的请求。
produces:
@RequestMapping(value = "/hello",method = RequestMethod.GET,produces = "application/json")
public String hello(Model model){
该配置表示方法仅处理request请求中Accept头包含“application/json”的请求,同时暗示了返回的内容类型为application/json。
4,利用SpringMVC实现RESTful风格
4.1 RESTful
RESTful为“Representational State Transfer”的缩写,中文释义为“表现层状态转换”。RESTful不是一种标准,而是- -种设计风格。RESTful 本质上是一种分布式系统的应用层解决方案,它的主要作用是充分并正确利用HTTP协议的特性,规范资源获取的URI路径。通俗地讲,RESTful风格的设计允许将参数通过URL拼接传到服务端,目的是让URL看起来更简洁实用。 并且对于不同操作,要指定不同的HTTP方法(POST/GET/PUT/DETELE)。可以这么说,只要是具有上述相关约束条件和原则的应用程序或设计就可以被称作RESTful风格的应用。
在RESTful风格的请求路径中,资源是由URI来指定的,RESTful 通过规范资源的表现形式来操作资源,其是资源状态的一种表达。一个满足RESTful的程序或设计应满足以下条件和约束:
第一,对请求的URL进行规范。RESTful 风格的URL的设计目的是将资源通过合理方式暴露出来。在RESTful风格的URL中不会出现动词,而是使用HTTP协议的动词。
下图为非RESTful风格的URL及RESTful风格的URL的区别:
第二,充分利用HTTP方法。在下表中,前面是HTTP请求对应的动作方法,包含了GET、POST、PUT、PATCH及DETELE方法,需要在不同的请求场景下使用不同的HTTP方法。
HTTP方法名 | 使用场景 |
---|---|
GET | 从服务器取出资源(一项或多项) |
POST | 在服务器新建一个资源 |
PUT | 在服务器更新资源(客户端提供完整的资源数据) |
PATCH | 在服务器更新资源(客户端提供完整的资源数据) |
DELETE | 从服务器删除资源 |
4.2 在SpringMVC中实现RESTful风格
SpringMVC可以使用@RequestMapping的路径设置,结合@PathVariable的参数指定,来实现RESTful风格的请求。
@Controller
public class RESTfulController {
@RequestMapping(value = "/add/{a}/{b}", method = RequestMethod.GET)
public String test(@PathVariable int a,@PathVariable int b, Model model){
int res = a + b;
model.addAttribute("msg", "a + b结果为 : " + res);
return "hello";
}
}
在该方法中,在@RequestMapping 注解的请求路径中添加了两个个动态数据“{a}"和“{b}”,它的作用是解析前台的请求路径,将动态数据所在的位置解析为名为a和b的请求参数。而在Controller的参数中,使用 @PathVariable注解,在其中指定请求参数的key名称,并映射在后面定义的形参上。方法体中其余的操作就是正常的业务逻辑。总的来说,利用Spring MVC实现RESTful风格主要就在于请求路径和请求参数的映射,以及RequestMethod的指定。
SpringMVC的@RequestMapping注解能够处理HTTP请求的方法,比如,GET,PUT,POST,DELETE,以及PATCH。,所有的地址栏请求默认都会是HTTP GET类型的。
方法级别的变体有如下几个:组合注解
@GetMapping(value=“#”) <====>@RequestMapping(value=“#”,method=RequestMethod.GET)
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
5,数据处理及数据回显
5.1 处理提交数据
- 提交的域名称与处理方法的参数名一致
提交数据:http://localhost:8080/sc4/t1?name=墨菲
处理方法:
@GetMapping("/t1")
public String test2(String name){
System.out.println(name);//墨菲
return "test";
}
2.提交的域名称和处理方法的参数名不一致
提交数据:http://localhost:8080/sc4/t1?username=墨菲
处理方法:使用注解@RequestParam
@GetMapping("/t1")
public String test2(@RequestParam("username") String name){
System.out.println(name);//墨菲
return "test";
}
3.提交的是一个对象
要求提交的表单域和对象的属性名一致,参数使用对象即可
实体类:
public class User {
private int id;
private String name;
private int age;
//get与set方法省略
}
提交数据:http://localhost:8080/sc4/t2?id=1&name=墨菲&age=8
处理方法:
@GetMapping("/t2")
public String test2(User user){
System.out.println(user);
return "test";//User{id=1, name='墨菲', age=8}
}
如果使用对象的话,前端传递的参数名和对象名必须一致,否则对应项就是null。
5.2 数据显示到前端
第一种:通过ModelAndView
可以在存储数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的扩展;
public class HelloController implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView modelAndView = new ModelAndView();
//业务代码
String result = "啊哈!墨菲";
modelAndView.addObject("msg",result);
//视图跳转
modelAndView.setViewName("test");
return modelAndView;
}
}
第二种:通过Model
只适合用于存储数据
@Controller
public class UserController {
@GetMapping("/t1")
public String test(@RequestParam("username") String name, Model model){
//1,接收前端参数
System.out.println(name);
//2,将返回的结果传递给前端 Model
model.addAttribute("msg",name);
//3,视图跳转
return "test";
}
}
第三种:通过ModelMap
public class ModelMap extends LinkedHashMap<String, Object> {}
ModelMap继承了LinkedMap,除了实现自身的一些方法,同样的继承LinkedMap的方法和特性;
@Controller
public class UserController {
@GetMapping("/t1")
public String test(@RequestParam("username") String name, ModelMap model){
//封装要显示到视图中的数据
//相当于req.setAttribute("msg",name)
model.addAttribute("msg",name);
System.out.println(name);
return "test";
}
6,利用SpringMVC实现JSON交互
JSON的数据格式规则十分简洁,书写格式为“数据名称:值”,组合中的名称写在前面(在双引号中),值对写在后面(同样在双引号中),中间用冒号隔开,最外层添加一对花括号即可:{“username”:“mofei”} ,当有多个参数时,使用英文逗号隔开。
JSON中的值可以有多重类型,每种类型有不同的表现形式:
格式 | JSON格式 |
---|---|
数字(整数或浮点数) | {“age”:8,“height”:172} |
字符串 | {“name”:“张三”} |
逻辑值 | {“isEmpty”:true} |
数组(在方括号中) | {“people”:[{“age”:3,“name”:“墨菲”,“sex”:“男”},{“age”:3,“name”:“墨菲2”,“sex”:“男”},{“age”:3,“name”:“墨菲3”,“sex”:“男”}]} |
对象 | {“people”:{“firstName”:“Brett”,“lastName”:McLaughlin",“email”:“aaaa”}} |
空(null) | {“tellphonenumber”:null} |
组装和解析JSON格式信息的工具类:json-lib,org-json,fast-json及jackson等,可以解决JSON交互的开发效率。
SpringMVC主要利用类型转换器(messageConverters)将前台信息转换成开发者需要的格式。然后在相应的Controller方法接收参数前添加@RequestBody注解,进行数据转换,或在方法的返回值类型处添加@ResponseBody注解,将返回信息转换成相关格式的数据。
@RequestBody注解的特点就是,根据请求参数的contentType决定是否将相关格式转换至包装类,如果contentType是目标类型,就进行转换。这里转换的是JSON数据,所以要求将前端请求的contentType指定为“application/json”类型,而普通key/value请求参数的contentType默认为“application/x-www-form-urlen”类型。
导入JSON依赖:
<dependencies>
<!--jackson-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.0-rc2</version>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
</dependencies>
统一json乱码问题:
<!--配置处理器,json乱码同一配置-->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
这里使用jackson测试案例:
实体类:
public class User {
private String name;
private int age;
private String sex;
//省略get和set方法省略
}
@RestController
public class UserController {
@RequestMapping(value = "/j1",produces = "application/json;charset=utf-8")
//@ResponseBody//此注解不会走视图解析器,直接返回一个字符串
public String json() throws JsonProcessingException {
//jackson包,ObjectMapper
ObjectMapper mapper = new ObjectMapper();
//创建一个对象
User user = new User("墨菲", 3, "男");
String valueAsString = mapper.writeValueAsString(user);
return valueAsString;
}
}
{"name":"墨菲","age":3,"sex":"男"}
使用@RestController或@ResponseBody中其中一个注解都可以将响应数据解析为JSON格式返回客户端。
@RequestMapping(value = "/j2",produces = "application/json;charset=utf-8")
@ResponseBody//此注解不会做视图解析器,直接返回一个字符串
public String json2() throws JsonProcessingException {
//jackson包,ObjectMapper
ObjectMapper mapper = new ObjectMapper();
List<User> users = new ArrayList<User>();
//创建一个对象
User user = new User("墨菲", 3, "男");
User user2 = new User("墨菲2", 3, "男");
User user3 = new User("墨菲3", 3, "男");
User user4 = new User("墨菲4", 3, "男");
users.add(user);
users.add(user2);
users.add(user3);
users.add(user4);
String valueAsString = mapper.writeValueAsString(users);
return valueAsString;
}
[{"name":"墨菲","age":3,"sex":"男"},{"name":"墨菲2","age":3,"sex":"男"},{"name":"墨菲3","age":3,"sex":"男"},{"name":"墨菲4","age":3,"sex":"男"}]
@RequestMapping(value = "/j3",produces = "application/json;charset=utf-8")
@ResponseBody//此注解不会做视图解析器,直接返回一个字符串
public String json3() throws JsonProcessingException {
//jackson包,ObjectMapper
ObjectMapper mapper = new ObjectMapper();
Date date = new Date();
//自定义日期的格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String s = sdf.format(date);
//ObjectMapper,时间解析后的默认格式为:Timestamp,时间戳
String valueAsString = mapper.writeValueAsString(s);
return valueAsString;
}
"2020-12-04 00:04:38"
@RequestMapping(value = "/j4",produces = "application/json;charset=utf-8")
@ResponseBody//此注解不会做视图解析器,直接返回一个字符串
public String json4() throws JsonProcessingException {
//jackson包,ObjectMapper
ObjectMapper mapper = new ObjectMapper();
//关闭时间戳的使用方式
mapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS,false);
//自定义日期的格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
mapper.setDateFormat(sdf);
Date date = new Date();
String s = sdf.format(date);
//ObjectMapper,时间解析后的默认格式为:Timestamp,时间戳
String valueAsString = mapper.writeValueAsString(s);
return valueAsString;
}
"2020-12-04 00:06:10"