私は私に交通情報を与えるオープンデータウェブサービスにアクセスしようとします。ドキュメントには、リクエストはGET
である必要があり、_Accept: application/json
_および_Content-Type: application/json
_を含める必要があると記載されています。 _Content-Type
_が必要な理由がわかりませんが、
_Accept:
_ヘッダーだけでデータを取得しようとしましたが、常に_415 Unsupported Media Type
_を取得しています。現在、私は現在この方法を試しています(しかし、本当に両方のヘッダーを正しく設定しているかどうかはわかりません):
_String entity = ClientBuilder.newClient().target(liveDataURI)
.path(liveDataPath)
.request(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.get(String.class);
_
ご覧のとおり、私はJersey 2.2を使用していますが、まだ_415 Unsupported Media Type
_を取得しています。
[〜#〜]編集[〜#〜]
だから私はそれを動作させましたが、なぜかわかりません。 accept(MediaType.APPLICATION_JSON)
とheader("Content-type","application/json")
は同じではありませんか?
_String responseEntity = ClientBuilder.newClient()
.target(liveDataURI)
.path(liveDataPath)
.request(MediaType.APPLICATION_JSON)
.header("Content-type", "application/json")
.get(String.class);
_
Accept
ヘッダーは、クライアントが何を望んでいるかをサーバーに伝えます。 _Content-Type
_ヘッダーは、クライアントがリクエストで送信したものをサーバーに通知します。したがって、この2つは同じではありません。
サーバーが_application/json
_のみを受け入れる場合は、要求の内容を指定する要求を送信する必要があります。
_Content-Type: application/json
_
これが、編集したコードが機能する理由です。
編集
最初のコードでは WebTarget.request(MediaType... acceptedResponseTypes)
を使用します。このメソッドのパラメーター
受け入れられる応答メディアタイプを定義します。
このメソッド呼び出しの結果で Innvocation.Builder.accept(MediaType... mediaTypes)
を使用しています。ただし、accept()
は新しいヘッダーを追加しません。最初のコードでは不要です。
リクエストのコンテンツタイプを指定することはありません。サーバーは_Content-Type
_ヘッダーを想定しているため、_415
_で応答します。
accept(MediaType.APPLICATION_JSON)
とheader("Content-type","application/json")
は同じではありませんか?
いいえ、違います。
これは、それらがどのように関連しているかです。
_Client Server
(header) (class/method annotation)
====================================================
Accept <---> @Produces
Content-Type <---> @Consumes
_
サーバーは、クライアントから受信したものを本文で消費し(その形式は_Content-Type
_で指定されます)、クライアントが受け入れるものを生成します(その形式はAccept
で指定されます)。
例:
Content-Type
_ = _text/xml
_(本文でXMLを送信します)Accept
= _application/json
_(JSONを応答として受け取ることを期待しています)@Consumes(MediaType.TEXT_XML)
(クライアントからXMLを取得します)@Produces(MediaType.APPLICATION_JSON)
(JSONをクライアントに送信します)Obs:
サーバーはより柔軟になり、multiple可能formatsを取得/生成するように構成されます。
例:@Consumes({ MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
アノテーションがある場合、クライアントはXMLを送信できますが、別のクライアントは同じメソッドにJSONを送信できます。
MediaType
値は単なるString
定数です:
_public final static String APPLICATION_JSON = "application/json";
public final static String TEXT_XML = "text/xml";
_
ContainerResponseFilter
を使用して、デフォルトのAcceptヘッダーを入力リクエストで提供されていない場合に設定できます。
@Provider
public class EntityResponseFilter implements ContainerResponseFilter {
private MediaType getExternalMediaType(){
MediaType mediaType = new MediaType("application", "vnd.xxx.resource+json")
return mediaType;
}
@Override
public void filter( ContainerRequestContext reqc , ContainerResponseContext resc ) throws IOException {
MediaType mediaType = getExternalMediaType();
List<MediaType> mediaTypes = reqc.getAcceptableMediaTypes();
if( mediaTypes.contains(mediaType) ) {
resc.setEntity( resc.getEntity(), new Annotation[0], mediaType );
}
// ...
}
}