简体   繁体   中英

Obtaining “MessageBodyWriter not found for media type=application/json” trying to send JSON object through JAX-RS web service

I am trying to send a JSON object through a JAX-RS web service. My file web.xml is:

<servlet>
 <description>JAX-RS Tools Generated - Do not modify</description>
 <servlet-name>JAX-RS Servlet</servlet-name>
 <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
  <init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>it.notifire</param-value>
  </init-param>
  <init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>JAX-RS Servlet</servlet-name>
  <url-pattern>/jaxrs/*</url-pattern>
</servlet-mapping>

The class that models the object I want to send is:

public class GPSCoordinate {

private float latitudine;
private float longitudine;

 public float getLatitudine() {
    return latitudine;
}
public void setLatitudine(float latitudine) {
     this.latitudine = latitudine;
}
public float getLongitudine() {
    return longitudine;
}
public void setLongitudine(float longitudine) {
    this.longitudine = longitudine;
}
}

The root class resource is:

@Path("position")
public class Position {

    @Context
private UriInfo context;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public GPSCoordinate getHTML() {

        GPSCoordinate coord = new GPSCoordinate();
        coord.setLatitudine(90.45f);
        coord.setLongitudine(34.56f);

        return coord;
    }
}

Now, when i try to access the service I point my browser to the following link

http://localhost:8080/Notifire/jaxrs/position

and i get the following error:

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

In my WEB-INF/lib folder I have the last release of jersey JAX-RS implementation (jaxrs-ri-2.5.jar) and the jersey-json.jar archive.

Any help would be much appreciated.

Try adding Genson to your classpath, it will automatically enable JSON support.

Genson is a data-binding and streaming library for json and java/scala. It implements the extension points MessageBodyReader/Writer of JAX-RS, allowing jersey to automatically detect Genson and use it for Json parsing/writing.

You can find some more infos about Gensons integration with JaxRS (jersey & cie).

Jersey supports 'autodiscoverable' features and JSON support is one of them. In order to enable it, you need to add a compatible library to your path, according to the docs

However, while the recommended jersey-media-json-processing library has not been recognized in my case for some reason, jersey-media-moxy has:

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

2.15 has been the latest version at the time of writing. Visit the maven central artifact page to find the current version.

Register the JacksonJsonProvier class with the client config and then create the Client object, this worked for me. Below is the code.

    ClientConfig config = new ClientConfig();
    config.register(JacksonJsonProvider.class);
    Client client = ClientBuilder.newClient(config);

This is how I solved the issue.

Used Jackson. Added these jars 在此输入图像描述

Added this Class to my project. The key lines of the code are marked IMPORTANT.

import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; <-- IMPORTANT
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;

//@javax.ws.rs.ApplicationPath("webresources")
public class MyApplicationConfig extends Application {

@Override
public Set<Class<?>> getClasses() {
    Set<Class<?>> resources = new java.util.HashSet<Class<?>>();
    //addRestResourceClasses(resources);
    //resources.add(MultiPartFeature.class);
    //resources.add(JettisonFeature.class);
    return resources;
}

@Override
public Set<Object> getSingletons() {
    final Set<Object> instances = new HashSet<Object>();

    instances.add(new JacksonJsonProvider()); <--------- IMPORTANT
    return instances;
}
/**
 * Do not modify addRestResourceClasses() method.
 * It is automatically populated with
 * all resources defined in the project.
 * If required, comment out calling this method in getClasses().
 */
private void addRestResourceClasses(Set<Class<?>> resources) {
    //resources.add(org.glassfish.jersey.media.multipart.MultiPartProperties.Feature.MultiPartContextResolver.class);
    //resources.add(org.glassfish.jersey.media.multipart.MultiPartProperties.Feature.MultiPartContextResolver.class);

}

}

My root cause was slightly different. I spent some time debugging Jersey source code, and it turned out that it fails to construct a JAXBContext due to missing default constructor in my JAXB class. It happens during the search for a suitable MessageBodyWriter, but the exception is not handled.

Here is the corresponding code snippet (MOXyJsonProvider:324):

try {
    Set<Class<?>> domainClasses = getDomainClasses(genericType);
    return getJAXBContext(domainClasses, annotations, mediaType, null);
} catch(JAXBException e) {
    return null;
}

So, if you have the Moxy JSON dependency in POM, double-check that your JAXB classes are valid.

Versions that I'm using: Jersey 2.19, Moxy 2.6.0.

Go to https://jersey.java.net/documentation/2.5.1/user-guide.html#json

You need to complete your Class.... JAXB needs that, example:

@XmlRootElement
public class MyJaxbBean {

    @XmlElement(name="king")
    public String name;

    @XmlTransient
    public int age;

    // several lines removed
}

It worked for me by adding all required jackson Jars. Added these jars

  • jackson-annotations-2.8.7.jar,
  • jackson-core-2.8.7.jar
  • jackson-databind-2.8.7.jar
  • jackson-jaxrs-base-2.8.7.jar
  • jackson-jaxrs-json-provider-2.8.3.jar
  • jackson-module-jaxb-annotations-2.8.7.jar

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM