介绍
因fastjson经常出现漏洞需要更新,但是很多工程已接入需要批量修改代码特别麻烦,所以考虑使用语法糖形式,替换成jackson后操作习惯保持一致,通过批量替换import引用即可
注意问题
- 序列化如果对象存在递归引用的属性,会出现无限递归栈溢出的报错(JsonMappingException: Infinite recursion StackOverflowError);
- 非规范书写的属性fasjson可以自动识别成小驼峰(如:testmethod -> testMethod),本插件通过配置强制使用bean原本的属性名;
- 原jackson只支持ISO8601国际标准的时间格式,本插件通过自建dateFormat兼容国内常用的时间格式,保持和fastjson一致。
配置说明
与fastjson基本一致的配置,忽略位置属性和不返回null
// static method faster
private static ObjectMapper mapper;
static {
mapper = new ObjectMapper();
// pass unknown properties
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// allow key no ""
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
// allow key use ''
mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
// allow int startWith 0
mapper.configure(JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS, true);
// allow string exist \r \n \t
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
// after serialization json properties exclude null
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// use lower camel case
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CAMEL_CASE);
// use bean names
mapper.enable(MapperFeature.USE_STD_BEAN_NAMING);
// dateFormat problems
JSONDateFormat smt = new JSONDateFormat();
mapper.setDateFormat(smt);
mapper.setTimeZone(DateUtils.DEFAULT_TIMEZONE);
}
自定义日期解析和格式化
@Override
public StringBuffer format(Date date, StringBuffer stringBuffer, FieldPosition fieldPosition) {
TimeZone tz = DateUtils.DEFAULT_TIMEZONE;
Calendar cal = (Calendar) DateUtils.CALENDAR.clone();
cal.setLenient(true);
cal.setTime(date);
int year = cal.get(1);
if (cal.get(0) == 0) {
if (year == 1) {
stringBuffer.append("+0000");
} else {
int isoYear = year - 1;
stringBuffer.append('-');
pad4(stringBuffer, isoYear);
}
} else {
if (year > 9999) {
stringBuffer.append('+');
}
pad4(stringBuffer, year);
}
stringBuffer.append('-');
pad2(stringBuffer, cal.get(2) + 1);
stringBuffer.append('-');
pad2(stringBuffer, cal.get(5));
stringBuffer.append(' ');
pad2(stringBuffer, cal.get(11));
stringBuffer.append(':');
pad2(stringBuffer, cal.get(12));
stringBuffer.append(':');
pad2(stringBuffer, cal.get(13));
stringBuffer.append('.');
pad3(stringBuffer, cal.get(14));
return stringBuffer;
}
public Date parse(String dateStr) throws ParseException {
dateStr = StringUtils.trim(dateStr);
if (StringUtils.isEmpty(dateStr)) {
return null;
}
if (Pattern.compile("^\\d{13}$").matcher(dateStr).matches()) {
return new Date(Long.valueOf(dateStr));
} else if (Pattern.compile("^\\d{10}$").matcher(dateStr).matches()) {
return new Date(Long.valueOf(dateStr + "000"));
} else {
for (Map.Entry<String, String> entry : dateRegFormat.entrySet()) {
if (Pattern.compile(entry.getKey()).matcher(dateStr).matches()) {
return DateUtils.parse(dateStr, entry.getValue());
}
}
}
return null;
}