Jackson在序列化Collection实例变量时随机添加Type Info

时间:2016-12-19 05:47:37

标签: java jackson

我在Tomcat上部署了一个Web应用程序,并使用Jackson将对象序列化为JSON。有时重启时我发现杰克逊突然开始使用集合(特别是List)输入类型信息。它不总是并且通常在tomcat重启时得到修复。 例如:

    public class Demo implements Serializable {

        private static final long serialVersionUID = 1L;
        private String name;
        private List<Long> f1;

        public List<Long> getF1() {
            return f1;
        }
        public void setF1(List<?> f1) {
            this.f1 = f1;
        }

        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder("Demo [f1=");
            for(Long f : f1) {
                sb.append(f).append(",");
            }
            sb.append("]");
            sb.append(name);
            return sb.toString();
        }
    }

Demo.class和其他类似的类别包含在共同的DataHolder.class

public class DataHolder {

    @JsonProperty("v")
    private Object value;

    public DataHolder() {
    }

    public DataHolder(Object value) {
        super();
        this.value = value;
    }

    public Object getValue() {
        return value;
    }

    public void setValue(Object value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "DataHolder [value=" + value + "]";
    }
}

我编写了一个自定义对象映射器:

public class CustomObjectMapper extends ObjectMapper {

    public CustomObjectMapper() {
        getSerializationConfig().
        setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);

        setVisibilityChecker(getSerializationConfig().
        getDefaultVisibilityChecker().
        withFieldVisibility(Visibility.ANY).
        withGetterVisibility(Visibility.NONE).
        withIsGetterVisibility(Visibility.NONE).
        withSetterVisibility(Visibility.NONE));

  configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false)
  .configure(SerializationConfig.Feature.WRITE_NULL_MAP_VALUES, false)
  .configure(SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION, false);
            enableDefaultTyping(DefaultTyping.JAVA_LANG_OBJECT);
        }

调用上述类并将其序列化的主要逻辑是:

CustomObjectMapper ct = new CustomObjectMapper();
DataHolder dh = new DataHolder(d);
String jsonToWrite = ct.writeValueAsString(dh);

现在,两个不同的JSON随机生成:

{"v":["com.main.cache.Demo",{"name":"piyush","f1":[1130890999009]}]}

OR

{"v":["com.main.cache.Demo",{"name":"piyush","f1":[["java.lang.Long",1130890999009]]}]}

I.e java.lang.Long随机进入JSON并在重新启动时得到修复。

如何解决这个问题。

编辑:我也在查找是否可以找到自定义序列化程序/反序列化程序,在JSONTypeInfo

中的所有集合引用的所有情况下都会删除Demo.class

1 个答案:

答案 0 :(得分:0)

删除此行应该足够了:

enableDefaultTyping(DefaultTyping.JAVA_LANG_OBJECT)

这是Jackson的选项,可在需要时添加类型信息。您可以在Jackson's Java Docs中详细了解相关信息。通常,您可以将以下选项传递给此方法:

  
      
  • JAVA_LANG_OBJECT 此值表示只有具有Object作为声明类型的属性(包括没有显式类型的泛型类型)才会使用默认类型。
  •   
  • NON_CONCRETE_AND_ARRAYS 值表示默认输入将用于OBJECT_AND_NON_CONCRETE所涵盖的所有类型以及所有类型的类型。
  •   
  • NON_FINAL 值表示默认输入将用于所有非最终类型,但少数&#34;自然&#34; types(String,Boolean,Integer,Double),可以从JSON正确推断出来;以及所有非最终类型的数组。
  •   
  • OBJECT_AND_NON_CONCRETE 值表示默认输入将用于声明类型为Object或抽象类型(抽象类或接口)的属性。
  •