jackson filter properties without annotations

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-24 06:37:41

问题


public Class User {
    private String name;
    private Integer age;
    ...
}

ObjectMapper om = new ObjectMapper();
om.writeValueAsString(user);

How can I filter properties without using any annotations like @JsonIgnore?


回答1:


You have two possible ways using Jackson

Mixin Annotations :- http://www.cowtowncoder.com/blog/archives/2009/08/entry_305.html

JSON Filter :- http://wiki.fasterxml.com/JacksonFeatureJsonFilter




回答2:


The example of excluding properties by name:

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

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

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

mapper.writeValueAsString(user); // {"name":"abc"}

You can instead of DynamicMixIn create MixInByPropName

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

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

mapper.writeValueAsString(user); // {"name":"abc"}

Note: If you want exclude property only for User you can change parameter Object.class of method addMixIn to User.class

Excluding properties by type you can create MixInByType

@JsonIgnoreType
public class MixInByType {
}

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

mapper.writeValueAsString(user); // {"name":"abc"}



回答3:


A little bit slow but I use two phase copying. Firstly using spring BeanUtils secondly using Jackson.

public static void copyWithIgnore(final Object source, final Object target, final String... ignoreProperties) {

    try {
        final ObjectMapper mapper = new ObjectMapper()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        final Object ignoredSource;

        if (ObjectUtils.isEmpty(ignoreProperties)) {
            ignoredSource = source;
        } else {
            ignoredSource = source.getClass().getDeclaredConstructor().newInstance();
            BeanUtils.copyProperties(source, ignoredSource, ignoreProperties);
        }

        mapper.readerForUpdating(target).readValue(mapper.writeValueAsString(ignoredSource));
    } catch (Exception e) {
        throw new RuntimeException("Cannot deserialize and instantiate source class");
    }
}



回答4:


I wrote a library called Squiggly Filter, which selects fields based on a subset of the Facebook Graph API syntax. For example, to select the zipCode of the address field of the user object, you would use the query string ?fields=address{zipCode}. One of the advantages of Squiggly Filter is that as long as you have access to the ObjectMapper that renders the json, you do not to have to modify the code of any of your controller methods.

Assuming, you are using the servlet API (which is not required, but probably the most common use case), you can do the following:

1) Register a filter

<filter> 
    <filter-name>squigglyFilter</filter-name>
    <filter-class>com.github.bohnman.squiggly.web.SquigglyRequestFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>squigglyFilter</filter-name>
    <url-pattern>/**</url-pattern> 
</filter-mapping>

2) Initialize the ObjectMapper

Squiggly.init(objectMapper, new RequestSquigglyContextProvider());

3) You can now filter your json

curl https://yourhost/path/to/endpoint?fields=field1,field2{nested1,nested2}

More information on Squiggly Filter is available on github.



来源:https://stackoverflow.com/questions/10916443/jackson-filter-properties-without-annotations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!