我的第一个Web客户端提供“找不到媒体类型的MessageBodyWriter ...”(JSON)

时间:2016-11-15 17:00:38

标签: java eclipse jar jersey genson

我先给你讲一个简短的故事。如果我在Eclipse中导出我的jar文件和jar文件(Runnable Jar向导并选择“Package required libraries ...”)而不是“Extract required libraries”,那么每件事都有效,但是开始的速度非常慢。如果我使用提取方法构建我的jar,代码将导致最终的

org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=application/json

我没有使用Maven。我还不知道。在大多数情况下,我对Eclipse缺乏经验,但我到了那里。我认为Genson会给我创建JSON所需的东西。

如果我列出我的jar文件和grep for MessageBodyWriter,我得到

1220 Tue Nov 15 10:29:02 CST 2016 javax/ws/rs/ext/MessageBodyWriter.class             
  47 Tue Nov 15 10:29:02 CST 2016 META-INF/services/javax.ws.rs.ext.MessageBodyWriter 

为了了解更长的故事,我在Eclipse中创建了一个简单的Java项目,将外部jar添加到我的构建路径中。 Eclipse不会抱怨任何遗漏。在我的代码中只有一两个关于未使用的this-and-thats的警告。出口工作正常,无论我做什么,没有问题。只有执行才会显示出一些刺激。

在我的请求课程中,我相信我已正确设置了所有内容。这是可以想象的最简单的POST客户端。我有必要的空构造函数,正确的注释。

@XmlRootElement
@Produces(MediaType.APPLICATION_JSON)

public class QQNotificationRequest {

    @JsonProperty("id")
    private int id;
    @JsonProperty("subId")
    private int subId;
    @JsonProperty("type")
    private int type;
    @JsonProperty("scode")
    private int scode;
    @JsonProperty("datetime")
    private String datetime;
    ...

这是我失败的终极电话

Response resp = m_webTarget.request(MediaType.APPLICATION_JSON).post(Entity.json(message));

这些是我的外部罐子

javax.ws.rs-api-2.0.1.jar
aopalliance-repackaged-2.5.0-b05.jar
hk2-api-2.5.0-b05.jar
hk2-locator-2.5.0-b05.jar
hk2-utils-2.5.0-b05.jar
javassist-3.20.0-GA.jar
javax.annotation-api-1.2.jar
javax.inject-2.5.0-b05.jar
javax.servlet-api-3.0.1.jar
jaxb-api-2.2.7.jar
jersey-guava-2.24.jar
org.osgi.core-4.2.0.jar
osgi-resource-locator-1.0.1.jar
persistence-api-1.0.jar
validation-api-1.1.0.Final.jar
jersey-client.jar
jersey-common.jar
jersey-container-servlet.jar
jersey-container-servlet-core.jar
jersey-media-jaxb.jar
jersey-server.jar
jargs.jar
genson-1.4.jar
jt400.jar
log4j-api-2.7.jar
log4j-core-2.7.jar

我觉得罐子里有东西没有正确地“导出”,但我不确定。只是在这里猜测,因为Java必须经历爆炸大罐内所有罐子的过程,它才能找到开始执行所需要的东西,而大罐子里面的.classes则没有。

暂时失去了,但是仍在继续。我很欣赏任何指示。

1 个答案:

答案 0 :(得分:1)

问题是每个Jersey jar的META-INF/services目录中都有文件需要在运行时出现。这些文件用于自动加载和注册提供程序类。

当所有的jar都保持独立并且只是添加到类路径时,所有文件都保持不变。但是当您创建一个jar时,这些文件会重叠(它们都具有相同的名称),因此将只包含每个具有相同名称的文件中的一个。因此Genson的文件可能不是包含的文件。

您可以将Genson明确注册为应用程序的提供者。我不是真的使用Genson,所以我不确定这样做的正确方法。但是快速查看the codebase,您似乎需要注册GensonJsonConverter

这可能有用,但它并没有解决有关未包含服务文件的主要问题。可能还有其他自动注册的组件未注册。

我不是真正的Eclipse用户,所以我不确定如何解决这个问题。我知道如果您使用的是Maven,则可以使用maven-shade-plugin,如上所述here。这个插件的功能是将所有文件内容连接成一个文件。这样可以解决问题。

所以我想这只是答案的一半,因为我不确定在使用Eclipse时如何做类似的事情。但至少你现在知道这个问题了。

仅供参考,this file,是您主要关心的问题。如果你浏览其他泽西岛罐子,你会发现有类似的文件。这就是我所说的,当我说只会使用一个时。在构建jar时,您需要找到一种将其内容连接到一个文件的方法