10

I am using spring rest api 4.x. We have a requirement to filter the fields in the response based on the request parameters.

My User object:

private class UserResource { private String userLastName; private String userFirstName; private String email; private String streetAddress; } E.g. URL: curl -i http://hostname:port/api/v1/users?fields=firstName,lastName. 

In this case I need to return only the fields which are in the request param "fields". JSON output should contain only firstName, lastName.

There are several ways filter the fields in Jackson based on the object. In my case I need to filter dynamically by passing the list of fields to Jackson serializer.

Please share some ideas.

3 Answers 3

18

Thanks Ali. It is a great help. Let me implement it today. I will post the result

@JsonFilter("blah.my.UserEntity") public class UserEntity implements Serializable { //fields goes here } @RequestMapping(value = "/users", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public MappingJacksonValue getUsers(@RequestParam MultiValueMap<String, String> params) { //Build pageable here Page<UserEntity> users = userService.findAll(pageable); MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(users); FilterProvider filters = new SimpleFilterProvider() .addFilter("blah.my.UserEntity", SimpleBeanPropertyFilter .filterOutAllExcept("userFirstName")); mappingJacksonValue.setFilters(filters); return mappingJacksonValue; } 
Sign up to request clarification or add additional context in comments.

1 Comment

This is very helpful for me
3

Use a ResponseBodyAdvice in order to change the response before it got written to the HTTP response. In beforeBodyWrite(...) method you have access to the current ServerHttpRequest which you can read the fields value. Your body advice would look like following:

@ControllerAdvice public class MyResponseBodyAdvisor implements ResponseBodyAdvice<UserResource> { @Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { return returnType.getParameterType().equals(UserResource.class); } @Override public UserResource beforeBodyWrite(UserResource body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { String fields = ((ServletServerHttpRequest) request).getServletRequest().getParameter("fields"); // body.set...(null) for each field not in fields return body; } } 

2 Comments

Hi Ali, In your solution, we are making fields empty. But I dont want to display the field at all. I implemented as described in SPR-12586. Thanks.
Annotate your dto with @JsonInclude to remove the empty fields from the response
0

It appears this is supported in Spring 4.2 as per https://github.com/spring-projects/spring-framework/issues/17187 via Jackson JsonFilter (though the jira is returning an error at the moment).

2 Comments

Hi Ben, Thanks for the response. It was very helpful.
Here is my solution. MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(MyObject); In your controller just return mappingJacksonValue. make sure MyObject has @JsonFilter("myObject") annotation.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.