【问题标题】:"MessageBodyWriter not found" when returning List<Long> with the Response-object in JAX-RS使用 JAX-RS 中的响应对象返回 List<Long> 时“找不到 MessageBodyWriter”
【发布时间】:2018-08-10 13:06:28
【问题描述】:

我目前正在尝试创建一个返回 List 类型对象的 rest-webservice。该服务使用 @Produces(MediaType.APPLICATION_JSON) 进行注释。

我对这个项目中的其他服务没有任何问题。

如果我编写如下代码:

List<Long> list = new ArrayList<Long>();
            list.add(100L);
            list.add(200L);
            list.add(300L);

return Response.ok(list)
               .build();

然后我在日志中收到以下消息:

MessageBodyWriter not found for media type=application/json, type=class java.util.ArrayList, genericType=class java.util.ArrayList.

如果我改为将其编写如下(与我为项目中的另一个服务所做的相同,但它是一个 pojo 对象列表):

List<Long> list = new ArrayList<Long>();
            list.add(100L);
            list.add(200L);
            list.add(300L);

GenericEntity<List<Long>> genericEntity = new GenericEntity<List<Long>>(list){};

return Response.ok(genericEntity)
               .build();

然后我收到以下消息:

MessageBodyWriter not found for media type=application/json, type=class java.util.ArrayList, genericType=java.util.List<java.lang.Long>.

谷歌搜索后,我发现以下建议将列表转换为数组,如下所示,但这也不起作用。

List<Long> list = new ArrayList<Long>();
            list.add(100L);
            list.add(200L);
            list.add(300L);

            return Response.ok(list.toArray()).build();

然后我得到:

MessageBodyWriter not found for media type=application/json, type=class [Ljava.lang.Object;, genericType=class [Ljava.lang.Object;.

我们使用的是 jackson-core 版本 2.3.2,jax-rs 实现是 Jersey,它包含在 Weblogic 12c 中。

有什么好的解决方案(不使用任何其他库)?

【问题讨论】:

  • 如果您使用 JAX-RS 并希望将结果作为 List&lt;Long&gt; 返回,我相信您只返回 List&lt;Long&gt; 本身,而不是包裹在 Response 中。 JAX-RS 将负责将其编组为请求的类型。
  • 是的,这是真的。但我也想在响应消息中返回一个标题。如果服务器端出现问题,我将返回带有相应 http 状态代码的错误消息。
  • 那么你只需抛出一个用适当的错误代码构造的WebApplicationException(使用Response.Status定义的状态代码常量)。让 JAX-RS 为您完成工作。
  • 感谢您的评论!似乎我今天学到了一些新东西(WebApplicationException)。但我仍然需要能够在响应中添加标头,包括正确响应和错误响应。
  • 您使用的是哪个 JAX-RS 框架?

标签: java rest jax-rs weblogic response


【解决方案1】:

您没有提到您正在使用哪个 JAX-RS 框架,但根据 Apache CXF documentation 举例,如果您想使用 Jackson 作为 JSON Provider,您需要此依赖项:

<dependency>
  <groupId>com.fasterxml.jackson.jaxrs</groupId>
  <artifactId>jackson-jaxrs-json-provider</artifactId>
  <version>2.9.3</version>
</dependency>

然后在您的 JAX-RS 服务上注册一个 Jackson 提供程序,我猜您的情况是 POJO 的一个,而不是 JAXB bean 的一个(警告:CXF 文档中的包名称是 Jackson 1.x,我替换为 Jackson 2.x 的那个):

<jaxrs:providers>
   <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider"/>
</jaxrs:providers>

对于泽西岛,它将是 different dependency

【讨论】:

  • 感谢您的回答!现在已经添加了我正在使用的框架。我试过你的建议,但不幸的是它似乎没有帮助。我认为这不是问题,因为杰克逊似乎适用于所有其他情况。
  • 再次,您使用的是哪个 JAX-RS 框架? (在以前的 cmets 中已经问过)如果您想要更好的答案,这将有助于检查它是否适用于您的情况。虽然是相同的 JAX-RS 标准,但是在实现上还是有区别的。
  • 抱歉,如果问题不清楚。它是包含在 Weblogic 12c 中的 Jersey。我将使用此信息更新问题。
  • 好吧,恐怕我不习惯 Jersey / Weblogic 环境 :-( 所以也许精通 Jersey 的人有更好的答案。
【解决方案2】:

虽然在 Response 对象中返回 List 对我不起作用,但我设法通过将列表嵌入新类来解决它。

新类如下所示:

public class LongArrayList {

    private List<Long> list;

    public LongArrayList() {

    }

    public LongArrayList(List<Long> list) {
        this.setList(list);
    }

    public List<Long> getList() {
        return list;
    }

    public void setList(List<Long> list) {
        this.list = list;
    }
}

然后我将这个列表返回如下:

return Response.ok(new LongArrayList(theOldLongList))
               .build();

不幸的是,这会返回比我想要的更大的 json:

{"list":[5,12,29,30]}

如果有人找到更好的解决方案,我会接受它作为这个问题的答案。

【讨论】:

    【解决方案3】:

    当您生成 json 类型的数据时,需要 Json 相关的 jar 来将 Object 解析为 json 形式。

    如果是 Maven 项目,请将 Jackson jar 添加到您的 pom.xml。

    添加这个依赖..

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.9.6</version>
    </dependency>
    

    或者

    下载 jar 并将其添加到类路径。

    【讨论】:

    • 感谢您的回复!我已经用我们正在使用的 Jackson 版本更新了问题。
    猜你喜欢
    • 2013-11-02
    • 2012-02-06
    • 2014-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    • 2012-07-31
    • 1970-01-01
    相关资源
    最近更新 更多