Как вернуть частичный ответ JSON с помощью Java?

Я создаю RESTful API и хочу предоставить разработчикам возможность выбирать, какие поля возвращать в ответе JSON. Это В сообщении в блоге показаны примеры того, как несколько API (Google, Facebook, LinkedIn) позволяют разработчикам настраивать ответ. Это называется частичным ответом.

Пример может выглядеть следующим образом:

/users/123?fields=userId,fullname,title

В приведенном выше примере API должен возвращать поля userId, fullName и title для пользователя «123».

Я ищу идеи, как реализовать это в моей веб-службе RESTful. В настоящее время я использую CXF (edit: и Jackson), но желаю попробовать другую реализацию 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 filterProperties = new HashSet();
    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();
    }
}

Мне нужно провести дополнительное тестирование, но пока все хорошо.

41
задан Justin 16 February 2012 в 22:39
поделиться