Java 未找到 Media type=application/json 的 MessageBodyReader

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23442440/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 23:00:44  来源:igfitidea点击:

MessageBodyReader not found for media type=application/json

javajsonjerseyjax-rs

提问by

I have wrote a JAX-RS server and client both use Jersey. I want to sent a collection of my entities to client and I made this steps:

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

  1. Made entity extends Serializable
  2. Wrote a custom provider and extended it to support a collections
  3. Copy-paste entity and provider to client side
  1. 使实体扩展可序列化
  2. 编写了一个自定义提供程序并将其扩展为支持集合
  3. 将实体和提供者复制粘贴到客户端

I make a request, it sucessfully handled on the server side by client receives an error:

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

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.access0(JerseyInvocation.java:90)
org.glassfish.jersey.client.JerseyInvocation.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)

Server:

服务器:

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

Client:

客户:

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

Provider:

供应商:

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;
}
}

回答by blacharnia

Your entity class does not have an empty constructor, which is needed for the JAX-RS unmarshalling.

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

Have a look here:

看看这里:

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

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

回答by brokethebuildagain

Sorry to resurrect this post, but I was having this problem with a Maven project and found that I needed to include a dependency for Hymanson-jaxrs-json-providerin my pom:

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

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

MVN Repository: http://mvnrepository.com/artifact/com.fasterxml.Hymanson.jaxrs/Hymanson-jaxrs-json-provider

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

回答by Denis535

You can use jersey json library:

您可以使用球衣 json 库:

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

Or genson:

或genson:

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

回答by brunocrt

Check if you are registering the media type for JSON support. Do you have jersey-media-moxyon your class-path? If not, add this dependency to your pom.xml, please check your jersey version, in this example I'm using Jersey 2 (2.24)

检查您是否正在为 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>

回答by Purushothaman

For Gradle, add the following dependency:

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

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

回答by user1932890

This very same exception is also thrown by jersey-media-moxy for silly mistakes like using an @XmlAttributeannotation where you really need an @XmlElement. This was the case in my scenario, and this is something to look into especially if the problem only happens for certain classes but others work fine.

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

回答by Hari Kiran

Adding this dependency has fixed my error while other suggested answers did not:

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

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