2

I'm using Spring MVC 4.3.2 with @RestController and I would like to be able to dynamically filter JSON properties specified by our clients in the request.

To keep things easy, let's say I have a Person POJO that contains firstName and lastName fields. This POJO is generated, that's why you will see that I'm using a mixin.

Let's say one client want to retrieve all the persons' firstName, he will call our rest endpoint like this : http://localhost/persons&fields=firstName. And the json will only contains the firstName, not the lastName fields.

Here is my Controller:

@RestController
public class RestPersonController implements PersonApi {

    @Autowired
    private PersonService personService;

    @Autowired
    private ObjectMapper objectMapper;    

    @Override
    @GetMapping(path = "/persons")
    public ResponseEntity<List<Person>> getPersons(
        @RequestParam(required = false) String fields) {

        List<Person> persons = this.personService.getPersons();

        // Filter fields
        if (StringUtils.isNotBlank(fields)) {
            configureFilter(fields);
        }

        return ResponseEntity.status(HttpStatus.OK).body(persons);
    }

    private void configureFilter(String fields) {
        Set<String> fieldsToKeep = new HashSet<>();
        fieldsToKeep.add(fields);

        objectMapper.addMixIn(Person.class, PersonDynamicFilterMixIn.class);
        FilterProvider filterProvider = new SimpleFilterProvider().
        addFilter("dynamicFilter", SimpleBeanPropertyFilter.filterOutAllExcept(fieldsToKeep));

        objectMapper.setFilterProvider(filterProvider);
    }
}

As you can see, the return of the method is ResponseEntity<List<Person>> (I can't change it to JacksonMappingValue, it is from the PersonApi interface) and we are returning with ResponseEntity.status(HttpStatus.OK).body(persons) (so I can't manually write the JSON response with the objectMapper myself);.

Under the hood, Spring is using Jackson ObjectMapper to do the conversion. I would like to configure that ObjectMapper when the fields request parameter is specified.

I also want the ObjectMapper configuration to be the same as Spring's default.

I can't use JsonViews because otherwise it is not dynamic anymore.

Could someone show me how I need to configure Spring to do that ? I tried to use these kind of things in SpringConfiguration, but then I end up with some of my tests not working anymore. For some tests, if I run a single test it passes, if I run the whole test suite that test doesn't pass anymore ...

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.add(new MappingJackson2HttpMessageConverter(objectMapper()));
}

@Bean
public ObjectMapper objectMapper() {
    return Jackson2ObjectMapperBuilder.json().build();
}

Thank you for your help !

Nis
  • 560
  • 5
  • 18

0 Answers0