如何使用Java返回部分JSON响应?

如何使用Java返回部分JSON响应?

问题描述:

我正在构建一个RESTful API,并希望为开发人员提供选择在JSON响应中返回哪些字段的选项。 此博客文章显示了几个API(Google,Facebook,LinkedIn)如何允许开发人员自定义的示例响应。这被称为部分响应。

I'm building a RESTful API and want to provide developers with the option to choose which fields to return in the JSON response. This blog post shows examples of how several API's (Google, Facebook, LinkedIn) allow developers to customize the response. This is referred to as partial response.

示例可能如下所示:

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

在上面的例子中API应该返回User123的userId,fullName和title字段。

In the example above the API should return the userId, fullName and title fields for User "123".

我正在寻找如何在我的RESTful Web服务中实现它的想法。我目前正在使用CXF(编辑:和杰克逊),但愿意尝试另一种JAX-RS实现。

I'm looking for ideas of how to implement this in my RESTful web service. I'm currently using CXF (edit: and Jackson) but willing to try another JAX-RS implementation.

这是我现在拥有的。它返回一个完整的User对象。如何根据字段参数返回API调用者在运行时所需的字段?我不想让其他字段为空。我根本不想退货。

Here's what I currently have. It returns a full User object. How can I return only the fields the API caller wants at runtime based on the "fields" paramaeter? I don't want to make the other fields Null. I simply don't want to return them.

@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

I followed unludo's link which then linked to this: http://wiki.fasterxml.com/JacksonFeatureJsonFilter

通过该信息,我将 @JsonFilter(myFilter)添加到我的域类。然后我修改了我的RESTful服务方法,返回String而不是User,如下所示:

With that info I added @JsonFilter("myFilter") to my domain class. Then I modified my RESTful service method to return String instead of User as follows:

@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();
    }
}

我需要做更多测试,但到目前为止还不错。

I need to do more testing but so far so good.

如果你使用Jackson(一个伟大的JSON lib - 我相信Java的标准),你可以使用 @View 注释,用于过滤生成的对象中的内容。

If you use Jackson (a great JSON lib - kind of the standard for Java I believe), you may use the @View annotation to filter what you want in the resulting object.

我知道你想要一些动态的东西,所以它有点复杂。您将在此处找到所需内容: http://www.cowtowncoder .com / blog / archives / 2011/02 / entry_443.html (查看6.完全动态过滤: @JsonFilter )。

I understand that you want something dynamic so it's a bit more complicated. You will find what you are looking for here: http://www.cowtowncoder.com/blog/archives/2011/02/entry_443.html (look at 6. Fully dynamic filtering: @JsonFilter).

我会对你会找到的解决方案感兴趣。

I would be interested in the solution you will find.