Details

    • Type: Improvement
    • Status: Closed
    • Priority: Minor
    • Resolution: Complete
    • Affects Version/s: 4.1.4
    • Fix Version/s: 4.2 RC1
    • Component/s: Web
    • Labels:
      None

      Description

      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.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                sdeleuze S├ębastien Deleuze
                Reporter:
                chris8204 Christopher Shannon
                Last updater:
                Spring Issuemaster
              • Votes:
                2 Vote for this issue
                Watchers:
                14 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Days since last comment:
                  26 weeks ago