Spring4.2+整合FastJson
前幾天升級Spring附帶把原先使用jackson替換爲速度比較快一點的fastjson,fastjson在處理大數據量的時候相對是要快一點。這個網上很多測評我就不多說了。
迴歸正傳,當決定升級spring的時候,就把spring升級到了4.2.8然後問題來了。整合不了fastjson,配置了直接不頂用,這特麼就尷尬了。拍胸脯保證的事情,苦逼的整吧。網上資源也比較少。就自己用maven整了源碼。
Spring4.2+相配的fastjson
在看原來的4.2-的源碼,![這裏寫圖片描述](https://img-blog.csdn.net/20161128211917854)
FastJsonHttpMessageConverter發現這個類。這個類主要作用是轉換器;它是4.2-的寫法。發現了一個問題那就是註釋:
/**
* Fastjson for Spring MVC Converter.
* <p>
* Compatible Spring MVC version 4.2- (Below 4.2)
*
* @author VictorZeng
* @see AbstractHttpMessageConverter
* @see GenericHttpMessageConverter
* @since 1.2.10
*/
看到沒有Compatible Spring MVC version 4.2- (Below 4.2)試用4.2以下版本。好像不是思想的問題。應該是沒問題。在看下面有一個FastJsonHttpMessageConverter4類。點進去
/**
* Fastjson for Spring MVC Converter.
* <p>
* Compatible Spring MVC version 4.2+
*
* @author Victor.Zxy
* @see AbstractGenericHttpMessageConverter
* @since 1.2.11
*/
Compatible Spring MVC version 4.2+找到了,那麼我們應該是用這個類。在對比一下這兩個類有什麼區別。
FastJsonHttpMessageConverter
public class FastJsonHttpMessageConverter //
extends AbstractHttpMessageConverter<Object> //
implements GenericHttpMessageConverter<Object> {
@Deprecated
protected Charset charset = IOUtils.UTF8;
@Deprecated
protected SerializerFeature[] features = new SerializerFeature[0];
@Deprecated
protected SerializeFilter[] filters = new SerializeFilter[0];
@Deprecated
protected String dateFormat;
/**
* with fastJson config
*/
private FastJsonConfig fastJsonConfig = new FastJsonConfig();
/**
* @return the fastJsonConfig.
* @since 1.2.11
*/
public FastJsonConfig getFastJsonConfig() {
return fastJsonConfig;
}
/**
* @param fastJsonConfig the fastJsonConfig to set.
* @since 1.2.11
*/
public void setFastJsonConfig(FastJsonConfig fastJsonConfig) {
this.fastJsonConfig = fastJsonConfig;
}
/**
* Can serialize/deserialize all types.
*/
public FastJsonHttpMessageConverter() {
super(MediaType.ALL);
}
@Deprecated
public Charset getCharset() {
return this.fastJsonConfig.getCharset();
}
@Deprecated
public void setCharset(Charset charset) {
this.fastJsonConfig.setCharset(charset);
}
@Deprecated
public String getDateFormat() {
return this.fastJsonConfig.getDateFormat();
}
@Deprecated
public void setDateFormat(String dateFormat) {
this.fastJsonConfig.setDateFormat(dateFormat);
}
@Deprecated
public SerializerFeature[] getFeatures() {
return this.fastJsonConfig.getSerializerFeatures();
}
@Deprecated
public void setFeatures(SerializerFeature... features) {
this.fastJsonConfig.setSerializerFeatures(features);
}
@Deprecated
public SerializeFilter[] getFilters() {
return this.fastJsonConfig.getSerializeFilters();
}
@Deprecated
public void setFilters(SerializeFilter... filters) {
this.fastJsonConfig.setSerializeFilters(filters);
}
@Deprecated
public void addSerializeFilter(SerializeFilter filter) {
if (filter == null) {
return;
}
int length = this.fastJsonConfig.getSerializeFilters().length;
SerializeFilter[] filters = new SerializeFilter[length + 1];
System.arraycopy(this.fastJsonConfig.getSerializeFilters(), 0, filters, 0, length);
filters[filters.length - 1] = filter;
this.fastJsonConfig.setSerializeFilters(filters);
}
@Override
protected boolean supports(Class<?> clazz) {
return true;
}
@Override
protected Object readInternal(Class<? extends Object> clazz, //
HttpInputMessage inputMessage //
) throws IOException, HttpMessageNotReadableException {
InputStream in = inputMessage.getBody();
return JSON.parseObject(in, fastJsonConfig.getCharset(), clazz, fastJsonConfig.getFeatures());
}
@Override
protected void writeInternal(Object obj, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
HttpHeaders headers = outputMessage.getHeaders();
ByteArrayOutputStream outnew = new ByteArrayOutputStream();
int len = JSON.writeJSONString(outnew, //
fastJsonConfig.getCharset(), //
obj, //
fastJsonConfig.getSerializeConfig(), //
fastJsonConfig.getSerializeFilters(), //
fastJsonConfig.getDateFormat(), //
JSON.DEFAULT_GENERATE_FEATURE, //
fastJsonConfig.getSerializerFeatures());
headers.setContentLength(len);
OutputStream out = outputMessage.getBody();
outnew.writeTo(out);
outnew.close();
}
/*
* @see org.springframework.http.converter.GenericHttpMessageConverter#canRead(java.lang.reflect.Type, java.lang.Class, org.springframework.http.MediaType)
*/
public boolean canRead(Type type, Class<?> contextClass, MediaType mediaType) {
return super.canRead(contextClass, mediaType);
}
/*
* @see org.springframework.http.converter.GenericHttpMessageConverter#canWrite(java.lang.reflect.Type, java.lang.Class, org.springframework.http.MediaType)
*/
public boolean canWrite(Type type, Class<?> contextClass, MediaType mediaType) {
return super.canWrite(contextClass, mediaType);
}
/*
* @see org.springframework.http.converter.GenericHttpMessageConverter#read(java.lang.reflect.Type, java.lang.Class, org.springframework.http.HttpInputMessage)
*/
public Object read(Type type, //
Class<?> contextClass, //
HttpInputMessage inputMessage //
) throws IOException, HttpMessageNotReadableException {
InputStream in = inputMessage.getBody();
return JSON.parseObject(in, fastJsonConfig.getCharset(), type, fastJsonConfig.getFeatures());
}
/*
* @see org.springframework.http.converter.GenericHttpMessageConverter#write(java.lang.Object, java.lang.reflect.Type, org.springframework.http.MediaType, org.springframework.http.HttpOutputMessage)
*/
public void write(Object t, //
Type type, //
MediaType contentType, //
HttpOutputMessage outputMessage //
) throws IOException, HttpMessageNotWritableException {
HttpHeaders headers = outputMessage.getHeaders();
if (headers.getContentType() == null) {
if (contentType == null || contentType.isWildcardType() || contentType.isWildcardSubtype()) {
contentType = getDefaultContentType(t);
}
if (contentType != null) {
headers.setContentType(contentType);
}
}
if (headers.getContentLength() == -1) {
Long contentLength = getContentLength(t, headers.getContentType());
if (contentLength != null) {
headers.setContentLength(contentLength);
}
}
writeInternal(t, outputMessage);
outputMessage.getBody().flush();
}
}
FastJsonHttpMessageConverter4
public class FastJsonHttpMessageConverter4 //
extends AbstractGenericHttpMessageConverter<Object> {
/**
* with fastJson config
*/
private FastJsonConfig fastJsonConfig = new FastJsonConfig();
/**
* @return the fastJsonConfig.
* @since 1.2.11
*/
public FastJsonConfig getFastJsonConfig() {
return fastJsonConfig;
}
/**
* @param fastJsonConfig the fastJsonConfig to set.
* @since 1.2.11
*/
public void setFastJsonConfig(FastJsonConfig fastJsonConfig) {
this.fastJsonConfig = fastJsonConfig;
}
/**
* Can serialize/deserialize all types.
*/
public FastJsonHttpMessageConverter4() {
super(MediaType.ALL);
}
@Override
protected boolean supports(Class<?> paramClass) {
return true;
}
@Override
public Object read(Type type, //
Class<?> contextClass, //
HttpInputMessage inputMessage //
) throws IOException, HttpMessageNotReadableException {
InputStream in = inputMessage.getBody();
return JSON.parseObject(in, fastJsonConfig.getCharset(), type, fastJsonConfig.getFeatures());
}
@Override
protected void writeInternal(Object obj, //
Type type, //
HttpOutputMessage outputMessage //
) throws IOException, HttpMessageNotWritableException {
HttpHeaders headers = outputMessage.getHeaders();
ByteArrayOutputStream outnew = new ByteArrayOutputStream();
int len = JSON.writeJSONString(outnew, //
fastJsonConfig.getCharset(), //
obj, //
fastJsonConfig.getSerializeConfig(), //
fastJsonConfig.getSerializeFilters(), //
fastJsonConfig.getDateFormat(), //
JSON.DEFAULT_GENERATE_FEATURE, //
fastJsonConfig.getSerializerFeatures());
headers.setContentLength(len);
OutputStream out = outputMessage.getBody();
outnew.writeTo(out);
outnew.close();
}
@Override
protected Object readInternal(Class<? extends Object> clazz, //
HttpInputMessage inputMessage //
) throws IOException, HttpMessageNotReadableException {
InputStream in = inputMessage.getBody();
return JSON.parseObject(in, fastJsonConfig.getCharset(), clazz, fastJsonConfig.getFeatures());
}
}
對比一下差別有點大
主要是
/**
* with fastJson config
*/
private FastJsonConfig fastJsonConfig = new FastJsonConfig();
/*==============分割線======================*/
@Deprecated
protected Charset charset = IOUtils.UTF8;
@Deprecated
protected SerializerFeature[] features = new SerializerFeature[0];
@Deprecated
protected SerializeFilter[] filters = new SerializeFilter[0];
@Deprecated
protected String dateFormat;
/**
* with fastJson config
*/
private FastJsonConfig fastJsonConfig = new FastJsonConfig();
/**
* @return the fastJsonConfig.
* @since 1.2.11
*/
public FastJsonConfig getFastJsonConfig() {
return fastJsonConfig;
}
/**
* @param fastJsonConfig the fastJsonConfig to set.
* @since 1.2.11
*/
public void setFastJsonConfig(FastJsonConfig fastJsonConfig) {
this.fastJsonConfig = fastJsonConfig;
}
/**
* Can serialize/deserialize all types.
*/
public FastJsonHttpMessageConverter() {
super(MediaType.ALL);
}
@Deprecated
public Charset getCharset() {
return this.fastJsonConfig.getCharset();
}
@Deprecated
public void setCharset(Charset charset) {
this.fastJsonConfig.setCharset(charset);
}
@Deprecated
public String getDateFormat() {
return this.fastJsonConfig.getDateFormat();
}
@Deprecated
public void setDateFormat(String dateFormat) {
this.fastJsonConfig.setDateFormat(dateFormat);
}
@Deprecated
public SerializerFeature[] getFeatures() {
return this.fastJsonConfig.getSerializerFeatures();
}
@Deprecated
public void setFeatures(SerializerFeature... features) {
this.fastJsonConfig.setSerializerFeatures(features);
}
@Deprecated
public SerializeFilter[] getFilters() {
return this.fastJsonConfig.getSerializeFilters();
}
@Deprecated
public void setFilters(SerializeFilter... filters) {
this.fastJsonConfig.setSerializeFilters(filters);
}
在Spring4.2+的版本fastjson(FastJsonHttpMessageConverter4)類用了一個外部變量來取代(FastJsonHttpMessageConverter)類裏面的屬性。主要差別在這,在看一下變量呢。
package com.alibaba.fastjson.support.config;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.util.IOUtils;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Map.Entry;
/**
* Config for FastJson.
*
* @author VictorZeng
* @see SerializeConfig
* @see ParserConfig
* @see SerializerFeature
* @see SerializeFilter
* @see Feature
* @since 1.2.11
*/
public class FastJsonConfig {
/**
* default charset
*/
private Charset charset;
/**
* serializeConfig
*/
private SerializeConfig serializeConfig;
/**
* parserConfig
*/
private ParserConfig parserConfig;
/**
* serializerFeatures
*/
private SerializerFeature[] serializerFeatures;
/**
* serializeFilters
*/
private SerializeFilter[] serializeFilters;
/**
* features
*/
private Feature[] features;
/**
* class level serializeFilter
*/
private Map<Class<?>, SerializeFilter> classSerializeFilters;
/**
* format date type
*/
private String dateFormat;
/**
* init param.
*/
public FastJsonConfig() {
this.charset = IOUtils.UTF8;
this.serializeConfig = SerializeConfig.getGlobalInstance();
this.parserConfig = ParserConfig.getGlobalInstance();
this.serializerFeatures = new SerializerFeature[0];
this.serializeFilters = new SerializeFilter[0];
this.features = new Feature[0];
}
/**
* @return the serializeConfig
*/
public SerializeConfig getSerializeConfig() {
return serializeConfig;
}
/**
* @param serializeConfig the serializeConfig to set
*/
public void setSerializeConfig(SerializeConfig serializeConfig) {
this.serializeConfig = serializeConfig;
}
/**
* @return the parserConfig
*/
public ParserConfig getParserConfig() {
return parserConfig;
}
/**
* @param parserConfig the parserConfig to set
*/
public void setParserConfig(ParserConfig parserConfig) {
this.parserConfig = parserConfig;
}
/**
* @return the serializerFeatures
*/
public SerializerFeature[] getSerializerFeatures() {
return serializerFeatures;
}
/**
* @param serializerFeatures the serializerFeatures to set
*/
public void setSerializerFeatures(SerializerFeature... serializerFeatures) {
this.serializerFeatures = serializerFeatures;
}
/**
* @return the serializeFilters
*/
public SerializeFilter[] getSerializeFilters() {
return serializeFilters;
}
/**
* @param serializeFilters the serializeFilters to set
*/
public void setSerializeFilters(SerializeFilter... serializeFilters) {
this.serializeFilters = serializeFilters;
}
/**
* @return the features
*/
public Feature[] getFeatures() {
return features;
}
/**
* @param features the features to set
*/
public void setFeatures(Feature... features) {
this.features = features;
}
/**
* @return the classSerializeFilters
*/
public Map<Class<?>, SerializeFilter> getClassSerializeFilters() {
return classSerializeFilters;
}
/**
* @param classSerializeFilters the classSerializeFilters to set
*/
public void setClassSerializeFilters(
Map<Class<?>, SerializeFilter> classSerializeFilters) {
if (classSerializeFilters == null)
return;
for (Entry<Class<?>, SerializeFilter> entry : classSerializeFilters.entrySet())
this.serializeConfig.addFilter(entry.getKey(), entry.getValue());
this.classSerializeFilters = classSerializeFilters;
}
/**
* @return the dateFormat
*/
public String getDateFormat() {
return dateFormat;
}
/**
* @param dateFormat the dateFormat to set
*/
public void setDateFormat(String dateFormat) {
this.dateFormat = dateFormat;
}
/**
* @return the charset
*/
public Charset getCharset() {
return charset;
}
/**
* @param charset the charset to set
*/
public void setCharset(Charset charset) {
this.charset = charset;
}
}
看到這應該就沒什麼問題了首先把轉換器換了由原先的(FastJsonHttpMessageConverter)改爲(FastJsonHttpMessageConverter4)
<bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4">
</bean>
然後裏面得設置上變量,得把fastJsonConfig變量注入spring裏去。在根據fastJsonConfig裏面的變量設置幾個屬性值。
<property name="fastJsonConfig">
<bean class="com.alibaba.fastjson.support.config.FastJsonConfig">
<property name="features">
<list>
<value>AllowArbitraryCommas</value>
<value>AllowUnQuotedFieldNames</value>
<value>DisableCircularReferenceDetect</value>
</list>
</property>
<property name="dateFormat" value="yyyy-MM-dd HH:mm:ss"></property>
</bean>
</property>
測試一下,通了。
看樣子是spring4.2出了用的人不多。要不然就不用自己去做輪子了。
現在貼上這一段完整的配置、
<bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4">
<property name="supportedMediaTypes">
<list>
<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="features">
<list>
<value>AllowArbitraryCommas</value>
<value>AllowUnQuotedFieldNames</value>
<value>DisableCircularReferenceDetect</value>
</list>
</property>
<property name="dateFormat" value="yyyy-MM-dd HH:mm:ss"></property>
</bean>
</property>
</bean>
時間倉促寫得比較粗糙,以後有時間詳細解答。