Rest JAX-RS exception, MessageBodyWriter not found

2019-07-15 08:40发布

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:

enter image description here

3条回答
兄弟一词,经得起流年.
2楼-- · 2019-07-15 09:14

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.

查看更多
▲ chillily
3楼-- · 2019-07-15 09:30

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;
   }
}
查看更多
聊天终结者
4楼-- · 2019-07-15 09:36

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>
查看更多
登录 后发表回答