杰克逊过滤掉没有注释的字段

JMa*_*Max 4 java json jackson

我试图通过SimpleBeanPropertyFilter使用以下(简化)代码从序列化中筛选出某些字段:

public static void main(String[] args) {
    ObjectMapper mapper = new ObjectMapper();

    SimpleFilterProvider filterProvider = new SimpleFilterProvider().addFilter("test",
            SimpleBeanPropertyFilter.filterOutAllExcept("data1"));
    try {
        String json = mapper.writer(filterProvider).writeValueAsString(new Data());

        System.out.println(json); // output: {"data1":"value1","data2":"value2"}

    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }
}

private static class Data {
    public String data1 = "value1";
    public String data2 = "value2";
}
Run Code Online (Sandbox Code Playgroud)

我们使用的SimpleBeanPropertyFilter.filterOutAllExcept("data1"));我一直期望创建的序列化Json字符串仅包含{"data1":"value1"},但是我得到了{"data1":"value1","data2":"value2"}

如何创建一个尊重指定过滤器的临时编写器(在我的情况下,无法重新配置ObjectMapper)。

注意:由于我的应用程序中的使用场景,我只能接受不使用Jackson批注的答案。

Man*_*dis 9

通常,您Data可以对您的类进行注释以应用过滤器:

@JsonFilter("test")
class Data {
Run Code Online (Sandbox Code Playgroud)

您已指定不能在类上使用批注。您可以使用混入来避免注释Data类。

@JsonFilter("test")
class DataMixIn {}
Run Code Online (Sandbox Code Playgroud)

必须在上指定Mixins ,ObjectMapper并且您指定不想重新配置它。在这种情况下,您始终可以复制ObjectMapper及其配置,然后修改副本的配置。这不会影响ObjectMapper代码中其他地方使用的原始文件。例如

ObjectMapper myMapper = mapper.copy();
myMapper.addMixIn(Data.class, DataMixIn.class);
Run Code Online (Sandbox Code Playgroud)

然后用新的 ObjectMapper

String json = myMapper.writer(filterProvider).writeValueAsString(new Data());
System.out.println(json); // output: {"data1":"value1"}
Run Code Online (Sandbox Code Playgroud)


Ben*_*yan 6

通过名称排除属性的示例:

public Class User {
    private String name = "abc";
    private Integer age = 1;
    //getters
}

@JsonFilter("dynamicFilter")
public class DynamicMixIn {
}

User user = new User();
String[] propertiesToExclude = {"name"};
ObjectMapper mapper = new ObjectMapper()
      .addMixIn(Object.class, DynamicMixIn.class);
FilterProvider filterProvider = new SimpleFilterProvider()
                .addFilter("dynamicFilter", SimpleBeanPropertyFilter.filterOutAllExcept(propertiesToExclude));
        mapper.setFilterProvider(filterProvider);

mapper.writeValueAsString(user); // {"name":"abc"}
Run Code Online (Sandbox Code Playgroud)

您可以代替DynamicMixIn创建MixInByPropName

@JsonIgnoreProperties(value = {"age"})
public class MixInByPropName {
}

ObjectMapper mapper = new ObjectMapper()
      .addMixIn(Object.class, MixInByPropName.class);

mapper.writeValueAsString(user); // {"name":"abc"}
Run Code Online (Sandbox Code Playgroud)

注意:如果仅想排除属性,则User可以将Object.classmethod的参数更改addMixInUser.class

按类型可以排除属性 MixInByType

@JsonIgnoreType
public class MixInByType {
}

ObjectMapper mapper = new ObjectMapper()
      .addMixIn(Integer.class, MixInByType.class);

mapper.writeValueAsString(user); // {"name":"abc"}
Run Code Online (Sandbox Code Playgroud)


dou*_*leW 6

如果由于某种原因,MixIns不适合您。您可以尝试以下方法:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector(){
    @Override
    public boolean hasIgnoreMarker(final AnnotatedMember m) {

    List<String> exclusions = Arrays.asList("field1", "field2");
    return exclusions.contains(m.getName())|| super.hasIgnoreMarker(m);
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 请注意,此解决方案将忽略序列化的所有类中的字段“field1”和“field2”,而不仅仅是一个类。因此,根据您的模型类和过滤的字段名称,您可能会过滤掉比所需更多的字段。 (2认同)