【问题标题】:MessageBodyReader not found for media type=application/json未找到媒体类型 = 应用程序/json 的 MessageBodyReader
【发布时间】:2014-06-19 23:34:12
【问题描述】:

我编写了一个 JAX-RS 服务器和客户端都使用 Jersey。我想将我的实体集合发送给客户,我做了以下步骤:

  1. 制造的实体扩展了可序列化
  2. 编写了自定义提供程序并将其扩展为支持集合
  3. 将实体和提供者复制粘贴到客户端

我发出一个请求,它成功地被客户端在服务器端处理收到一个错误:

org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=application/json, type=interface java.util.List, genericType=java.util.List<model.HotelsEntity>.
org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:225)
org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:149)
org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1124)
org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:853)
org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:812)
org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:377)
org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:813)
org.glassfish.jersey.client.JerseyInvocation.access$600(JerseyInvocation.java:90)
org.glassfish.jersey.client.JerseyInvocation$3.call(JerseyInvocation.java:693)
org.glassfish.jersey.internal.Errors.process(Errors.java:315)
org.glassfish.jersey.internal.Errors.process(Errors.java:297)
org.glassfish.jersey.internal.Errors.process(Errors.java:228)
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:424)
org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:689)
org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:405)
org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:301)
service.HotelService.getHotels(HotelService.java:30)
actions.HotelAction.perform(HotelAction.java:42)
MainServlet.processResponse(MainServlet.java:33)
MainServlet.doPost(MainServlet.java:22)
javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

服务器:

    @GET
@Produces(MediaType.APPLICATION_JSON)
public Response getHotelsList(@QueryParam("startDate") String startDate,
                              @QueryParam("endDate") String endDate) {
    List<HotelsEntity> list = hotelService.getAll();
    return ResponseFactory.response(Response.Status.OK, list);
}

客户:

    GenericType<List<HotelsEntity>> genericType = new GenericType<List<HotelsEntity>>(){};
    WebTarget target = client.target(preparePath());
    List<HotelsEntity> hotels = target.request(MediaType.APPLICATION_JSON_TYPE).get(genericType);

提供者:

public class JsonProvider<T> implements MessageBodyReader<T>, MessageBodyWriter<T> {

@Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
    return MediaType.APPLICATION_JSON.equals(mediaType.getType()) &&
            MediaType.APPLICATION_JSON.equals(mediaType.getSubtype());
}

@Override
public T readFrom(Class<T> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {
    Gson gson = createGson();
    Reader reader = new InputStreamReader(entityStream, Charset.forName(Constants.UTF_8));
    return gson.fromJson(reader, genericType);
}

@Override
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
    return MediaType.APPLICATION_JSON.equals(mediaType.getType()) &&
            MediaType.APPLICATION_JSON.equals(mediaType.getSubtype());
}

@Override
public long getSize(T t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
    return -1;
}

@Override
public void writeTo(T t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
    Gson gson = createGson();
    JsonElement element = gson.toJsonTree(entityStream);
    Writer writer = null;
    try {
        writer = new OutputStreamWriter(entityStream, Charset.forName(Constants.UTF_8));
        gson.toJson(element, writer);
    } finally {
        if (writer != null) {
            writer.flush();
        }
    }
}

private Gson createGson() {
    return new GsonBuilder().setPrettyPrinting().create();
}

}

@Provider
public class JsonCollection extends JsonProvider<Collection<? extends HospitalityEntity>> {}

@Entity
@Table(name = "hotels", schema = "", catalog = "mydb")
public class HotelsEntity implements HospitalityEntity{
private int idHotel;
private String name;
private String region;
private String description;

@Id
@Column(name = "id_hotel")
public int getIdHotel() {
    return idHotel;
}

public void setIdHotel(int idHotel) {
    this.idHotel = idHotel;
}

@Basic
@Column(name = "name")
public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@Basic
@Column(name = "region")
public String getRegion() {
    return region;
}

public void setRegion(String region) {
    this.region = region;
}

@Basic
@Column(name = "description")
public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}


@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    HotelsEntity that = (HotelsEntity) o;

    if (idHotel != that.idHotel) return false;
    if (description != null ? !description.equals(that.description) : that.description != null) return false;
    if (name != null ? !name.equals(that.name) : that.name != null) return false;
    if (region != null ? !region.equals(that.region) : that.region != null) return false;

    return true;
}

@Override
public int hashCode() {
    int result = idHotel;
    result = 31 * result + (name != null ? name.hashCode() : 0);
    result = 31 * result + (region != null ? region.hashCode() : 0);
    result = 31 * result + (description != null ? description.hashCode() : 0);
    return result;
}
}

【问题讨论】:

  • 如果您正确包含jersey-media-moxy 或其他内容,当您没有自定义类的@XmlJavaTypeAdapter 时会遇到此错误。
  • 如果你已经完成了其他答案中的所有事情,不要忘记clientConfig.register(JacksonJsonProvider.class);
  • 我认为你的问题可能出在这个 @Override public boolean isReadable(Class> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return MediaType.APPLICATION_JSON.equals(mediaType.getType ()) && MediaType.APPLICATION_JSON.equals(mediaType.getSubtype()); } 参数 mediaType 是一个实例,有类型(“应用程序”)和子类型(“json”)之分。替换为 return MediaType.valueOf(MediaType.APPLICATION_JSON).equals(mediaType);希望对您有所帮助
  • 帮我打包 uber jar

