在开发中好多人喜欢用阿里的fastjson,官方评价说是最快的json解析框架,但最近几年经常出高危漏洞,项目也跟着不断打复补丁,有时候搞得人心惶惶的,特别被动。于是做个记录:为了今后不重复造轮子,将Jackson封装成统一的json处理工具,可以根据自己公司的情况定制序列化 和 反序列化的一些功能特性。
(1)JsonUtils工具类
/**
* @author: wf
* @create: 2020/10/23 14:53
* @description: JSON序列化工具
*/
public class JsonUtils {
private static final Logger logger = LoggerFactory.getLogger(JsonUtils.class);
private static ObjectMapper objectMapper = new ObjectMapper();
private JsonUtils() {
}
static {
objectMapper.setSerializationInclusion(Include.NON_NULL);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.configure(Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true);
objectMapper.configure(Feature.ALLOW_COMMENTS, true);
objectMapper.configure(Feature.ALLOW_NON_NUMERIC_NUMBERS, true);
objectMapper.configure(Feature.ALLOW_NUMERIC_LEADING_ZEROS, true);
objectMapper.configure(Feature.ALLOW_SINGLE_QUOTES, true);
objectMapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
objectMapper.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
//DateTime解析器
SimpleModule module = new SimpleModule("DateTimeModule", Version.unknownVersion());
module.addDeserializer(DateTime.class, new DateTimeDeserializer());
module.addSerializer(DateTime.class, new DateTimeSerializer());
objectMapper.registerModule(module);
}
/**
* 序列化
* @param obj
* @param <T>
* @return
*/
public static <T> String encode(T obj) {
if (Objects.isNull(obj)) {
return null;
}
try {
return objectMapper.writeValueAsString(obj);
} catch (Exception e) {
logger.error("json encode error, obj={}", obj, e);
return null;
}
}
/**
* 反序列化
* @param json
* @param valueType
* @param <T>
* @return
*/
public static <T> T decode(String json, Class<T> valueType) {
if (!Strings.isNullOrEmpty(json) && !Objects.isNull(valueType)) {
try {
return objectMapper.readValue(json, valueType);
} catch (Exception e) {
logger.error("json decode fail,jsonString={}, type={}", json, valueType.getName(), e);
}
}
return null;
}
/**
* 反序列化成list
* @param json
* @param clazz
* @param <T>
* @return
*/
public static <T> List<T> decode2List(String json, Class<T> clazz) {
if (!Strings.isNullOrEmpty(json) && !Objects.isNull(clazz)) {
try {
return (List) objectMapper.readValue(json, objectMapper.getTypeFactory().constructCollectionType(List.class, clazz));
} catch (Exception var3) {
logger.error("json decode2list fail,json={},classType={}", new Object[]{json, clazz.getName(), var3});
}
}
return null;
}
/**
* map转clazz对象
* @param map
* @param clazz
* @param <T>
* @return
*/
public static <T> T mapToObject(Map map, Class<T> clazz) {
String json = null;
try {
json = objectMapper.writeValueAsString(map);
return objectMapper.readValue(json, clazz);
} catch (Exception e) {
logger.error("json map2object fail,map={},ClassName={}", json, clazz.getName());
return null;
}
}
/**
* 将JSONObject解析成map
* @param prefix key名称前缀
* @param obj JSONObject对象
* @param map
*/
public static void decodeJSONObject(String prefix, Object obj, Map<String, Object> map) {
if (obj instanceof JSONObject) {
JSONObject json = (JSONObject) obj;
Iterator keys = ((JSONObject) obj).keySet().iterator();
while (true) {
while (keys.hasNext()) {
String key = (String) keys.next();
Object o = json.get(key);
String pre = String.join(".", prefix, key);
if (!(o instanceof JSONObject) && !(o instanceof JSONArray)) {
map.put(pre, o);
} else {
decodeJSONObject(pre, o, map);
}
}
return;
}
} else if (obj instanceof JSONArray) {
Iterator iterator = ((JSONArray) obj).iterator();
while (true) {
while (iterator.hasNext()) {
Object ob = iterator.next();
if (!(ob instanceof JSONObject) && !(ob instanceof JSONArray)) {
map.put(prefix, ob);
} else {
decodeJSONObject(prefix, ob, map);
}
}
return;
}
}
}
}
(2)自定义序列化和反序列化转换器
自定义DateTime的序列化和反序列化JSON的处理器:
- 1.序列化解析器:通过继承StdScalarSerializer或JsonSerializer类重写serialize()方法来实现。
- 2.反序列化解析器:通过继承StdScalarDeserializer或JsonDeserializer类重写deserialize()方法来实现。
/**
* @author: wf
* @create: 2020/10/26 11:55
* @description: DateTime JSON反序列化解析器(也可以继承JsonDeserializer)
*/
public class DateTimeDeserializer extends StdScalarDeserializer<DateTime> {
private static final long serialVersionUID = 3616995296305009426L;
public DateTimeDeserializer() {
super(DateTime.class);
}
@Override
public DateTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
String text = jp.getText();
DateTime parse = DateTime.parse(text, ISODateTimeFormat.dateTimeNoMillis());
return parse;
}
}
/**
* @author: wf
* @create: 2020/10/26 14:32
* @description: DateTime JSON序列化处理器(也可以继承JsonDeserializer)
*/
public class DateTimeSerializer extends StdScalarSerializer<DateTime> {
private static final long serialVersionUID = -4174688115741929195L;
public DateTimeSerializer() {
super(DateTime.class);
}
@Override
public void serialize(DateTime dateTime, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException {
String dateTimeAsString = dateTime.toString(ISODateTimeFormat.dateTimeNoMillis());
jsonGenerator.writeString(dateTimeAsString);
}
}
总结:可以通过继承JsonSerializer、JsonDeserializer的方式,并重写seriakize()、deserialize()来自定义任何类型的序列化和反序列化方式。
2020年12月06日 晚 于北京记