目录
导言
正在做异常入库报警的功能,我们需要把每一个异常入库进行消息通知,分配专门的开发人员来处理异常。这就需要涉及到异常序列化和反序列化的问题,由于序列化的时候开启了WriteClassName属性,则会把类信息也一并进行了序列化,结果反序列化的时候报出如下错误:
com.alibaba.fastjson.JSONException: autoType is not support. org.eclipse.jetty.util.Utf8Appendable$NotUtf8Exception
at com.alibaba.fastjson.parser.ParserConfig.checkAutoType(ParserConfig.java:1386) ~[fastjson-1.2.70.jar:?]
at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:333) ~[fastjson-1.2.70.jar:?]
at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:565) ~[fastjson-1.2.70.jar:?]
at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1401) ~[fastjson-1.2.70.jar:?]
at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1367) ~[fastjson-1.2.70.jar:?]
at com.alibaba.fastjson.JSON.parse(JSON.java:183) ~[fastjson-1.2.70.jar:?]
at com.alibaba.fastjson.JSON.parse(JSON.java:193) ~[fastjson-1.2.70.jar:?]
at com.alibaba.fastjson.JSON.parse(JSON.java:149) ~[fastjson-1.2.70.jar:?]
at com.alibaba.fastjson.JSON.parseObject(JSON.java:254) ~[fastjson-1.2.70.jar:?]
查了网上很多资料,有的说是没有无参构造方法,有的说是添加序列化白名单,但都无法解决我的问题。
序列化方式
public static JSONObject getExtendedThrowable(Throwable var0, boolean var1, boolean var2) {
JSONObject var3 = new JSONObject();
var3.put("1-messages", JSON.parseArray(JsonUtils.getJsonNodeValuesByJsonPath(JSON.toJSONString(var0), "$..message")));
var3.put("2-@types", JSON.parseArray(JsonUtils.getJsonNodeValuesByJsonPath(JSON.toJSONString(var0), "$..@type")));
var3.put("3-rootCause", throwable2rootCause(var0));
if (var1) {
var3.put("4-fullThrowable", var0);
}
if (var2) {
var3.put("5-stacktrace", "\n" + throwable2stacktraceString(var0));
}
return var3;
}
public static String getJsonNodeValuesByJsonPath(String var0, String var1) {
if (!isJsonString(var0)) {
throw new RuntimeException("Not a json string:\n" + var0);
} else {
Object var2 = JsonPath.parse(var0).read(JsonPath.compile(var1, new Predicate[0]));
Constants.LOGGER.info("jsonNodeValues.getClass(): [{}]", var2.getClass());
PrintUtils.print(var2, "jsonNodeValues");
return JSON.toJSONString(var2);
}
}
使用阿里的FastJSON序列化的,然后我尝试用FastJSON反序列化就报出上面提到的错误。
终极解决方案
使用Jackson的addMixIn方法反序列化,代码如下:
public static <T> T jsonString2javaObject(String var0, Object var1, boolean var2, List<Entry<Class<?>, Class<?>>> var3) {
return ThrowableUtils.checkedException2unchecked(() -> {
ObjectMapper var4 = new ObjectMapper();
if (var2) {
var4.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
if (var3 != null) {
var3.forEach((var1x) -> {
var4.addMixIn((Class)var1x.getKey(), (Class)var1x.getValue());
});
}
Object var5;
if (var1 instanceof Class) {
var5 = var4.readValue(var0, (Class)var1);
} else if (var1 instanceof String) {
String var6 = StringUtils.stringReplace((String)var1, " ", "");
JavaType var7 = var4.getTypeFactory().constructFromCanonical(var6);
var5 = var4.readValue(var0, var7);
} else {
if (!(var1 instanceof TypeReference)) {
throw new RuntimeException("clazzOrTypeStringOrTypeReference must be of type Class or String or TypeReference!");
}
var5 = var4.readValue(var0, (TypeReference)var1);
}
return var5;
});
}
大功告成了!