【问题标题】:Why is Jersey/JAX-RS client unable to handle generics?为什么 Jersey/JAX-RS 客户端无法处理泛型?
【发布时间】:2015-02-20 09:18:33
【问题描述】:

我有一个 Jersery/JAX-RS 客户端,它访问一个 RESTful API (JSON),它应该返回我的 POJO 列表:

// Hits: GET localhost:8080/myapp/fizz/widget/{widget_id}
@Override
public List<Widget> getWidgetsByUser(Long id) {
    return webResource.path("fizz").path("widget").path(id.toString()).get(List.class);
}

以及用于测试客户端的驱动程序:

public class Driver {
    public static void main(String[] args) {
        Driver d = new Driver();
        d.run();
    }

    public void run() {
        MyAppService myService = getSomehow();

        List<Widget> widgets = myService.getWidgetResource().getWidgetsByUser(2L);
        for(Widget widget : widgets) {
            System.out.println("\t...and it found Widget #" + widget.getCaseId());
        }
    }
}

当我运行它时,我得到:

Exception in thread "main" java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.me.myapp.Widget
    <stack trace omitted for brevity>

从for循环抛出异常:

for(Widget widget : widgets) {

这告诉我客户端有点工作,但我没有正确配置它。

因此,要么 Jersey 尝试返回纯 JSON,而 没有 尝试将其映射回 Widget 列表,要么我错误地调用了 get(Class&lt;?&gt;) 方法。有什么想法吗?

【问题讨论】:

  • 这很容易理解——你是在告诉 Jersey(可能有 Jackson 在它下面)将响应正文转换为 List。除了选择框架想要用于列表元素的任何内容之外,您还能期望框架做什么。
  • 感谢@PavelHoral (+1) - 那么如何配置 Jersey 以返回 List&lt;Widget&gt;
  • 您可以通过引入WidgetCollection 对象并将列表作为其属性来解决此问题(我会说这是一种常见做法)。除此之外,我会阅读泽西岛的文档。但是您最终可能会阅读 Jackson 解决此问题的方法 (TypeReference)——但这可能不适用于 Jersey 的 API。

标签: java json generics jersey jax-rs


【解决方案1】:

Pavel Horal 的评论是正确的。如果没有已知类型,Jackson(底层解串器)将映射到 LinkedHashMap,因此它将返回 List&lt;LinkedHashMap&gt;

修复:

对于泛型类型,我们应该使用另一个get() method,它接受GenericType 参数。所以我们应该做类似的事情

...get(new GenericType<List<Widget>>(){});

【讨论】:

    猜你喜欢
    • 2016-02-21
    • 1970-01-01
    • 1970-01-01
    • 2020-06-19
    • 2015-07-20
    • 2011-10-26
    • 1970-01-01
    • 2013-02-13
    • 1970-01-01
    相关资源
    最近更新 更多