jackson对Exception类型对象的序列化与反序列化「建议收藏」

jackson对Exception类型对象的序列化与反序列化「建议收藏」jackson对Exception类型对象的序列化与反序列化

大家好,又见面了,我是你们的朋友全栈君。

发现问题

今天在调试系统错误通知的时候遇到了一个问题。我们在系统异常时候要通过队列系统发送各种通知到团队内部成员。

因此我写了一个通用接口。接口中有传递Exception对象到队列中,再由队列消费者解析后生成消息发送出去。

这个Exception对象是先通过jackson序列化后再在队列消费端反序列化完成传递的。

但是在测试过程中发现,经过队列传递后的Exception对象丢失了很多信息,甚至连基本的class类型都不能还原。

比如一个IllegalArgumentException经过jackson的序列化与反序列化之后得到的是一个几乎空的Exception对象。从message到cause到stackTrace数据全部丢失。

例如:

IllegalStateException e = new IllegalStateException("abc");
String str = JSONSnakeUtils.writeValue(e);
Exception ex = JSONSnakeUtils.readValue(str, Exception.class);

注:以上代码中JSONSnakeUtils是我们自己封装的jackson方法,基本原样调用了jackson的objectMapper方法。

上面方法中ex对象已经和原来的e对象天差地别了。

尝试解决

然后我想到了使用java自带的序列化工具来实现。
经过以下测试:

IllegalStateException e = new IllegalStateException("abc");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(byteArrayOutputStream);
oo.writeObject(e);
oo.close();
byte[] bytes = byteArrayOutputStream.toByteArray();

ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(byteArrayInputStream);
Exception ex = (Exception) ois.readObject();

得到的ex对象原样还原了原始的e对象,说明这个思路是可行的。

最终方案

结合jackson自定义序列化与反序列化的方式,有了最终的解决方案:

首先定义自定义的序列化与反序列化方法,将经过ObjectOutputStream序列化后的byte数组转化为字符串通过json传递。再在消费端经过byte数组转换回Exception对象。代码如下:

定义序列化类
public class ExceptionJsonSerializer extends JsonSerializer<Exception> {

    @Override
    public void serialize(Exception exception, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream oo = new ObjectOutputStream(byteArrayOutputStream);
        oo.writeObject(exception);
        oo.flush();
        oo.close();
        byte[] bytes = byteArrayOutputStream.toByteArray();
        gen.writeRawValue("\"" + ByteArrayUtil.toHexString(bytes) + "\"");
    }

}
定义反序列化类
public class ExceptionJsonDeserializer extends JsonDeserializer<Exception> {

    @Override
    public Exception deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        String valueAsString = jsonParser.getValueAsString();
        byte[] bytes = ByteArrayUtil.hexStringToByteArray(valueAsString);
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        ObjectInputStream ois = new ObjectInputStream(byteArrayInputStream);
        try {
            Exception ex = (Exception) ois.readObject();
            return ex;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        } finally {
            ois.close();
        }
    }
}
最后在对象字段上添加注解
public static class AAA {
    String xxx;
    String yyy;
    @JsonSerialize(using = ExceptionJsonSerializer.class)
    @JsonDeserialize(using = ExceptionJsonDeserializer.class)
    Exception exception;
}

OK。至此问题解决。

转载于:https://www.cnblogs.com/succour/p/10245788.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/107077.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • net:err_unknown_url_scheme

    net:err_unknown_url_scheme

  • 获取窗口句柄

    获取窗口句柄importwin32guihwnd_title=dict()defget_all_hwnd(hwnd,tem):ifwin32gui.IsWindow(hwnd)andwin32gu

  • pycharm2021.8.3永久激活码[最新免费获取]

    (pycharm2021.8.3永久激活码)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

  • 支持向量回归-SVR

    支持向量回归-SVR对于一般的回归问题,给定训练样本D={(x1,y1),(x2,y2),…,(xn,yn)},yi€R,我们希望学习到一个f(x)使得,其与y尽可能的接近,w,b是待确定的参数。在这个模型中,只有当发f(x)与y完全相同时,损失才为零,而支持向量回归假设我们能容忍的f(x)与之间最多有ε的偏差,当且仅当f(x)与y的差别绝对值大于ε时,才计算损失,此时相当于以f(x)为中心,构建一个宽度为2ε的

  • IE中出现 “Stack overflow at line“ 错误的解决方法

    IE中出现 “Stack overflow at line“ 错误的解决方法IE中出现”Stackoverflowatline”错误的解决方法

  • 博弈论(Game Theory)入门学习笔记(持续更新)

    博弈论(Game Theory)入门学习笔记(持续更新)博弈论(GameTheory)入门学习笔记课程介绍1-1Taste-Backoff1-2Self-InterestedAgentsandUtilityTheory1-3Define1-4Examples1-5NashEquilibriumIntro1-6StrategicReasoning课程介绍博弈论,又称对策论,是使用严谨的数学模型研究冲突对抗条件下最优决策问题的理论,是研究竞争的逻辑和规律的数学分支。1-1Taste-Backoff以一个经典案例引出博弈论

    2022年10月15日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号