Я создаю RESTful API и хочу предоставить разработчикам возможность выбирать, какие поля возвращать в ответе JSON. В этом блоге показаны примеры того, как несколько API (Google, Facebook, LinkedIn) позволяют разработчикам настраивать ответ.Это называется частичным ответом.
Пример может выглядеть следующим образом:
/users/123?fields=userId,fullname,title
В приведенном выше примере API должен возвращать поля userId, fullName и title для пользователя «123».
Я ищу идеи о том, как реализовать это в моем веб-сервисе RESTful.В настоящее время я использую CXF (edit: и Джексон), но хочу попробовать другую реализацию JAX-RS.
Вот что у меня сейчас есть.Возвращает полный объект User.Как я могу вернуть только те поля, которые хочет вызывающий API во время выполнения, основываясь на параметре «fields»?Я не хочу, чтобы другие поля были пустыми.Я просто не хочу их возвращать.
@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's where i would like to select only the fields i want to return
}
return user;
}
ОБНОВЛЕНИЕ:
Я перешел по ссылке 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();
}
}
Мне нужно больше тестировать, но пока все хорошо.