Severe: Messagebodywriter Not Found for Media Type=Application/JSON, Type=Class Com.Jersey.Jaxb.Todo, Generictype=Class Com.Jersey.Jaxb.Todo

SEVERE: MessageBodyWriter not found for media type=application/json, type=class com.jersey.jaxb.Todo, genericType=class com.jersey.jaxb.Todo

You have jackson-jaxrs-json-provider which is a start..

But...

that artifact is still dependent on Jacskon itself, which includes all these artifacts

Sample Image

That's why we use Maven[1] (so we don't have to worry about this kind of thing :-). So go find these.

Then just add the package to the web.xml, and it should work

<param-name>jersey.config.server.provider.packages</param-name>
<param-value>
com.jersey.jaxb,
com.fasterxml.jackson.jaxrs.json
</param-value>

1. Maven dependency

<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.2.3</version>
</dependency>

Or use the below Jersey "wrapper" for the above dependency. It will register the Jackson providers (so we don't need to explicitly register like above), and the Jackson exception mappers, and start from version 2.17, provides support for Entity Data Filtering.

<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey2.version}</version>
</dependency>

Note: The fact that we don't have to register anything with the above dependency, is made possible through the Auto-discovery feature of Jersey. If we for some reason disable the auto-discovery, you will want to explicitly register the JacksonFeature.

How to resolve MessageBodyWriter not found?

Using custom media/mime type and serializing/deserializing the received or sent object according to the new media type.

It just requires a class with "@Provider" annotation and a "@Produces". The produces annotation will be written as: @Produces({"application/customType.v1+json", "application/json"}).

With a constructor/method having Object mapper serialization and deserialization.

NOTE: Keep this class in the package where all API classes are.

Example Code:

@Provider
@Produces({MediaType.APPLICATION_JSON, "application/customType.v1+json"})
public class JacksonJsonProvider extends JacksonJaxbJsonProvider {

public JacksonJsonProvider() {

ObjectMapper objectMapper = new ObjectMapper()
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.registerModule(new JodaModule())
.setDateFormat(new RFC3339DateFormat());

setMapper(objectMapper);
}
}

MessageBodyWriter not found for media type=application/json with GF4 and Jackson

Unfortunately my last post was marked as duplicate although the problem and the solution was different. Therefore I'm posting a new question with the two solutions to hopefully help you avoid head banging at the table for several hours.

Preferred solution:

Apparently GF4 ships with MoxyJson which I didn't want to use. To integrate your own dependency - in my case Jackson - you need to disable the MoxyJson with the below code.

@ApplicationPath("/")
public class ApplicationConfig extends Application {

/**
* {@inheritDoc}
*/
@Override
public Map<String, Object> getProperties() {
final Map<String, Object> properties = new HashMap<String, Object>();
properties.put("jersey.config.server.disableMoxyJson", true);

return properties;
}
}

Then add your own dependencies, e.g. in my case only those two because the others are referenced by another lib I use.

<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.6.2</version>
</dependency>

Finally I made the mistake of not setting a value to the @JsonProperty annotations which will cause a No MessageBodyWriter found exception. To avoid that use the following ony relevant getters of your class.

@JsonProperty("randomName")
public String getRandomName(){
...
}

Alternative:

Worse than above you'll need to disable MoxyJson, register each service individually, and fix a Bug when using ResourceConfig of GF.

@ApplicationPath("/")
public class ApplicationConfig extends ResourceConfig {

/**
* The default constructor.
*/
public ApplicationConfig() {

// Disable Moxy and use Jackson
this.property(ServerProperties.MOXY_JSON_FEATURE_DISABLE, true);

// Register own provider classes
this.register(Fully.Qualified.Path.To.Your.Service.class);

// Register Jackson provider
// Workaround for GF4.1 bug for details: https://java.net/jira/browse/GLASSFISH-21141
final ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JaxbAnnotationModule());
this.register(new JacksonJaxbJsonProvider(mapper, JacksonJaxbJsonProvider.DEFAULT_ANNOTATIONS));
}
}

You'll need an additional dependency for the ResourceConfig class.

 <dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.6.2</version>
</dependency>

<dependency>
<groupId>org.glassfish.main.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>4.1.1</version>
<scope>provided</scope>
</dependency>

Finally the same as above - be aware to use @JsonProperty with a set value.

MessageBodyWriter not found for media type=application/xml

Do you have the jaxb dependency in your project?

<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-jaxb</artifactId>
<version>x.x.x</version>
</dependency>

If yes, perhaps you could try to wrap the exception.getErrors() (which appears to be a Map?) into a GenericEntity and giving that entity to the response:

GenericEntity<Map<?, ?>> entity = new GenericEntity..

return Response.status(Status.X).entity(entity).type(MediaType.APPLICATION_XML).build();


Related Topics



Leave a reply



Submit