web-dev-qa-db-ja.com

Jersey例外:重大:Javaクラスのメッセージ本文リーダー

JSONを出力するJerseyベースのRest WSがあります。 WSを呼び出してJSON応答を消費するために、Jersey Clientを実装しています。私が持っているクライアントコードは以下です

 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 [] 。クラス);

2行目はJSON文字列応答を正しく出力しますが、JSONをPOJOにマーシャリングする3行目は発生せず、次の例外スタックトレースを取得します

 SEVERE:Java class [Lorg.shoppingsite.model.entity.jpa.User;]のメッセージ本文リーダー、およびJava typeクラス[Lorg.shoppingsite.model.entity.jpa.User ;、およびMIMEメディアタイプapplication/jsonが見つかりませんでした
 2011年12月21日11:32:01 AM com.Sun.jersey.api.client.ClientResponse getEntity 
 SEVERE:MIMEメディアタイプと互換性のある登録済みのメッセージボディリーダーは、
 */*-> 
 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.provi der.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アノテーションが付けられています。私は何が欠けています。

ありがとうございました

35
VDev

Jersey-jsonのMaven依存関係を追加することで問題を修正できました。

29
VDev

動作させるために必要なものは2つだけです。不足しているかどうかを確認します。

  1. まず、オブジェクトクラス/エンティティに@ XmlRootElementアノテーションが必要です。
  2. 不足している場合は、jersey-jsonの依存関係を追加する必要があります。参考のために、この依存関係をpom.xmlに追加しました。

    <dependency>
        <groupId>com.Sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.17.1</version>
    </dependency>
    
27
user2139024

これを置いて

    <init-param>
        <param-name>com.Sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>

私はこの投稿が古いことを知っており、あなたはずっと前にこれを理解しましたが、これをしばらく読んでくれる人を救うためだけです。

おそらく、エンドポイントに渡すエンティティに注釈を追加するのを忘れたため、Jerseyは受信したPOJOを処理する方法を知りません。次のようなものでpojoに注釈を付けます。

@XmlRootElement(name = "someName")

Uberjarまたは "shaded jar"を構築している場合は、meta infサービスファイルがマージされていることを確認してください。 (これは、dropwizardプロジェクトで何度も噛みつきました。)

Gradle shadowJarプラグインを使用している場合は、shadowJarターゲットでmergeServiceFiles()を呼び出します。 https://github.com/johnrengelman/shadow#merging-service-ファイル

Mavenやその他のビルドシステム用の類似のコマンドが何かわからない。

8
mooreds

また、ジャージをソリューションとして使用することも決定しました。しかし、ほとんどの場合にorg.JSONを使用しているため、この依存関係は不要であり、良くないと感じました。

したがって、文字列表現を使用して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;
4
Jens Peters

クラスの開始前にPOJOに以下の行を追加するだけで、問題は解決します。 @Produces( "application/json")@XmlRootElement例を参照import javax.ws.rs.Produces; import javax.xml.bind.annotation.XmlRootElement;

 /**
 * @author manoj.kumar
 * @email [email protected]
 */
 @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!!!
3
mkumar0304

私の場合、私は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>
3
James.G

追加してみてください:

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

また、メッセージ本文でHTTP GETを使用している場合にもこの問題が発生する可能性があるため、この場合はjersey-json lib、@XmlRootElementの追加、またはweb.xmlの変更は役に立ちません。 URL QueryParamまたはHTTP POSTを使用する必要があります。

2
Justas

Eclipseで異なるインスタンスを実行しているかどうかを確認してください。他のすべてのセッションを終了し、クリーンビルドで問題を修正しました

0
gibsosmart

独自のMessageBodyReaderMessageBodyWriterをクラスに実装する必要がありますLorg.shoppingsite.model.entity.jpa.User

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;
}
0
alex347

Jersey-json jarを追加してもこの問題を解決できない理由が混同される場合があります。このjarはjersey-json-1.7.jarよりも新しい必要があることがわかりました(1.7.0は動作しませんが、1.7.1は正常に動作します)。これが役立つことを願って

0
Nick Liu