如何跟踪杰克逊可能反序列化的课程?

时间:2014-06-11 21:15:22

标签: java jackson deserialization

为了对Jackson可能反序列化的类进行某些检查,我希望能够轻松找到任何这样的类。但是,在标准用法中,杰克逊可以反序列化为一个没有杰克逊注释的完全正常的类。

一位同事提到,之前已经看到一些方法来设置Jackson只能成功地反序列化明确注释为能够这样做的类。这将提供一个简单的解决方案,因为我可以找到具有这种注释的类。但是,查看所有Jackson文档,我找不到此功能。有谁知道它被发现的位置/这是否被弃用?

2 个答案:

答案 0 :(得分:1)

在用于反序列化的ObjectMapper上,您可以配置字段,方法和创建者的自动检测。如果您想在整个应用程序中强制执行此操作,我建议您在任何地方扩展ObjectMapper并使用自定义实现。然后,您想要施加的任何其他配置也可以存在。像这样:

public class CustomObjectMapper extends ObjectMapper {
    public CustomObjectMapper() {
        setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
    }
}

您当然可以在声明setVisibility的任何地方致电ObjectMapper

ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);

答案 1 :(得分:1)

考虑一个选项,用自定义注释标记“json”类,然后设置一个特殊的annotation introspector,它将无法序列化应用程序中的所有其他类。

请注意,您需要能够区分标准类,如基元,字符串,集合等,它们没有自定义注释,以及应用程序中不应处理的类。

以下是一个例子:

package stackoverflow;

public class JacksonTracking {
    @Retention(RetentionPolicy.RUNTIME)
    public static @interface Json {
    }

    @Json
    public static class A {
        public final String field1;

        public A(String field1) {
            this.field1 = field1;
        }
    }

    public static class B {
        public final String field2;

        public B(String field2) {
            this.field2 = field2;
        }
    }

    public static class UnsupportedSerializer extends JsonSerializer.None {
        private final Class<?> type;

        public UnsupportedSerializer(Class<?> type) {
            this.type = type;
        }

        @Override
        public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
            throw new UnsupportedOperationException("Unsupported type: " + type);
        }
    }

    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
            @Override
            public Object findSerializer(Annotated a) {
                if (a instanceof AnnotatedClass
                        && a.getRawType().getPackage().getName().startsWith("stackoverflow")
                        && !a.hasAnnotation(Json.class)) {
                    return new UnsupportedSerializer(a.getRawType());
                }
                return super.findSerializer(a);
            }
        });

        System.out.println(mapper.writeValueAsString(new A("value1")));
        System.out.println(mapper.writeValueAsString(new B("value2")));
    }
}

输出:

{"field1":"value1"}
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Unsupported type: class stackoverflow.JacksonTracking$B
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:125)
    at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:2866)
    at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:2323)
    at stackoverflow.JacksonTracking.main(JacksonTracking.java:71)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.lang.UnsupportedOperationException: Unsupported type: class stackoverflow.JacksonTracking$B
    at stackoverflow.JacksonTracking$UnsupportedSerializer.serialize(JacksonTracking.java:52)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:114)
    ... 8 more