2016-04-03 7 views
0

JerseyとJacksonを使用してREST Webサービスにアクセスしています。これは正しく作成されたJSONデータを正しく返していますが、 :Acceptに従わないWebサービスを扱う方法:JerseyとJacksonを使用しているapplication/json

コンテンツタイプ:text/html;文字セット= UTF-8

同意指定したにもかかわらず:要求ヘッダーの結果としてアプリケーション/ JSONジャージーをスローする原因となっている。

org.glassfish.jersey.message.internal .MessageBodyProviderNotFoundException:MessageBodyReaderのメディアタイプが見つかりません= text/htmlの;のcharset = UTF-8

私は私のコードで細かい他のWebサービスを消費していますが、私自身のMessageBodyReaderのを作成する方法があるかどうか、私は疑問に思ってミスマッチに対処するために、私はまだ描いていない正しく実装する方法を教えてください。私は、不一致を修正するためにWebサービスの所有者に依頼する予定ですが、私は多くの希望を持っていません。

+0

はどのようにあなたはそれが正しいJSONである知っている結果として、私はMessageBodyReaderのを実装するために以下のクラスを実装していますデータ?生の反応を見ましたか?サーバー側で何らかのエラーが発生したため、HTMLページが出力される可能性があります。サーバーログでエラーが発生しましたか? –

+0

データを取得し、ヘッダを置き換えてさらに処理することができます。しかし、データを取得するだけで、ヘッダーを無視し、jsonオブジェクトに解析するほうが簡単だと思います。 –

+0

Chrome RestClient拡張機能を使用してサービスに手動でアクセスしているので正しいことが分かります。 –

答えて

1

私は基本的にスティーブンCの助言に従うことでそれを理解することができましたが、他の誰かが同じボートに入っている場合には、さらに詳しい情報を投稿すると思いました。まず、私が実際にジャージーから始め、背中のいくつかのセクションを案内し、特にこの1:もちろん、私はjavax.ws.rs.client用ジャージーを使用していますが、私はJSONのデシリアライゼーションを行うにはGensonを使用しています

https://jersey.java.net/documentation/latest/user-guide.html#d0e6825

。それが作成された後、次のように、このクライアントに登録されます

public class BTCEURTradeMessageBodyReader 
     implements MessageBodyReader<BTCEURTrades> { 

    final org.slf4j.Logger logger = 
      LoggerFactory.getLogger(BTCEURTradeMessageBodyReader.class); 

    @Override 
    public boolean isReadable(Class<?> type, Type genericType, 
      Annotation[] annotations, MediaType mediaType) { 
    logger.info("isReadable being checked for: {} and media type: {}", type, mediaType); 
    return type == BTCEURTrades.class; 
    } 

    @Override 
    public BTCEURTrades readFrom(Class<BTCEURTrades> type, Type genericType, 
      Annotation[] annotations, MediaType mediaType, 
      MultivaluedMap<String, String> httpHeaders, InputStream entityStream) 
      throws IOException, WebApplicationException { 
    logger.info("readFrom being called for: {}", type); 

    BTCEURTrades btceurTrades; 
    try { 
     btceurTrades = new Genson().deserialize(entityStream, type); 
    } catch(Exception e) { 
     logger.error("Error processing JSON reponse.", e); 
     throw new ProcessingException("Error processing JSON reponse."); 
    } 
    return btceurTrades; 
    } 

} 

client = ClientBuilder.newClient(); 
client.register(BTCEURTradeMessageBodyReader.class); 
+0

私は途中でジャクソンから変わったと指摘しておきます。 –

+0

なぜジェンソンとのデフォルトのGenson統合を使用しませんでしたか?あなたは物事を記録したいからですか?あなたのインプルメントを守れば。私はGensonを一度しかインスタンス化せずに、そのインスタンスをreadFromの呼び出しごとにインスタンスを作成する代わりに、さまざまなリクエストにわたって再利用することをお勧めします。 – eugen

0

私は自分のMessageBodyReaderを作成して、不一致を処理する方法があるのだろうかと思います。ジャージードキュメントの

このページでは、カスタムのMessageBodyReaderの作成方法について説明します:あなたのケースでは

を、あなたはそのリーダーのためのソースコードを見つけることができるかもしれませんJSONのために通常使用され、それを "微調整"します。理論的には。ジャージーは、すでにJSONを幅広くサポートしていることを私に言っている

はしかし、もう少し読んだ後、私はこれを見つけました。ジャージーが珍しいコンテンツタイプで何をすべきかを知っておくために、設定を微調整するだけで問題を解決できる可能性があります。しかし、これは、JSONレスポンスの本文を解析する可能性のあるさまざまな方法のうちのどれに依存しますか...現時点では。


誰かはこのようにコメントした:

は、しかし私は、より簡単だと思うだけで、データを取得し、ヘッダを無視し、ちょうどあなたのJSONオブジェクトにそれを解析します。

これは悪い考えです。ヘッダーは、JSONにマルチバイト文字が含まれている可能性があることを伝えています。単純に無視し、デフォルトの文字セットの文字をバイトにデコードすると、マルチバイト文字が存在する場合は「mojibake」となります。

あなた自身でJSONを解析している場合は、UTF-8を使用するようにパーサーの入力ストリームを設定するか、コンテンツタイプヘッダーに文字エンコーディングがあると言うものを設定するのは簡単です。


最後に、「誰が間違っているか」の問題があります。

私は実際にあなたのせいだと思っています。 「Accept:application/json」ヘッダーだけを送信した場合は、文字セットが何であるか気にしないことをサーバーに伝えます。サーバーは、応答テキストを正しく表すことがわかっている応答の文字セットを自由に選択できます。 (この場合、JSONのテキストコンテンツ)

具体的には、ASCIIまたはLatin-1が必要な場合は、「Accept-charset:」ヘッダーを追加する必要があります。

>> THAT < <が動作しない場合は、おそらくサーバーの不具合です。しかし、応答があなたの好みの文字セットでエンコードできない文字を含んでいるなら、サーバはあなたに406エラーを送るかもしれません。

関連する問題