I am using Jersey 2.13
I get MessageBoddyWriter not found exception when I try to access a resource via a url in a browser.
Exception:
MessageBodyWriter not found for media type=application/json,
type=class java.util.ArrayList, genericType=java.util.List<com.webservices.entity.Book>.
I have another method that produces "APPLICATION_XML" and that seems to work fine.
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Book {
@XmlElement
private String name;
@XmlElement
private String author;
//getters setters
}
@GET
@Path("/json")
@Produces(MediaType.APPLICATION_JSON)
public List<Book> getJsonResponse(JAXBElement<Book> book){
return new ArrayList<Book>();
}
My thought was jersey would automatically find the "JacksonJsonProvider"
, a message writer class, provided by Jackson but it doesn't.
My lib folder:
According to mkyong jersey+jackson tutorial, you need to add com.sun.jersey.api.json.POJOMappingFeature param in your web.xml to integrate them
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.mkyong.rest</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>
Starting with Jersey 2.9, automatic discovery of converter classes has been disabled. You have to register the converter class of your JSON library with Jersey manually. Here is what I do (I'm using Genson):
@ApplicationPath( "/api/library" )
public class RestService extends Application {
@Override
public Set<Class<?>> getClasses( ) {
final Set<Class<?>> returnValue = new HashSet<Class<?>>( );
returnValue.add( GensonJsonConverter.class );
return returnValue;
}
}
If you want to make your application code support both xml and json you need to create a wrapper object to support the collection rather than returning a GenericType. The PojoMappingFeature will work as it uses the native Jackson ObjectMapper instead of using the jaxb annotations for marshalling the object.
If you want it to be portable the best solution is to create a simple wrapper object as such.
@XmlRootElement
public class Books {
private List<Book> books;
public Books() {
}
public Books(List<Book> books) {
this.books = books;
}
@XmlElement(name="book")
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> books) {
this.books = books;
}
}
@GET
@Path("/json")
@Produces(MediaType.APPLICATION_JSON)
public Books getJsonResponse(JAXBElement<Book> book){
return new Books(new ArrayList<Book>());
}
If you decide you want to also support MediaType.APPLICATION_XML then this is required. This will also solve the json (jackson) problem.