Я создаю RESTful API и хочу предоставить разработчикам возможность выбирать, какие поля возвращаться в ответ JSON. Это сообщение в блоге показывает примеры того, как несколько API (Google, Facebook, LinkedIn) позволяют разработчикам настраивать ответ. Это называется частичным ответом.
Пример может выглядеть так:
/users/123?fields=userId,fullname,title
В приведенном выше примере API должен возвращать поля userId, fullName и заголовки для пользователя "123".
Я ищу идеи о том, как реализовать это в своем веб-сервисе RESTful. В настоящее время я использую CXF (edit: и Jackson), но желаю попробовать другую реализацию JAX-RS.
Вот что я сейчас имею. Он возвращает полный пользовательский объект. Как я могу вернуть только те поля, которые хочет запросить API во время выполнения, на основе "параметров полей"? Я не хочу делать другие поля Null. Я просто не хочу их возвращать.
@GET
@Path("/{userId}")
@Produces("application/json")
public User getUser(@PathParam("userId") Long userId,
@DefaultValue("userId,fullname,title") @QueryParam("fields") String fields) {
User user = userService.findOne(userId);
StringTokenizer st = new StringTokenizer(fields, ",");
while (st.hasMoreTokens()) {
// here where i would like to select only the fields i want to return
}
return user;
}
UPDATE:
Я следил за ссылкой unludo, которая затем была связана с этим: http://wiki.fasterxml.com/JacksonFeatureJsonFilter
С этой информацией я добавил @JsonFilter("myFilter")
в свой класс домена. Затем я изменил метод службы RESTful, чтобы вернуть String вместо User следующим образом:
@GET
@Path("/{userId}")
@Produces("application/json")
public String getUser(@PathParam("userId") Long userId,
@DefaultValue("userId,fullname,title") @QueryParam("fields") String fields) {
User user = userService.findOne(userId);
StringTokenizer st = new StringTokenizer(fields, ",");
Set<String> filterProperties = new HashSet<String>();
while (st.hasMoreTokens()) {
filterProperties.add(st.nextToken());
}
ObjectMapper mapper = new ObjectMapper();
FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter",
SimpleBeanPropertyFilter.filterOutAllExcept(filterProperties));
try {
String json = mapper.filteredWriter(filters).writeValueAsString(user);
return json;
} catch (IOException e) {
e.printStackTrace();
return e.getMessage();
}
}
Мне нужно сделать больше тестов, но пока так хорошо.