Obtaining "MessageBodyWriter not found for media type=application/json" trying to send JSON object through JAX-RS web service
Solution 1
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).
Solution 2
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.
Solution 3
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);
Solution 4
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);
}
}
Solution 5
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.
amedeo avogadro
Updated on May 15, 2020Comments
-
amedeo avogadro almost 4 years
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.