SpringMVC 4.x输出JSON数据配置
我们在日常开发工作中,会遇到需要输出JSON格式数据的需求,特别是rest风格盛行的今日。那么怎么来配置JSON格式结果输出呢?一般情况我们采用jackson-databind或者fastjson来做返回数据的JSON序列化处理。
依赖jar包引入
使用jackson-databind时需要引入如下依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.5</version>
</dependency>
使用fastjson时需要引入如下依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.23</version>
</dependency>
建议尽量使用新版本,避免出现奇怪的版本问题异常。
怎么配置到我们的工程中呢,我们一般有如下几种方式
第一种方法
我们可以在xml配置文件的配置RequestMappingHandlerAdapter对应的Bean
<!--采用以下配置支持controller中返回String,否则会当成是视图名称和路劲处理-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<!-- String结果数据支持,此解析器要放在JSON解析器前 -->
<ref bean="stringHttpMessageConverter"/>
<!-- JSON结果数据支持(使用fastjson) -->
<ref bean="fastJsonHttpMessageConverter"/>
<!-- JSON结果数据支持(使用jackson) -->
<!-- <ref bean="mappingJacksonHttpMessageConverter" /> -->
</list>
</property>
</bean>
<!-- String转化器 -->
<bean id="stringHttpMessageConverter"
class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<!-- 这里顺序不能反,一定先写text/html,不然ie下出现下载提示 -->
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- JSON转化器(jackson版本) -->
<bean id="mappingJacksonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<!-- <bean class="com.threeStepTech.ObjectMapper.CustomObjectMapper"/> -->
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss"/>
</bean>
</property>
<property name="serializationInclusion">
<!-- 注入枚举类型,过滤对象,这样JSON中不会输出null -->
<value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value>
</property>
</bean>
</property>
<property name="supportedMediaTypes">
<list>
<!-- 这里顺序不能反,一定先写text/html,不然ie下出现下载提示 -->
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- JSON转化器(fastjson版本) -->
<bean id="fastJsonHttpMessageConverter"
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4">
<property name="supportedMediaTypes">
<list>
<!-- 这里顺序不能反,一定先写text/html,不然ie下出现下载提示 -->
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
<property name="fastJsonConfig">
<bean class="com.alibaba.fastjson.support.config.FastJsonConfig">
<property name="dateFormat" value="yyyy-MM-dd HH:mm:ss"/>
<property name="serializerFeatures">
<array>
<!--此配置用于将Date类型转化为dateFormat对应的格式-->
<value>WriteDateUseDateFormat</value>
</array>
</property>
</bean>
</property>
</bean>
第二种方式
我们可以在<mvc:annotation-driven/>
添加 <mvc:message-converters>
变量信息,具体代码如下:
<mvc:annotation-driven>
<mvc:message-converters>
<bean id="stringHttpMessageConverter"
class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<!-- 这里顺序不能反,一定先写text/html,不然ie下出现下载提示 -->
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- 如果不使用jackson可使用fastjson版本JSON转换器 -->
<bean id="mappingJacksonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<!-- <bean class="com.threeStepTech.ObjectMapper.CustomObjectMapper"/> -->
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss"/>
</bean>
</property>
<property name="serializationInclusion">
<!-- 注入枚举类型,过滤不输出null -->
<value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value>
</property>
</bean>
</property>
<property name="supportedMediaTypes">
<list>
<!-- 这里顺序不能反,一定先写text/html,不然ie下出现下载提示 -->
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
其中mappingJacksonHttpMessageConverter 可以替换为fastjson版本的配置
<bean id="fastJsonHttpMessageConverter"
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4">
<property name="supportedMediaTypes">
<list>
<!-- 这里顺序不能反,一定先写text/html,不然ie下出现下载提示 -->
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
<property name="fastJsonConfig">
<bean class="com.alibaba.fastjson.support.config.FastJsonConfig">
<property name="dateFormat" value="yyyy-MM-dd HH:mm:ss"/>
<property name="serializerFeatures">
<array>
<value>WriteDateUseDateFormat</value>
</array>
</property>
</bean>
</property>
</bean>
以上是直接使用Spring 4.2.x以上版本时候的配置方式,如果我们使用spring boot,那么该怎么配置呢?我们可以WebMvcConfigurerAdapter并重写extendMessageConverters方法,具体格式如下
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
/**
* Created by comven on 2017/1/20.
*/
@Configuration
@EnableWebMvc
public class AutoConfig extends WebMvcConfigurerAdapter {
private Charset default_charset = Charset.forName("UTF-8");
private static List<MediaType> buildDefaultMediaTypes() {
List<MediaType> list = new ArrayList<>();
list.add(MediaType.TEXT_HTML);
list.add(MediaType.APPLICATION_JSON_UTF8);
return list;
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(stringHttpMessageConverter());
converters.add(mappingJackson2HttpMessageConverter());
//如果不使用MappingJackson2HttpMessageConverter,可使用如下的转换器
//spring4.2以上使用如下转换器
//converters.add(fastJsonHttpMessageConverter4());
//spring4.2以下使用如下转换器
//converters.add(fastJsonHttpMessageConverter());
super.extendMessageConverters(converters);
}
@Bean
public StringHttpMessageConverter stringHttpMessageConverter() {
StringHttpMessageConverter converter = new StringHttpMessageConverter(default_charset);
List<MediaType> list = buildDefaultMediaTypes();
converter.setSupportedMediaTypes(list);
return converter;
}
/**
* 创建jackson类型的JsonHttpMessageConverter
*
* @return MappingJackson2HttpMessageConverter
*/
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);//此设置使输出json时不显示null类型的字段
converter.setObjectMapper(objectMapper);
List<MediaType> list = buildDefaultMediaTypes();
converter.setSupportedMediaTypes(list);
return converter;
}
/**
* spring4.2以后建议采用这个方式创建
*
* @return FastJsonHttpMessageConverter4
*/
@Bean
public FastJsonHttpMessageConverter4 fastJsonHttpMessageConverter4() {
FastJsonHttpMessageConverter4 converter = new FastJsonHttpMessageConverter4();
List<MediaType> list = buildDefaultMediaTypes();
converter.setSupportedMediaTypes(list);
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
fastJsonConfig.setCharset(default_charset);
//此处是可变参数可以配置多个
fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteDateUseDateFormat);//SerializerFeature.WriteMapNullValue此配置加上后会输出null
converter.setFastJsonConfig(fastJsonConfig);
return converter;
}
/**
* spring4.2以前可以采用这个方式创建
*
* @return FastJsonHttpMessageConverter
*/
@Bean
public FastJsonHttpMessageConverter fastJsonHttpMessageConverter() {
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
fastJsonConfig.setCharset(default_charset);
//此处是可变参数可以配置多个
fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteDateUseDateFormat);//SerializerFeature.WriteMapNullValue此配置加上后会输出null
converter.setFastJsonConfig(fastJsonConfig);
List<MediaType> list = buildDefaultMediaTypes();
converter.setSupportedMediaTypes(list);
return converter;
}
}
使用此方式后不需要在xml文件中配置<mvc:annotation-driven/>
申明。
使用以上三种配置方式之后,只需要在Controller的方法上使用@ResponseBody注解或者Controller采用@RestController 我们的controller方法就会输出对应的String数据或者JSON格式数据
特别说明:
fastjson提供的MessageConverter分为两个版本,一个是spring4.0以下类名为FastJsonHttpMessageConverter,spring4.0以上使用FastJsonHttpMessageConverter4。