Skip to content

Support Jackson @JsonFilter [SPR-12586] #17187

Closed
@spring-projects-issues

Description

@spring-projects-issues

Christopher Shannon opened SPR-12586 and commented

I occasionally need to be able to dynamically filter what fields are returned from a rest controller. The Jackson @JsonView annotation is a good improvement but it still requires configuration ahead of time and isn't dynamic.

One use case I have is that a user will pass in a list of parameters specifying what they want to see (or exclude) in a result set. Based on that list the result set could then be customized for the user. A way this can be done with Jackson is using filters.

Here is an example:

@JsonFilter("someFilter")
class MyBean {
    ...
}

MyBean value;
//business logic to set value
ObjectMapper mapper = new ObjectMapper();
FilterProvider filters = new SimpleFilterProvider().addFilter("someFilter",
    SimpleBeanPropertyFilter.filterOutAllExcept("someProperty"));

String json = mapper.filteredWriter(filters).writeValueAsString(value);
//....

It would be nice to be able to do this with Spring MVC using either the MappingJackson2HttpMessageConverter or a view (MappingJackson2JsonView)

For controllers using view resolution I think it would be pretty straight forward. The filter could be applied the same way a JsonView is done now, it could be done like this:

    @RequestMapping(value = "/data", method = RequestMethod.GET)
    public String getData(Model model) {
        //business logic to create or look up filter
        FilterProvider filters = new SimpleFilterProvider().addFilter("someFilter",
            SimpleBeanPropertyFilter.filterOutAllExcept("someProperty"));

        //add to model
        model.addAttribute('jsonFilters', filters);

        return "dataView";
    }

And then the MappingJackson2JsonView class could read that value to configure the serializer.

It gets a little more tricky with the message converter set up (which is what I mosly use) since the AbstractJackson2HttpMessageConverter needs a way to dynamically know what filter to use. Maybe the controller method could return a wrapper type that could be detected by the message converter. Something like:

    @RequestMapping(value = "/data", method = RequestMethod.GET)
    @ResponseBody
    public Object getData() {
        MyObject data;
        //....do some business logic and set data
        //create or look up filter
        FilterProvider filters = new SimpleFilterProvider().addFilter("someFilter",
            SimpleBeanPropertyFilter.filterOutAllExcept("someProperty"));

        return new FilterWrapper(filters, data);
    }

If the converter detects that FilterWrapper type then it could set up the writer to use the filter when serializing. The filter would need to be configured dynamically at runtime so an annotation on the controller method wouldn't work in this case.

Let me know what you think.


Affects: 4.1.4

Reference URL: http://wiki.fasterxml.com/JacksonFeatureJsonFilter

Issue Links:

Referenced from: commits ca06582

2 votes, 14 watchers

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions