Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 430
amedeo avogadro Avatar asked Dec 24 '13 13:12

amedeo avogadro


5 Answers

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

like image 132
eugen Avatar answered Nov 14 '22 02:11

eugen


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.

like image 44
kostja Avatar answered Nov 14 '22 03:11

kostja


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);
like image 8
lakshmanas Avatar answered Nov 14 '22 01:11

lakshmanas


This is how I solved the issue.

Used Jackson. Added these jars enter image description here

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

}

}
like image 4
bickster Avatar answered Nov 14 '22 02:11

bickster


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.

like image 2
jFrenetic Avatar answered Nov 14 '22 01:11

jFrenetic