MessageBodyWriter not found for media type=application/json

I am facing issues while consuming JAX-RS services as JSON.

Below I have added my code.

This is my service class:

//Sets the path to base URL + /hello
@Path("/hello")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class Hello {


@GET
@Produces("application/json")
public Student getStudent() {


Student s = new Student();
s.first_name = "Test First Name !!!";
s.last_name = "Test Last Name!!!";


return s;
}

Student class which I am trying to get from service:

@XmlRootElement
public class Student implements Serializable {


public String first_name;
public String last_name;


public String getFirst_name() {
return first_name;
}


public void setFirst_name(String first_name) {
this.first_name = first_name;
}


public String getLast_name() {
return last_name;
}


public void setLast_name(String last_name) {
this.last_name = last_name;
}


public Student()
{
first_name = "Fahad";
last_name = "Mullaji";
}
}

Web XML on service side.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>com.vogella.jersey.first</display-name>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<!-- Register resources and providers under com.vogella.jersey.first package. -->
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.vogella.jersey.first</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>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>

I don't know how to fix this issue. I am using SOAP UI for testing JSON response but I guess that it should not matter.

Many places I read that I need to add the code below. But I don't know where. I am not using Maven for building.

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

Server is looking for function to parse Student object to JSON but it is not able to find function or jar file for it. I have added jar of Genson, Moxy, RESTEasy and Jackson but I think that's the problem. I think I am missing mapping somewhere.

148723 次浏览

I was able to fix it by install jersey-media-json-jackson

Add the dependency to pom.xml

<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<scope>runtime</scope>
</dependency>

I was in the same situation where
- I was not using Maven or Ant,
- I finished this Vogella tutorial on Jersey,
- and I was getting the MessageBodyWriter error when trying to use @Produces(MediaType.APPLICATION_JSON).

This answer by @peeskillet solves the problem - you have to use the Jackson *.jar files that are available from the FasterXML Jackson Download page. You'll need the core files as well as the jaxrs files.

I added them to my WebContent/WEB-INF/lib folder where I have my Jersey *.jar files per the above tutorial, and made the small change to the web.xml file below (again, as originally shared by @peeskillet):

<param-name>jersey.config.server.provider.packages</param-name>
<param-value>
your.other.package.here, com.fasterxml.jackson.jaxrs.json
</param-value>

The important part being com.fasterxml.jackson.jaxrs.json.

Uncommenting the below code helped

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

which was present in pom.xml in my maven based project resolved this error for me.

You've to create empty constructor because JAX-RS initializes the classes... Your constructor must have no arguments:

@XmlRootElement
public class Student implements Serializable {


public String first_name;
public String last_name;


public String getFirst_name() {
return first_name;
}


public void setFirst_name(String first_name) {
this.first_name = first_name;
}


public String getLast_name() {
return last_name;
}


public void setLast_name(String last_name) {
this.last_name = last_name;
}


public Student()
{
first_name = "Fahad";
last_name = "Mullaji";
}




public Student()
{
}
}

I think may be you should try to convert the data to json format. It can be done by using gson lib. Try something like below.

I don't know it is a best solutions or not but you could do it this way.It worked for me

example : `

@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response info(@HeaderParam("Accept") String accept) {
Info information = new Info();
information.setInfo("Calc Application Info");
System.out.println(accept);
if (!accept.equals(MediaType.APPLICATION_JSON)) {
return Response.status(Status.ACCEPTED).entity(information).build();
} else {
Gson jsonConverter = new GsonBuilder().create();
return Response.status(Status.ACCEPTED).entity(jsonConverter.toJson(information)).build();
}
}

Below should be in your pom.xml above other jersy/jackson dependencies. In my case it as below jersy-client dep-cy and i got MessageBodyWriter not found for media type=application/json.

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

To overcome this issue try the following. Worked for me.

Add following dependency in the pom.xml

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

And make sure Model class contains no arg constructor

 public Student()
{
}

In my experience this error is pretty common, for some reason jersey sometimes has problems parsing custom java types. Usually all you have to do is make sure that you respect the following 3 conditions:

  1. you have jersey-media-json-jackson in you pom.xml if using maven or added to your build path;
  2. you have an empty constructor in the data type you are trying to de-/serialize;
  3. you have the relevant annotation at the class and field level for your custom data type (xmlelement and/or jsonproperty);

However, I have ran into cases where this just was not enough. Then you can always wrap you custom data type in a GenericEntity and pass it as such to your ResponseBuilder:

GenericEntity<CustomDataType> entity = new GenericEntity<CustomDataType>(myObj) {};
return Response.status(httpCode).entity(entity).build();

This way you are trying to help jersey to find the proper/relevant serialization provider for you object. Well, sometimes this also is not enough. In my case I was trying to produce a text/plain from a custom data type. Theoretically jersey should have used the StringMessageProvider, but for some reason that I did not manage to discover it was giving me this error:

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

So what solved the problem for me was to do my own serialization with jackson's writeValueAsString(). I'm not proud of it but at the end of the day I can deliver an acceptable solution.

Ensure that you have following JARS in place: 1) jackson-core-asl-1.9.13 2) jackson-jaxrs-1.9.13 3) jackson-mapper-asl-1.9.13 4) jackson-xc-1.9.13

You have to convert the response to JSON using Gson.toJson(object).

For example:

return Response.status(Status.OK).entity(new Gson().toJson(Student)).build();

My preferred alternative to pulling in the jersey-media-json-jackson dependency other answers are mentioning is to instead register JacksonJsonProvider with your Jersey ResourceConfig:

import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
import org.glassfish.jersey.server.ResourceConfig;


...


ResourceConfig myResourceConfig = new ResourceConfig();
myResourceConfig.register(JacksonJsonProvider.class);

The Javadoc on JacksonJsonProvider explains:

Basic implementation of JAX-RS abstractions (MessageBodyReader,
MessageBodyWriter) needed for binding JSON ("application/json")
content to and from Java Objects ("POJO"s).


Actual data binding functionality is implemented by ObjectMapper:
mapper to use can be configured in multiple ways:


By explicitly passing mapper to use in constructor
By explictly setting mapper to use by setMapper
By defining JAX-RS Provider that returns ObjectMappers.
By doing none of above, in which case a default mapper instance is
constructed (and configured if configuration methods are called)


The last method ("do nothing specific") is often good enough; explicit passing
of Mapper is simple and explicit; and Provider-based method may make sense
with Depedency Injection frameworks, or if Mapper has to be configured differently
for different media types.


Note that the default mapper instance will be automatically created if
one of explicit configuration methods (like configure)
is called: if so, Provider-based introspection is NOT used, but the
resulting Mapper is used as configured.


Note: version 1.3 added a sub-class (JacksonJaxbJsonProvider) which
is configured by default to use both Jackson and JAXB annotations for configuration
(base class when used as-is defaults to using just Jackson annotations)

(as it suggests, you can alternatively use JacksonJaxbJsonProvider).

Can confirm, that I had this exact error for about a week-long, I added the dependency listed above and lombok, @Data. What this does is insert all getters, setters, empty constructor, and complete constructors. More-or-less, if you are working with a big JSON response it can cause a massive problem. Also, this ensures that the other classes that you built if objects are coming or dates are parsed correctly. LET THE COMPUTER DO THE WORK.

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

This worked for me.