jsonconvert java版本_解决fastjson从1.1.41升级到1.2.28后报错问题详解

在升级Fastjson从1.1.41到1.2.28后,遇到请求报错问题,由于新版本设置MediaType为'*/*'导致。解决方法是为自定义的FastJsonHttpMessageConverter设置支持的MediaType,避免通配符。另外,新版本默认不再对字段排序,若需要排序,可通过SerializerFeature.MapSortField配置。序列化和反序列化可能存在不兼容问题,可能导致乱码。
摘要由CSDN通过智能技术生成

最近因为fastjson安全漏洞,升级jar包时,踩了一些坑。

新版本FastJsonHttpMessageConverter初始化,默认设置MediaType为*/*

背景:

使用Spring RestTemplate,配置如下:

text/html;charset=UTF-8

application/json

text/javascript;charset=utf-8

其中ViewAwareJsonMessageConverter继承自FastJsonHttpMessageConverter。

fastjson从1.1.41升级到1.2.28之后,请求报错:

json java.lang.IllegalArgumentException: 'Content-Type' cannot contain wildcard type '*'

原因是在1.1.41中,FastJsonHttpMessageConverter初始化时,设置了MediaType。

public FastJsonHttpMessageConverter(){

super(new MediaType("application", "json", UTF8), new MediaType("application", "*+json", UTF8));

}

而在1.2.28中,设置的MediaType为‘/',即:

public FastJsonHttpMessageConverter() {

super(MediaType.ALL); // */*

}

后续在org.springframework.http.converter.AbstractHttpMessageConverter.write过程中,又要判断Content-Type不能含有通配符,这应该是一种保护机制,并强制用户自己配置MediaType。代码如下:

@Override

public final void write(final T t, MediaType contentType, HttpOutputMessage outputMessage)

throws IOException, HttpMessageNotWritableException {

final HttpHeaders headers = outputMessage.getHeaders();

if (headers.getContentType() == null) {

MediaType contentTypeToUse = contentType;

if (contentType == null || contentType.isWildcardType() || contentType.isWildcardSubtype()) {

contentTypeToUse = getDefaultContentType(t);

}

if (contentTypeToUse != null) {

//设置Content-Type,不允许含有通配符

headers.setContentType(contentTypeToUse);

}

}

......

if (outputMessage instanceof StreamingHttpOutputMessage) {

......

}else {

//自定义MessageConverter的write操作

writeInternal(t, outputMessage);

outputMessage.getBody().flush();

}

}

public void setContentType(MediaType mediaType) {

Assert.isTrue(!mediaType.isWildcardType(), "'Content-Type' cannot contain wildcard type '*'");

Assert.isTrue(!mediaType.isWildcardSubtype(), "'Content-Type' cannot contain wildcard subtype '*'");

set(CONTENT_TYPE, mediaType.toString());

}

所以,需要为ViewAwareJsonMessageConverter设置supportedMediaTypes:

application/json;charset=UTF-8

application/*+json;charset=UTF-8

新版本序列化默认不再对字段进行排序

这个是一个签名算法的场景:客户端对参数进行序列化,然后md5加密成一个签名;服务端按照相同的算法解析一遍参数,对比签名值。这里加密依赖json序列化之后的字符串,也就依赖序列化时字段的排序。

这是fastjson做了一个性能优化,将排序需求抽象出一个SerializerFeature,供用户自己配置。如果需要排序场景,在序列化时添加参数SerializerFeature.MapSortField即可,即:

JSON.toJSONString(obj, SerializerFeature.MapSortField);

官方文档

1.2.3之后的版本,Map的序列化没有做排序再输出,原因是通过TreeMap排序很影响性能。

1.2.27版本中增加SerializerFeature.MapSortField实现同样的功能。

使用方法如下:

a) 传入SerializerFeature.MapSortField参数。 JSON.toJSONString(map, SerializerFeature.MapSortField);

b) 通过代码修改全局缺省配置。 JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.MapSortField.getMask();

c) 通过JVM启动参数配置修改全局配置 -Dfastjson.serializerFeatures.MapSortField=true

d) 通过类路径下的fastjson.properties来配置 fastjson.serializerFeatures.MapSortField=true

新老版本序列化和反序列化不兼容,会出乱码。

更多关于fastjson的相关文章请点击下面的相关链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值