标签: java json jersey jax-rs


【解决方案1】:

你可以使用 jersey json 库:

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.22</version>
</dependency>

或者根森:

<dependency>
    <groupId>com.owlike</groupId>
    <artifactId>genson</artifactId>
    <version>1.3</version>
</dependency>

【讨论】:

  • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
  • 这些库/依赖项是处理 JSON 数据的其他选项,它们中的大多数是兼容的,因为它们实现了称为 JSR 353 或 374 - Java API for JSON Processing (JSON-P) 的标准 Java 规范。遵循此规范的所有库都能够以标准方式解析、生成、转换和查询 JSON,并与 Java 生态系统兼容。有关此规范的更多信息,请参阅 jcp.org/en/jsr/detail?id=353jcp.org/en/jsr/detail?id=374。有关 Genson 库实现的信息genson.io
【解决方案2】:

很抱歉恢复这篇文章,但我在一个 Maven 项目中遇到了这个问题,发现我需要在我的 pom 中包含一个 jackson-jaxrs-json-provider 的依赖项:

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

MVN 存储库:http://mvnrepository.com/artifact/com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider

【讨论】:

  • 只是将它添加到我的 pom 并不能解决我的问题。
  • 根据您的开发环境,您可能需要更新源或在更改后重新导入 pom 以使其工作。但这对我有用。
  • 我已经解决了我的问题。我必须用我的ClientConfig 注册像this one 这样的课程。
  • @2rs2ts 没有帮助我:(
  • 没用。下面的答案是 jersey json 库。
【解决方案3】:

您的实体类没有 JAX-RS 解组所需的空构造函数。

看看这里:

https://blogs.oracle.com/groundside/entry/jax_rs_2_0_messagebodyreader

【讨论】:

  • 这个解决了我的问题。
  • 这解决了我的问题。花了几个小时弄清楚出了什么问题!
【解决方案4】:

检查您是否正在注册支持 JSON 的媒体类型。你的类路径上有 jersey-media-moxy 吗?如果没有,请将此依赖项添加到您的 pom.xml,请检查您的球衣版本,在此示例中,我使用的是 Jersey 2 (2.24)

    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-moxy</artifactId>
        <version>2.24</version>
    </dependency>

【讨论】:

  • 我还必须添加jaxb-runtimejersey-guava
  • jersey-media-moxy 是基于 EclipseLink MOXy 的 Jersey JSON 实体提供者支持模块。 MOXy 实现了 JAXB,允许开发人员通过注解提供映射信息,并支持以 XML 格式存储映射,还可以将 Java 类绑定到 XML 或 JSON 更多信息eclipse.org/eclipselink/#moxy
【解决方案5】:

对于 Gradle,添加以下依赖项:

compile group: 'org.glassfish.jersey.media',
name         : 'jersey-media-moxy',
version      : '2.24.1'

【讨论】:

    【解决方案6】:

    jersey-media-moxy 也会抛出同样的异常,因为愚蠢的错误,比如在你真正需要 @XmlElement 的地方使用 @XmlAttribute 注释。在我的场景中就是这种情况,特别是如果问题仅发生在某些类但其他类工作正常时,这是需要研究的问题。

    【讨论】:

      【解决方案7】:

      添加此依赖项已修复我的错误,而其他建议的答案没有:

      <dependency>
          <groupId>org.glassfish.jersey.media</groupId>
          <artifactId>jersey-media-jaxb</artifactId>
          <version>${jersey2.version}</version>
      </dependency>
      

      【讨论】:

        【解决方案8】:

        可能是你依赖于:

        jersey-common-2.25.1.jar
        jersey-media-json-jackson-2.25.1.jar
        

        ...?

        我在一个执行客户端休息调用的富 Java 应用程序中拥有它。当我为此客户端组装可执行 jar 时,所有依赖项都被解压缩到一个 jar 文件中。原来这两个文件都有一个文件 org.glassfish.jersey.internal.spi.AutoDiscoverable ...内容不同!

        在我的 IDE 中一切正常,一旦在一个 jar 中组装,所需的内容就会被另一个 jar 覆盖。

        最终解决方案是如何声明依赖项中的顺序以及一些排除项。我把它放在列表的前面:

        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
                <artifactId>jersey-media-json-jackson</artifactId>
                <version>2.25.1</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.glassfish.jersey.core</groupId>
                        <artifactId>jersey-common</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>com.fasterxml.jackson.core</groupId>
                        <artifactId>jackson-annotations</artifactId>
                    </exclusion>
                </exclusions>
        </dependency>
        

        后来我放了:

         <dependency>   
              <groupId>org.glassfish.jersey.core</groupId>
              <artifactId>jersey-common</artifactId>
              <version>2.25.1</version>
         </dependency>
        

        我还从其他依赖项中排除了对 jersey-common 的任何其他依赖项。 最好的祝福 弗雷德里克

        【讨论】:

          猜你喜欢
          • 2013-11-19
          • 1970-01-01
          • 2015-01-21
          • 1970-01-01
          • 1970-01-01
          • 2016-01-20
          • 2015-03-27
          • 1970-01-01
          • 2012-08-24
          相关资源
          最近更新 更多