首页 文章

Jersey异常:SEVERE:Java类的消息体阅读器

提问于
浏览
33

我有一个基于 Jersey 的Rest WS输出JSON . 我正在实现一个Jersey客户端来调用WS并使用JSON响应 . 我的客户端代码如下

WebResource r = restClient.resource(UriBuilder.fromUri("http://localhost/").port(8080).build());
String resp = r.path("/user").accept(MediaType.APPLICATION_JSON).get(String.class);
User[] users = r.path("/user").accept(MediaType.APPLICATION_JSON).get(User[].class);

第二行正确输出JSON字符串响应,但第3行将JSON编组到POJO没有发生,我得到以下异常堆栈跟踪

SEVERE: A message body reader for Java class [Lorg.shoppingsite.model.entity.jpa.User;, and Java type class [Lorg.shoppingsite.model.entity.jpa.User;, and MIME media type application/json was not found
Dec 21, 2011 11:32:01 AM com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: The registered message body readers compatible with the MIME media type are:
*/* ->
  com.sun.jersey.core.impl.provider.entity.FormProvider
  com.sun.jersey.core.impl.provider.entity.StringProvider
  com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
  com.sun.jersey.core.impl.provider.entity.FileProvider
  com.sun.jersey.core.impl.provider.entity.InputStreamProvider
  com.sun.jersey.core.impl.provider.entity.DataSourceProvider
  com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
  com.sun.jersey.core.impl.provider.entity.ReaderProvider
  com.sun.jersey.core.impl.provider.entity.DocumentProvider
  com.sun.jersey.core.impl.provider.entity.SourceProvider$StreamSourceReader
  com.sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader
  com.sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader
  com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$General
  com.sun.jersey.core.impl.provider.entity.EntityHolderReader

我的请求中有正确的MIME类型 . 我的POJO已使用XMLRootElement注释 . 我错过了什么

谢谢

13 回答

  • 10

    我能够通过为jersey-json添加maven依赖来解决这个问题 .

  • -3

    为了使它工作,你只需要两件事 . 检查您是否遗失:

    • 首先,您需要为对象类/实体添加 @XmlRootElement 注释 .

    • 如果缺少,则需要为 jersey-json 添加依赖项 . 作为参考,我将此依赖项添加到我的pom.xml中 .

    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.17.1</version>
    </dependency>
    
  • 4

    就这么说吧

    <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>
    
  • 3

    我知道这篇文章已经很久了,你很久以前就已经知道了这一点,但只是为了挽救那些读过这篇文章的人 .

    您可能忘记将注释添加到要传递给 endpoints 的实体,因此Jersey不知道如何处理它收到的POJO . 用这样的东西注释pojo:

    @XmlRootElement(name = "someName")
    
  • 25

    如果要构建uberjar或“阴影jar”,请确保合并了meta inf服务文件 . (这在一个dropwizard项目中多次出现 . )

    如果您使用的是gradle shadowJar插件,则需要在 shadowJar 目标中调用 mergeServiceFiles()https://github.com/johnrengelman/shadow#merging-service-files

    不确定maven或其他构建系统的类似命令是什么 .

  • 10

    我们还决定使用平针织作为解决方案 . 但是,由于我们在大多数情况下使用org.JSON,这种依赖是不必要的,我们觉得不好 .

    因此,我们使用String表示来获取org.JSON对象,而不是

    JSONObject output = response.getEntity(JSONObject.class);
    

    我们现在用这种方式:

    JSONObject output = new JSONObject(response.getEntity(String.class));
    

    其中JSONObject来自org.JSON,并且可以从以下位置更改导入:

    -import org.codehaus.jettison.json.JSONArray;
    -import org.codehaus.jettison.json.JSONException;
    -import org.codehaus.jettison.json.JSONObject;
    +import org.json.JSONArray;
    +import org.json.JSONException;
    +import org.json.JSONObject;
    
  • 3

    就我而言,我正在使用POJO . 我忘了将POJOMappingFeature配置为true . 梅康在早期的回答中指出了这一点 . 但是有些人可能无法在web.xml中正确配置它,这是我的例子 .

    <servlet>
        <servlet-name>Jersey Servlet</servlet-name>
        <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
        <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>
    
  • 29

    只需在课程开始前在POJO中添加以下行,您的问题就会得到解决 . @Produces(“application / json”)@XmlRootElement参见示例import javax.ws.rs.Produces; import javax.xml.bind.annotation.XmlRootElement;

    /**
     * @author manoj.kumar
     * @email kumarmanoj.mtech@gmail.com
     */
     @Produces("application/json")
     @XmlRootElement  
     public class User {
    
     private String username;
     private String password;
     private String email;
     public String getUsername() {
     return username;
     }
     public void setUsername(String username) {
         this.username = username;
     }
     public String getPassword() {
         return password;
     }
     public void setPassword(String password) {
         this.password = password;
     }
     public String getEmail() {
        return email;
     }
     public void setEmail(String email) {
        this.email = email;
     }
    
    }
    add below lines inside of your web.xml
    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>  
    Now recompile your webservice everything would work!!!
    
  • 8

    尝试添加:

    <dependency>
        <groupId>com.owlike</groupId>
        <artifactId>genson</artifactId>
        <version>1.4</version>
    </dependency>
    

    如果您使用 HTTP GET 与消息正文,也可能会出现此问题,因此在这种情况下添加jersey-json lib, @XmlRootElement 或修改web.xml将无济于事 . 您应该使用URL QueryParamHTTP POST .

  • 0

    您需要为您的 class Lorg.shoppingsite.model.entity.jpa.User 实现自己的 MessageBodyReaderMessageBodyWriter .

    package javax.ws.rs.ext;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Type;
    import javax.ws.rs.WebApplicationException;
    import javax.ws.rs.core.MediaType;
    import javax.ws.rs.core.MultivaluedMap;
    
    public interface MessageBodyReader<T extends Object> {
    
        public boolean isReadable(Class<?> type, 
            Type genericType, 
            Annotation[] annotations, 
            MediaType mediaType);
    
        public T readFrom(Class<T> type, 
            Type genericType, 
            Annotation[] annotations, 
            MediaType mediaType, 
            MultivaluedMap<String, String> httpHeaders, 
            InputStream entityStream) throws IOException, WebApplicationException;
    }
    
    package javax.ws.rs.ext;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Type;
    import javax.ws.rs.WebApplicationException;
    import javax.ws.rs.core.MediaType;
    import javax.ws.rs.core.MultivaluedMap;
    
    public interface MessageBodyWriter<T extends Object> {
    
        public boolean isWriteable(Class<?> type, 
            Type genericType, 
            Annotation[] annotations, 
            MediaType mediaType);
    
        public long getSize(T t, 
            Class<?> type, 
            Type genericType, 
            Annotation[] annotations, 
            MediaType mediaType);
    
        public void writeTo(T t, 
            Class<?> type, 
            Type genericType, 
            Annotation[] annotations, 
            MediaType mediaType, 
            MultivaluedMap<String, Object> httpHeaders, 
            OutputStream entityStream) throws IOException, WebApplicationException;
    }
    
  • 2

    只需检查您是否在eclipse中运行不同的实例 . 我退出了所有其他会话,清理构建修复了问题

  • 0

    有些人可能会混淆为什么添加jersey-json jar无法解决这个问题 . 我发现这个jar比jersey-json-1.7.jar更新(1.7.0不起作用,但1.7.1工作正常 . ) . 希望这可以提供帮助

  • 0

    我的情况类似 . 我在关键时刻得到这个错误,我不记得以前我是如何解决它的,我做了很多次 . 经过长时间的检查,我已经解决并重现了错误,并确定了解决这种情况的简单方法 .

    好的 - 解决方案: remove (or correct) any newly made changes to your main project's properties files.

    是的,就是这样 . 事实上,我的项目是一个多模块的巨大的项目,你知道没有正确的依赖是一个罕见的情况,因为经常从git(RAC)获取 . 我的项目几乎所有可配置的东西都来自一个属性文件,这个文件大约有15个左右的模块(子项目),它们之间具有大量的内部依赖性 . jersey-json的依赖总是存在于我合并的父pom中 . XML注释不是问题,因为项目在修改后运行了大约100次 . 这里的一些解决方案指向web.xml和POJOMappingFeature之类的东西 . 在我的情况下,我甚至没有触及此版本中的webapp模块 . 所以无论如何,这个解决方案对我有用,我花时间在SO中记录这个以防万一我碰巧遇到这个错误,我不必浪费我昏昏欲睡的夜晚 . (当然,也适合你)

相关问题