Limiting Fields in JSON Response for REST API?

2019-05-15 19:53发布

问题:

I am using Spring and Java and implementing REST Based services. I have a set of developers who develop for mobile,iPad and Web too. Consider I have a bean

Class User{
private String Name;
private Integer id;
private String photoURL;
private ArrayList<String> ProjectName;
private ArrayList<String> TechnologyList;
private ArrayList<String> InterestList;

//Getters and setters

}

While the Web Developers need the entire fields and mobile developers just require two fields from it whereas the iPad requires something in between mobile and web.

Since I am using jackson as a parser, is there a way where while requesting to the controller I can specify which all data I require and avoid the others. For example consider I do a GET request like

GET>http://somedomain.com/users?filter=name,id,photoUrl

Which returns me a JSON structure something like

{
"name":"My Name",
"id":32434,
"photoUrl":"/sss/photo.jpg"
}

Sameway if someone asks for some more fields, they could be filtered. Please let me know how this can be done so that my API remains generic and useable for all.

回答1:

You can achieve what you want but some extra work is necessary. I can offer you two solutions.

1. Return a Map

Simply put every property that is requested into the map.

2. Use Jacksons Object Mapper directly

Jackson lets you set filters that specify which properties are serialized or ignored.

FilterProvider filter = new SimpleFilterProvider().addFilter("myFilter",
   SimpleBeanPropertyFilter.filterOutAllExcept(requestedProperties));

String json = objectMapper.writer(filter).writeValueAsString(value);

You can then return the JSON string directly instead of an object.

For both solutions you would ideally write a class that does the job. But if you do that you could as well write your own message converter. You could extend the MappingJackson2HttpMessageConverter, for instance, and overwrite the writeInternal method to suit your needs. That has the big advantage that you don't need to change your controllers.



回答2:

The straightforward solution is to implement custom Jackson JSON serializer that will get field names that should be serialized from thread local storage and then serialize only fields which names are presented in that context. For other hand, in controller you can grab all allowed fields names from url and store them into thread local context. Hope this helps.