MessageBodyWriter not found for media type=application/json

JavaRestJerseyJax Rs

Java Problem Overview


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.

Java Solutions


Solution 1 - Java

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>

Solution 2 - Java

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()
    {
    }
}

Solution 3 - Java

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.

Solution 4 - Java

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.

Solution 5 - Java

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>

Solution 6 - Java

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()
    {
    }

Solution 7 - Java

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

Solution 8 - Java

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.

Solution 9 - Java

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

Solution 10 - Java

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

Solution 11 - Java

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFahad MullajiView Question on Stackoverflow
Solution 1 - JavaAlicia TangView Answer on Stackoverflow
Solution 2 - Javaasad.qaziView Answer on Stackoverflow
Solution 3 - JavaamessView Answer on Stackoverflow
Solution 4 - JavaSaurabh ThakurView Answer on Stackoverflow
Solution 5 - JavaomilusView Answer on Stackoverflow
Solution 6 - JavaDu-LacosteView Answer on Stackoverflow
Solution 7 - JavasajanView Answer on Stackoverflow
Solution 8 - JavaJediCateView Answer on Stackoverflow
Solution 9 - JavaJainender ChauhanView Answer on Stackoverflow
Solution 10 - JavaBadr KenzallahView Answer on Stackoverflow
Solution 11 - JavaAlexander TerpView Answer on Stackoverflow