gson迁移到jackson
Posted 不去天涯
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gson迁移到jackson相关的知识,希望对你有一定的参考价值。
概述
gson和jackson在使用上是很相似的,不论是直接和POJO互相转换,还是逐个属性解析Json文本,基本上没有什么差别。
但是由于对属性名解析策略上有所不同,在遇到isXxx或者hasXxx形式的getter方法时就有差别了。
对于isXxx形式,gson生成的json会是isXxx或者is_xxx形式;而jackson生成的会是xxx形式,也就是自动删除了is。
对于hasXxx形式,gson生成的是xxx形式;而jackson会忽略掉这个属性,因为jackson只识别getXxx和isXxx形式的getter方法。
如果,希望jackson能够识别hasXxx形式,那么需要给它加上@JsonProperty(“hasXxx”)注解。
当然了,一般情况下,我们用eclipse自带的getter、setter创建工具,是不会出现hasXXX这样的getter方法的。
jackson想指定属性名字转换成json的样式可以这样做:
1.使用@JsonProperty注解,指定字段名;
2.给ObjectMapper指定PropertyNamingStrategy,这种方式可以生成驼峰式、小写+横线连字符式、小写+下划线连字符式等多种形式;
3.使用自定义的PropertyNamingStrategy实现字段名转换。
@JsonProperty注解方式
需要在特殊的字段上都加上注解:
@JsonProperty("hasChecked")
private boolean hasChecked;
@JsonProperty("isMyFault")
private boolean isMyFault;
指定PropertyNamingStrategy
jackson默认输出的是驼峰形式字段名,可以通过指定PropertyNamingStrategy,输出小写+横线连字符式、小写+下划线连字符式的字段名:
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
使用自定义的PropertyNamingStrategy
上边说到了从gson转到jackson时,isXxx类型的字段名输出不一致。
如果恰好你们的项目里面也遇到这样的问题,可以用@JsonProperty的方式明确指定字段名,如果字段多的话就是稍微麻烦点,问题也不大。
但是如果像我们的项目一样,就惨了,我们系统提供pc的spring mvc服务,你知道spring mvc默认使用的是jackson返回json数据的。
然而,我们的项目同时提供内部使用的rest接口,接口返回的json是用gson返回的(自己封装了一个netty框架)。数据Model共享,导致同一个字段在pc端返回的需要是驼峰形式,在内部rest接口返回小写+下划线方式。
可想而知,用@JsonProperty是不行的了,不能做到两方兼顾。
这时候就可以使用第三种方式,自定义PropertyNamingStrategy来实现了:
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy()
@Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
String input = defaultName;
if(method.getName().startsWith("is"))
input = method.getName();
if (input == null) return input;
int length = input.length();
StringBuilder result = new StringBuilder(length * 2);
int resultLength = 0;
boolean wasPrevTranslated = false;
for (int i = 0; i < length; i++)
char c = input.charAt(i);
if (i > 0 || c != '_') // skip first starting underscore
if (Character.isUpperCase(c))
if (!wasPrevTranslated && resultLength > 0 && result.charAt(resultLength - 1) != '_')
result.append('_');
resultLength++;
c = Character.toLowerCase(c);
wasPrevTranslated = true;
else
wasPrevTranslated = false;
result.append(c);
resultLength++;
return resultLength > 0 ? result.toString() : input;
);
20170825补充
现实场景一般来说会复杂一些,我们遇到的情况如下:
public class EclipseAutoMethodName
private boolean isOutlets;
private boolean overSea;
public boolean isOutlets()
return isOutlets;
public void setOutlets(boolean isOutlets)
this.isOutlets = isOutlets;
public boolean isOverSea()
return overSea;
public void setOverSea(boolean overSea)
this.overSea = overSea;
其中的getter和setter方法都是eclipse自动生成的,gson的处理方法是field优先。它会解析成:
"isOutlets":true,"overSea":false
jackson不指定PropertyNamingStrategy的情况下会解析成:
"outlets":true,"overSea":false
也就是,会自动擦除is。
如果使用本文中给的PropertyNamingStrategy实现,那么会被jackson解析成:
"isOutlets":true,"isOverSea":false
因为jackson是Getter方法优先,所以,如果你的历史代码中有这种字段名以is开头,也有非is开头的boolean属性的时候,唯一的处理方法就是把以is开头的boolean属性的getter方法前加get,如下:
public class EclipseAutoMethodName
private boolean isOutlets;
private boolean overSea;
public boolean getIsOutlets()
return isOutlets;
public void setOutlets(boolean isOutlets)
this.isOutlets = isOutlets;
public boolean isOverSea()
return overSea;
public void setOverSea(boolean overSea)
this.overSea = overSea;
以上是关于gson迁移到jackson的主要内容,如果未能解决你的问题,请参考以下文章
Gson、FastJson、Jackson、json-lib对比总结