当前位置: 首页 > 知识库问答 >
问题:

用Jackson实现集合的类反序列化失败

何向荣
2023-03-14

我有以下JSON:

{
  "item": [
    { "foo": 1 },
    { "foo": 2 }
  ]
} 

这基本上是一个包含项集合的对象。

所以我做了一个类来反序列化:

public class ItemList {
  @JsonProperty("item")
  List<Item> items;

  // Getters, setters & co.
  // ...
}
public class ItemList implements Collection<Item>, Iterable<Item> {
  @JsonProperty("item")
  List<Item> items;

  // Getters, setters & co.

  // Generated all method delegates to items. For instance:
  public Item get(int position) {
    return items.get(position);
  }
}

我尝试添加@jsondeserialize(as=itemlist.class),但没有成功。

怎么走?

共有1个答案

夹谷苗宣
2023-03-14

显然,它不起作用,因为Jackson使用Java集合类型的标准集合反序列化程序,它对itemlist属性一无所知。

有可能使它工作,但不是以一种非常优雅的方式。您需要配置ObjectMapper以替换为相应类型手动创建的bean反序列化程序上的默认集合反序列化程序。我在BeandeSerializerModifier中为所有用自定义注释注释的类编写了一个示例。

请注意,我必须重写ObjectMapper以访问ObjectMapper的受保护方法CreateDeserializationContext以创建正确的反序列化上下文,因为bean修饰符不能访问它。

public class JacksonCustomList {
    public static final String JSON = "{\n" +
            "  \"item\": [\n" +
            "    { \"foo\": 1 },\n" +
            "    { \"foo\": 2 }\n" +
            "  ]\n" +
            "} ";

    @Retention(RetentionPolicy.RUNTIME)
    public static @interface PreferBeanDeserializer {

    }

    public static class Item {
        public int foo;

        @Override
        public String toString() {
            return String.valueOf(foo);
        }
    }

    @PreferBeanDeserializer
    public static class ItemList extends ArrayList<Item> {
        @JsonProperty("item")
        public List<Item> items;

        @Override
        public String toString() {
            return items.toString();
        }
    }

    public static class Modifier extends BeanDeserializerModifier {
        private final MyObjectMapper mapper;

        public Modifier(final MyObjectMapper mapper) {
            this.mapper = mapper;
        }

        @Override
        public JsonDeserializer<?> modifyCollectionDeserializer(
                final DeserializationConfig config,
                final CollectionType type,
                final BeanDescription beanDesc,
                final JsonDeserializer<?> deserializer) {
            if (type.getRawClass().getAnnotation(PreferBeanDeserializer.class) != null) {
                DeserializationContext context = mapper.createContext(config);
                try {
                    return context.getFactory().createBeanDeserializer(context, type, beanDesc);
                } catch (JsonMappingException e) {
                   throw new IllegalStateException(e);
                }

            }
            return super.modifyCollectionDeserializer(config, type, beanDesc, deserializer);
        }
    }

    public static class MyObjectMapper extends ObjectMapper {
        public DeserializationContext createContext(final DeserializationConfig cfg) {
            return super.createDeserializationContext(getDeserializationContext().getParser(), cfg);
        }
    }

    public static void main(String[] args) throws IOException {
        final MyObjectMapper mapper = new MyObjectMapper();
        SimpleModule module = new SimpleModule();
        module.setDeserializerModifier(new Modifier(mapper));

        mapper.registerModule(module);
        System.out.println(mapper.readValue(JSON, ItemList.class));
    }

}
 类似资料:
  • 好的,我知道有一堆类似的问题,但似乎都行不通。 我为我的实体设置了以下结构。 在我的控制器中,我尝试将一个请求映射到下面的方法。 请尝试%1 我认为它是这样做的--添加了一个元数据属性,该属性将存储子类类。 结果是什么。 结果是什么。 即使将和添加到这两个子类中,也会得到相同的结果。 其他尝试 我试了很多。什么都不起作用。不会包含这里的所有内容。 我觉得应该有一个简单的方法来做到这一点,但我只是不

  • 将有更多的类(不同的产品)扩展。 当我使用序列化它时, 这是输出: 将引发此异常: java.lang.IllegalArgumentException:意外的标记(VALUE_STRING),应为field_name:缺少包含类型id(类com.shubham.model.product的)的属性“type”,位于[源:n/a;行:-1,列:-1] 我在这里做错了什么?我观察了一下,发现了一个问

  • 我试图使用混合序列化集合,但Jackson不会保存类型信息。这是一个基本测试,说明会发生什么: 如何在第一个输出上实现输出?

  • 我正在尝试使用JSON ObjectMapper反序列化对象。我在尝试反序列化时看到以下错误

  • 在使用SpringBoot和Angular开发的REST应用程序中,我需要向SpringBoot后端发送REST请求,以便将对象保存到数据库中。 在前端,用户填写表单并提交。下面是创建对象的接口,对象将作为REST调用发送到后端。 我知道这个错误是因为我使用接口作为图像列表的类型。 我认为解决这个问题的办法是让Jackson知道应该使用注释将列表反序列化为什么类型。所以,我用了下面的 Common

  • 问题内容: 我有一个json字符串,应该将其反序列化为以下类 我该怎么做?这是通常的方式 但是我怎么提到T代表什么呢? 问题答案: 你需要为使用的每种通用类型创建一个对象,并将其用于反序列化。例如