SpringMVC中使用Jackson和FastJson
1、Jackson
- 导入相关依赖
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.0</version>
</dependency>
- 创建User类
package com.wust.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String pwd;
}
- 编写UserController
@RestController //@Controller 和 @ResponseBody的组合注解,不会走视图解析器,只返回字符串
public class UserController {
@RequestMapping(value = "/json",produces = "application/json;charset=utf-8")
public String json() throws JsonProcessingException {
User user = new User(1,"张三","111");
ObjectMapper objectMapper = new ObjectMapper();
String str = objectMapper.writeValueAsString(user);
return str;
//produces = "application/json;charset=utf-8"的作用是防止中文乱码,缺点是每个返回json的方法上都要添加。
- 因为通过 produces = "application/json;charset=utf-8"防止中文乱码需在每个返回json的方法上都要添加,方法多了会很麻烦。因此springMVC 提供了可以在配置文件中统一配置的策略。另外produces的作用是指定返回值类型和返回值编码。与之对应的还有consumes,作用是指定提交到方法的请求的内容类型(Content-Type),比如在上面的json方法中设置consumes="application/json",此时该方法只处理json类型的请求。
<?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">
<!--自动扫描包,让指定包下的注解生效-->
<context:component-scan base-package="com.wust.controller"/>
<!--过滤掉静态资源(css,js,html...),防止静态资源被视图解析器处理-->
<mvc:default-servlet-handler/>
<!--
支持mvc注解驱动
在spring中一般采用@RequestMapping注解来完成映射关系
要使@RequestMapping注解生效,必须向容器中注册DefaultAnnotationHandlerMapping
以及AnnotationMethodHandlerAdapter实例,这两个实例分别在类级别和方法级别处理
而annotation-driven配置会自动注入上述两个实例的注入
-->
<mvc:annotation-driven>
<!--统一设置返回json数据的编码为UTF-8-->
<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>
<!--视图解析器-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
1.1、<mvc:message-converters register-defaults="true">的简单介绍
首先说说@ResponseBody注解,很明显这个注解就是将方法的返回值作为reponse的body部分。我们进一步分析下这个过程涉及到的内容,首先就是方法返回的类型,可以是字节数组、字符串、对象引用等,将这些返回类型以什么样的内容格式(即response的content-type类型,同时还要考虑到客户端是否接受这个类型)存进response的body中返回给客户端是一个问题,对于这个过程的处理都是靠各种HttpMessageConverter转换器来完成的。
点击@ResponseBody源码,我们可以看到这两个属性consumes和produces,它们就是分别用来指定request的content-type和response的content-type的。都可以接收一个或者多个。下面看下各种converter.
ByteArrayHttpMessageConverter | 支持返回值类型为byte[],content-type为application/octet-stream,*/* |
StringHttpMessageConverter | 支持的返回值类型为String,默认content-type为 text/plain;charset=ISO-8859-1 |
ResourceHttpMessageConverter | 支持的返回值类型为Resource,content-type为 */* |
SourceHttpMessageConverter | 支持的返回值类型为DomSource,SAXSource,Source,StreamSource,content-type为application/xml,text/xml,application/*+xml |
MappingJacksonHttpMessageConverter | 判断返回值能否被格式化成json,content-type为 application/json,application/*+json |
AllEncompassingFormHttpMessageConverter | 支持的返回值类型为MultiValueMap,content-type为application/x-www-form-urlencoded,multipart/form-data |
具体的消息转换机制原理参考博文https://my.oschina.net/lichhao/blog/172562
2、FastJson
- 导入依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
- fastjson 三个主要的类
JSONObject 代表 json 对象
-
JSONObject实现了Map接口, 猜想 JSONObject底层操作是由Map实现的。
-
JSONObject对应json对象,通过各种形式的get()方法可以获取json对象中的数据,也可利用诸如size(),isEmpty()等方法获取"键:值"对的个数和判断是否为空。其本质是通过实现Map接口并调用接口中的方法完成的。
JSONArray 代表 json 对象数组
-
内部是有List接口中的方法来完成操作的。
JSON代表 JSONObject和JSONArray的转化
-
JSON类源码分析与使用
-
仔细观察这些方法,主要是实现json对象,json对象数组,javabean对象,json字符串之间的相互转化。
具体使用方法如下:
//创建对象
User user1 = new User("张三", 3, "男");
User user2 = new User("李四", 3, "男");
User user3 = new User("王五", 3, "男");
User user4 = new User("赵六", 3, "男");
List<User> list = new ArrayList<User>();
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
//*******Java对象 转 JSON字符串*******
String str1 = JSON.toJSONString(list);
System.out.println("JSON.toJSONString(list)==>"+str1);
String str2 = JSON.toJSONString(user1);
System.out.println("JSON.toJSONString(user1)==>"+str2);
//****** JSON字符串 解析为 Java对象*******
User user=JSON.parseObject(str2,User.class);
System.out.println("JSON.parseObject(str2,User.class)==>"+user);
//****** Java对象 转 JSON对象 ******
JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2);
System.out.println("(JSONObject)
JSON.toJSON(user2)==>"+jsonObject1.getString("name"));
//****** JSON对象 转 Java对象 ******
User to_java_user = JSON.toJavaObject(jsonObject1, User.class);
System.out.println("JSON.toJavaObject(jsonObject1, User.class)==>"+to_java_user);