26

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.

amedeo avogadro
  • 595
  • 2
  • 7
  • 14

7 Answers7

52

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

eugen
  • 5,856
  • 2
  • 29
  • 26
  • 5
    It is a data-binding and streaming library for json. It also implements the extension points MessageBodyReader/Writer of JAX-RS and declares its impl with Javas service loader mechanism, allowing jersey (and others) to automatically detect Genson and use it for Json parsing/writing. – eugen Feb 14 '14 at 09:07
  • 1
    Do you know how to do the same with XML ? I need to technically understand what you are saying, could you recommend a book or a tutorial other than Jersey's user-guide (v2.5.1) ? I get lost when I start reading it ! – Muhammad Gelbana Feb 15 '14 at 09:57
  • If you want to produce xml [here](http://www.mkyong.com/webservices/jax-rs/download-xml-with-jersey-jaxb/) is a quick example how to do it with jersey. Concerning how Genson is getting wired with jersey you can read [this](http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html), this is the basic mechanism proposed by java to provide extension points – eugen Feb 15 '14 at 16:31
  • thanks a lot. it worked for me. awesome.. greate help – Lahiru Cooray Aug 22 '15 at 17:12
  • Thank you very much. I still don't understand why this works and all other libraries with "Auto-Discoverable Features” doesn't work, even if I tried using maven and registering classes myself in web.xml... – fatihpense Nov 03 '15 at 18:30
9

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.

kostja
  • 60,521
  • 48
  • 179
  • 224
  • Thanks for the suggestion. It solved my problem. I see that this dependency has added few **org.eclipse.persistence.*** dependencies in the project. Are these required? – Taher May 26 '15 at 08:35
  • I went through the code. It uses the MOXyJsonProvider class and other classes from that package. So i guess that is fine. – Taher May 26 '15 at 08:49
  • @Taher - you're welcome :) as for the dependencies - they are transitive dependencies for moxy & antlr - take a look at the dependency list: http://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-moxy/2.15 – kostja May 26 '15 at 08:50
  • Looking at the package **org.eclipse.***, my first instinct told me, am I adding some redundant jars (which could be IDE specific, as i use Eclipse for development), but then did some digging around to found the dependencies. Went through the dependency list too that clears everything. Had been trying a couple of things and found another alternate solution with json-jackson. org.glassfish.jersey.media jersey-media-json-jackson 2.17 – Taher May 26 '15 at 10:32
8

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);
lakshmanas
  • 119
  • 1
  • 1
  • I think that's the problem in the most cases. If automatic registering doesn't work you should try to register it, manually. – PAX May 25 '19 at 12:51
  • This worked for me, just incase this helps someone, also added: org.glassfish.jersey.media jersey-media-moxy – jawn Sep 15 '22 at 20:41
5

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

}

}
bickster
  • 1,292
  • 17
  • 18
  • It's 2023 and this was the missing link in my 3 day problem. -_- I had to Load the resources manually like here and then load the `JacksonJsonProvider` (The missing link) before it could run. – Dark Star1 May 22 '23 at 14:16
2

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.

jFrenetic
  • 5,384
  • 5
  • 42
  • 67
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
}
rink.attendant.6
  • 44,500
  • 61
  • 101
  • 156
0

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