MessageBodyReader not found for media type=application/json

86,715

Solution 1

You can use jersey json library:

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

Or genson:

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

Solution 2

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 jackson-jaxrs-json-provider in my pom:

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

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

Solution 3

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

Have a look here:

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

Solution 4

Check if you are registering the media type for JSON support. Do you have jersey-media-moxy on 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)

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

Solution 5

For Gradle, add the following dependency:

compile group: 'org.glassfish.jersey.media',
name         : 'jersey-media-moxy',
version      : '2.24.1'
Share:
86,715
Admin
Author by

Admin

Updated on November 28, 2020

Comments

  • Admin
    Admin over 3 years

    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:

    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

    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.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)
    

    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;
    }
    }
    
  • 2rs2ts
    2rs2ts over 9 years
    Simply adding this to my pom did not fix my problem.
  • brokethebuildagain
    brokethebuildagain over 9 years
    Depending on your dev environment, you may have to update sources or re-import the pom after changing it to get it to work. But it did the trick for me.
  • 2rs2ts
    2rs2ts over 9 years
    I've solved my problem. I had to register a class like this one with my ClientConfig.
  • Dejell
    Dejell over 9 years
    @2rs2ts didn't help me :(
  • JAL
    JAL over 8 years
    While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value.
  • Jonathas Pacífico
    Jonathas Pacífico over 7 years
    This one fixed my problem.
  • Árpád Magosányi
    Árpád Magosányi about 7 years
    Did not work. The answer below with the jersey json library did.
  • Wand Maker
    Wand Maker almost 7 years
    This fixed my problem. Spent hours figuring out what was going wrong!
  • Peter
    Peter over 6 years
    You also have to register the provider: on your webtarget, call .register(JacksonJsonProvider.class)
  • prayagupa
    prayagupa about 5 years
    I also had to add jaxb-runtime and also jersey-guava
  • brunocrt
    brunocrt over 4 years
    The jersey-media-moxy is Jersey JSON entity providers support module based on EclipseLink MOXy. MOXy implements JAXB allowing developers to provide their mapping information through annotations as well as providing support for storing the mappings in XML format and also enables to bind Java classes to XML or JSON More information on eclipse.org/eclipselink/#moxy
  • brunocrt
    brunocrt over 4 years
    These libraries/dependencies are other options to process JSON data and most of them are compatible because they implement a standard Java Specification called JSR 353 or 374 - Java API for JSON Processing (JSON-P). All libraries that follow this specification are able to parse, generate, transform and query JSON in a standard way and are compatible with the Java Ecosystem. For more information about this specification see jcp.org/en/jsr/detail?id=353 and jcp.org/en/jsr/detail?id=374. Info about the Genson library implementation genson.io