专栏首页用户7614879的专栏Java 使用Jackson处理json 字符串值反序列化类型为集合时的报错处理 单个值自动转集合

Java 使用Jackson处理json 字符串值反序列化类型为集合时的报错处理 单个值自动转集合

在处理Json字符串时 有时会遇到一种情况:

JSON字符串中的某一项的值是字符串类型,但想要反序列化为一个集合类型

举例: {"i":1,"list":"astr","str":"em"} 这样一个字符串 想要反序列化为如下的一个类 可以预见的在转换到list时会抛出如下异常

public class Po {

    private Integer i;

    private List<String> list;

    private String str;

}

com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'XXX': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')

jackson在发现目标类型是list 但当前字符没有[ 这样的集合开始标志 就会抛出转换失败异常。

解决办法就是在使用之前 为objectMapper增加一项自定义的错误处理器,并在处理这个错误时将list 实例化,将对应的值加入该list

代码:

/**
 * 当json字符串中值为string类型 并无[]符号,且要反序列化为list时 使用该配置解决报错
 *
 * @author heasy
 **/
public class MyDeserializationProblemHandler extends DeserializationProblemHandler {

    @Override
    public Object handleUnexpectedToken(DeserializationContext ctxt, JavaType targetType, JsonToken token, JsonParser parser, String failureMsg) throws IOException {
        //处理json字符串 转 目标为数组 元素为字符串的情况
        if (token == JsonToken.VALUE_STRING && targetType.isCollectionLikeType()) {
            return deserializeString(targetType, parser);
        }
        //处理单个json对象 转 目标为数组 且元素为对象的情况
        if (token == JsonToken.START_OBJECT && targetType.isCollectionLikeType()) {
            return deserializeObject(targetType, parser);
        }
        return super.handleUnexpectedToken(ctxt, targetType, token, parser, failureMsg);
    }


    private Object deserializeObject(JavaType targetType, JsonParser parser) throws IOException {
        List<Object> list = new ArrayList<>(1);
        final Class<?> rawClass = targetType.getContentType().getRawClass();
        final Object o = ReflectUtil.newInstanceIfPossible(rawClass);
        while (parser.getCurrentToken() != JsonToken.END_OBJECT) {
            if (parser.getText().equals(JsonToken.START_OBJECT.asString())) {
                parser.nextToken();
                continue;
            }
            String field = parser.getText();
            parser.nextToken();
            String value = parser.getText();
            if (ReflectUtil.hasField(rawClass, field)) {
                ReflectUtil.setFieldValue(o, field, value);
            }
            parser.nextToken();
        }
        list.add(o);
        return list;
    }

    private Object deserializeString(JavaType listType, JsonParser parser) throws IOException {
        String[] values = parser.getText().split(",");

        JavaType itemType = listType.getContentType();

        List<Object> result = new ArrayList<>(values.length);
        for (String value : values) {
            final String json = "\"" + value.trim() + "\"";
            final Object o = JsonUtil.fromJson(json, itemType);
            result.add(o);
        }

        return result;
    }


}

除了简单字符串转list,还可以处理object的json 转object对应list 这里用到了反射,工具类使用的是hutool的。如果不需要去掉对应判断即可

然后将这个错误处理器配置到你使用的objectmapper中即可

objectMapper.addHandler(new MyDeserializationProblemHandler());

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 都是微服务的天下了,还有不知道 JSON 的程序员吗?

      JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协...

    Demo_Null
  • 除了FastJson,你也应该了解一下Jackson(一)

    在上月末的时候收到一条关于fastjson安全漏洞的消息,突然想到先前好像已经有好多次这样的事件了(在fastjson上面)。关于安全方面,虽然中枪的机率微小,...

    东溪陈姓少年
  • 如何通过Jackson注解@JsonTypeInfo解决多态反序列化问题?

    Jackson是Spring Boot(SpringBoot)默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库。有的小伙伴以为Jackson只...

    码农架构
  • 放弃FastJson!一篇就够,Jackson的功能原来如此之牛(万字干货)

    在上篇《经过多方调研,最终还是决定禁用FastJson!》中,讲了FastJson的基本使用以及存在的不确定性问题,所以最终决定在项目中放弃使用,进而选择市面上...

    程序新视界
  • 6. 二十不惑,ObjectMapper使用也不再迷惑

    各位好,我是YourBatman。从本文起,终于要和Jackson的“高级”部分打交道了,也就是数据绑定jackson-databind模块。通过接触它的高级A...

    YourBatman
  • 6. 二十不惑,ObjectMapper使用也不再迷惑

    各位好,我是YourBatman。从本文起,终于要和Jackson的“高级”部分打交道了,也就是数据绑定jackson-databind模块。通过接触它的高级A...

    YourBatman
  • Java几种常用JSON库性能比较

    本文通过JMH(即JavaMicrobenchmarkHarness,基于方法层面的基准测试,...

    Java架构师必看
  • 除了闹过腥风血雨的fastjosn,你还知道哪些Java解析JSON的利器?

    昨天下午 5 点 10 分左右,我解决掉了最后一个 bug,轻舒一口气,准备关机下班。可这个时候,老板朝我走来,脸上挂着神秘的微笑,我就知道他不怀好意。果不其然...

    沉默王二
  • Android中JSON库性能比较

    JSON不管是在Web开发还是服务器开发中是相当常见的数据传输格式,一般情况我们对于JSON解析构造的性能并不需要过于关心,除非是在性能要求比较高的系统。 目前...

    蜻蜓队长
  • 用了几年的 Fastjson,我最终替换成了Jackson!

    作者:larva-zhh 来源:www.cnblogs.com/larva-zhh/p/11544317.html

    Java技术栈
  • 序列化与反序列化核心用法-JSON框架Jackson精解第一篇

    Jackson是Spring Boot默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库。有的小伙伴以为Jackson只能在Spring框架...

    字母哥博客
  • Jaskson精讲第7篇-JsonTypeInfo注解在类继承关系下的使用

    Jackson是Spring Boot(SpringBoot)默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库。有的小伙伴以为Jackson只...

    字母哥博客
  • Java 几种常用 JSON 库性能比较

    本篇通过JMH来测试一下Java中几种常见的JSON解析库的性能。每次都在网上看到别人说什么某某库性能是如何如何的好,碾压其他的库。但是百闻不如一见,只有自己亲...

    冯杰宁
  • Jaskson精讲第6篇-自定义JsonSerialize与Deserialize实现数据类型转换

    Jackson是Spring Boot(SpringBoot)默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库。有的小伙伴以为Jackson只...

    字母哥博客
  • Gson:我爸是 Google

    我叫 Gson,是一款开源的 Java 库,主要用途为序列化 Java 对象为 JSON 字符串,或反序列化 JSON 字符串成 Java 对象。从我的名字上,...

    沉默王二
  • Java 几种常用 JSON 库性能比较

    本篇通过JMH来测试一下Java中几种常见的JSON解析库的性能。每次都在网上看到别人说什么某某库性能是如何如何的好,碾压其他的库。但是百闻不如一见,只有自己亲...

    Java团长
  • Java几种常用JSON库性能比较

    本篇通过JMH来测试一下Java中几种常见的JSON解析库的性能。 每次都在网上看到别人说什么某某库性能是如何如何的好,碾压其他的库。但是百闻不如一见,只有自己...

    用户5224393
  • JAVA中几种常用JSON库性能比较

    本篇通过JMH来测试一下Java中几种常见的JSON解析库的性能。每次都在网上看到别人说什么某某库性能是如何如何的好,碾压其他的库。但是百闻不如一见,只有自己亲...

    Java技术江湖
  • JAVA中几种常用JSON库性能比较

    本篇通过JMH来测试一下Java中几种常见的JSON解析库的性能。每次都在网上看到别人说什么某某库性能是如何如何的好,碾压其他的库。但是百闻不如一见,只有自己亲...

    用户5927304

扫码关注云+社区

领取腾讯云代金券