48.3. アプリケーションの応答の微調整

48.3.1. 応答構築の基本

概要

RESTful サービスでは、リソースメソッドがプレーンな Java コンストラクトを返す場合に、コンシューマーへ返される応答をより正確に制御する必要があります。JAX-RS Response クラスを使用すると、リソースメソッドがコンシューマーに送信される戻り値をある程度制御し、応答に HTTP メッセージヘッダーとクッキーを指定できます。

Response オブジェクトは、コンシューマーに返されるエンティティーを表すオブジェクトをラップします。Response オブジェクトは ResponseBuilder クラスをファクトリーとして使用してインスタンス化されます。

ResponseBuilder クラスには、応答のメタデータを操作するために使用されるメソッドも多数あります。たとえば、ResonseBuilder クラスには、HTTP ヘッダーとキャッシュ制御ディレクティブを設定するメソッドが含まれます。

応答と応答ビルダーの関係

Response クラスには保護されたコンストラクターがあるため、直接インスタンス化することはできません。これらは、Response クラスによって囲まれた ResponseBuilder クラスを使用して作成されます。ResponseBuilder クラスは、そこから作成された応答にカプセル化されるすべての情報のホルダーです。ResponseBuilder クラスには、メッセージに HTTP ヘッダープロパティーを設定するすべてのメソッドもあります。

Response クラスは、適切な応答コードの設定とエンティティーのラップを容易にするメソッドを提供します。一般的な応答ステータスコードごとにメソッドがあります。エンティティー本体または必要なメタデータを含むステータスに対応するメソッドには、関連する応答ビルダーに、情報を直接設定できるバージョンが含まれています。

ResponseBuilder クラスの build() メソッドは、メソッドが呼び出される際に応答ビルダーに保存されている情報が含まれる応答オブジェクトを返します。応答オブジェクトが返されると、応答ビルダーはクリーンな状態に戻ります。

応答ビルダーの取得

応答ビルダーを取得する方法は 2 つあります。

  • Response クラスを使用した応答ビルダーの取得 に示すように、Response クラスの静的メソッドを使用します。

    Response クラスを使用した応答ビルダーの取得

    import javax.ws.rs.core.Response;
    
    Response r = Response.ok().build();

    この方法で応答ビルダーを取得すると、複数の手順で操作できるインスタンスに、アクセスできなくなります。すべてのアクションを単一のメソッド呼び出しに配列する必要があります。

  • Apache CXF 固有の ResponseBuilderImpl クラスの使用。このクラスを使用すると、応答ビルダーを直接操作できます。ただし、すべての応答ビルダーの情報を手動で設定する必要があります。

    例48.1「ResponseBuilderImpl クラスを使用した応答ビルダーの取得」は、ResponseBuilderImpl クラスを使用して Response クラスを使用した応答ビルダーの取得 を書き換える方法を表しています。

    例48.1 ResponseBuilderImpl クラスを使用した応答ビルダーの取得

    import javax.ws.rs.core.Response;
    import org.apache.cxf.jaxrs.impl.ResponseBuilderImpl;
    
    ResponseBuilderImpl builder = new ResponseBuilderImpl();
    builder.status(200);
    Response r = builder.build();
    注記

    Response クラスのメソッドから返される ResponseBuilderResponseBuilderImpl オブジェクトに割り当てることもできます。

補足情報

Response クラスの詳細は、Response クラスの Javadoc を参照してください。

ResponseBuilder クラスの詳細は、ResponseBuilder クラスの Javadoc を参照してください。

Apache CXF ResponseBuilderIml クラスの詳細は、ResponseBuilderImpl Javadoc を参照してください。

48.3.2. 一般的なユースケースに対する応答の作成

概要

Response クラスは、RESTful サービスが必要とするより一般的な応答を処理するためのショートカットメソッドを提供します。これらのメソッドは、提供された値またはデフォルト値のいずれかを使用して適切なヘッダーの設定を処理します。また、必要に応じてエンティティーボディーの設定を処理します。

正常な要求の応答作成

要求が正常に処理されると、アプリケーションが応答を送信して、要求が完了したことを確認する必要があります。この応答にはエンティティーが含まれる可能性があります。

応答を正常に完了した場合の最も一般的な応答は OK です。OK 応答には通常、リクエストに対応するエンティティーが含まれます。Response クラスには、応答のステータスを 200 に設定し、指定されたエンティティーを囲まれた応答ビルダーに追加するオーバーロードされた ok() メソッドがあります。ok() メソッドには 5 つのバージョンがあります。最も一般的に使用されるバリアントは以下のとおりです。

  • Response.ok() - 200 のステータスおよび空のエンティティーボディーでレスポンスを作成します。
  • Response.ok(java.lang.Object entity) - 200 のステータスで応答を作成し、指定されたオブジェクトを応答エンティティーボディーに保存します。また、オブジェクトのイントロスペクションによるエンティティーメディア型を決定します。

200 応答での応答の作成 は、OK ステータスで応答を作成する例を示しています。

200 応答での応答の作成

import javax.ws.rs.core.Response;
import demo.jaxrs.server.Customer;
...

Customer customer = new Customer("Jane", 12);

return Response.ok(customer).build();

要求元がエンティティーボディーを期待しない場合は、200 OK のステータスではなく 204 No Content ステータスを送信する方が適切な場合があります。Response.noContent() メソッドにより、適切な応答オブジェクトが作成されます。

204 ステータスでの応答の作成 は、204 ステータスで応答を作成する例を示しています。

204 ステータスでの応答の作成

import javax.ws.rs.core.Response;

return Response.noContent().build();

リダイレクトの応答の作成

Response クラスは、3 つのリダイレクト応答ステータスを処理するメソッドを提供します。

303 See Other

303 See Other ステータスは、リクエストされたリソースが要求を処理するためにコンシューマーを新しいリソースに永続的にリダイレクトする必要がある場合に便利です。

Response クラスの seeOther() メソッドは、303 のステータスで応答を作成し、新しいリソース URI をメッセージの Location フィールドに配置します。seeOther() メソッドは、新しい URI を java.net.URI オブジェクトとして指定する単一のパラメーターを取ります。

304 Not Modified

304 Not Modified ステータスは、リクエストの性質に応じてさまざまなものに使用できます。前回の GET リクエスト以降、要求されたリソースが変更されていないことを示すことができます。リソース変更要求で、リソースが変更されなかったと示すために使用することもできます。

Response クラスの notModified() メソッドは 304 ステータスで応答を作成し、HTTP メッセージに変更された日付プロパティーを設定します。notModified() メソッドには 3 つのバージョンがあります。

  • notModified
  • notModifiedjavax.ws.rs.core.Entitytag
  • notModifiedjava.lang.Stringtag
307 Temporary Redirect

307 Temporary Redirect ステータスは、要求されたリソースがコンシューマーを新しいリソースに転送する必要があるものの、このリソースを引き続き使用して今後の要求を処理する場合に役立ちます。

Response クラスの temporaryRedirect() メソッドは、307 のステータスで応答を作成し、新しいリソース URI をメッセージの Location フィールドに配置します。temporaryRedirect() メソッドは、新しい URI を java.net.URI オブジェクトとして指定する単一のパラメーターを取ります。

304 ステータスでの応答の作成 は、304 ステータスで応答を作成する例を示しています。

304 ステータスでの応答の作成

import javax.ws.rs.core.Response;

return Response.notModified().build();

エラーを示す応答の作成

Response クラスは、2 つの基本的な処理エラーに対する応答を作成するメソッドを提供します。

  • serverError - 500 Internal Server Error のステータスでレスポンスを作成します。
  • notAcceptablejava.util.List<javax.ws.rs.core.Variant>variants - 406 Not Acceptable ステータスと、許容可能なリソース型の一覧が含まれるエンティティーボディーでレスポンスを作成します。

500 ステータスでの応答の作成 は、500 ステータスで応答を作成する例を示しています。

500 ステータスでの応答の作成

import javax.ws.rs.core.Response;

return Response.serverError().build();

48.3.3. より高度な応答の処理

概要

Response クラスメソッドは、一般的なケースの応答を作成するためのショートカットを提供します。キャッシュ制御ディレクティブの指定、カスタム HTTP ヘッダーの追加、または Response クラスで処理されていないステータスの送信など、より複雑なケースに対応する必要がある場合は、build() メソッドを使用してレスポンスオブジェクトを生成する前に、ResponseBuilder クラスメソッドを使用してレスポンスを入力する必要があります。

「応答ビルダーの取得」 で説明されているように、Apache CXF ResponseBuilderImpl クラスを使用して直接操作できるレスポンスビルダーインスタンスを作成できます。

カスタムヘッダーの追加

カスタムヘッダーは、ResponseBuilder クラスの header() メソッドを使用してレスポンスに追加されます。header() メソッドは、2 つのパラメーターを取ります。

  • name - ヘッダー名を指定する文字列
  • value - ヘッダーに格納されたデータを含む Java オブジェクト

header() メソッドを繰り返し呼び出すと、メッセージに複数のヘッダーを設定することができます。

応答へのヘッダーの追加 は、応答にヘッダーを追加するコードを示します。

応答へのヘッダーの追加

import javax.ws.rs.core.Response;
import org.apache.cxf.jaxrs.impl.ResponseBuilderImpl;

ResponseBuilderImpl builder = new ResponseBuilderImpl();
builder.header("username", "joe");
Response r = builder.build();

クッキーの追加

カスタムヘッダーは、ResponseBuilder クラスの cookie() メソッドを使用してレスポンスに追加されます。cookie() メソッドは 1 つ以上のクッキーを取ります。各クッキーは javax.ws.rs.core.NewCookie オブジェクトに保存されます。最も簡単に使用できる NewCookie クラスのコンストラクターは、2 つのパラメーターを取ります。

  • name - クッキーの名前を指定する文字列
  • value - クッキーの値を指定する文字列

cookie() メソッドを繰り返し呼び出して、複数のクッキーを設定できます。

応答へのクッキーの追加 は、クッキーを応答に追加するコードを示します。

応答へのクッキーの追加

import javax.ws.rs.core.Response;
import javax.ws.rs.core.NewCookie;

NewCookie cookie = new NewCookie("username", "joe");

Response r = Response.ok().cookie(cookie).build();

警告

null パラメーターリストで cookie() メソッドを呼び出すと、すでに応答に関連付けられているクッキーが消去されます。

応答ステータスの設定

Response クラスのヘルパーメソッドでサポートされないステータスを返す場合は、ResponseBuilder クラスの status() メソッドを使用してレスポンスのステータスコードを設定することができます。status() メソッドには 2 つのバリアントがあります。1 つは、レスポンスコードを指定する int を取ります。もう 1 つは Response.Status オブジェクトを取り、応答コードを指定します。

Response.Status クラスは、Response クラスで囲まれた列挙型です。定義されたほとんどの HTTP 応答コードに、エントリーがあります。

応答へのヘッダーの追加 に、応答ステータスを 404 Not Found に設定するコードを示します。

応答へのヘッダーの追加

import javax.ws.rs.core.Response;
import org.apache.cxf.jaxrs.impl.ResponseBuilderImpl;

ResponseBuilderImpl builder = new ResponseBuilderImpl();
builder.status(404);
Response r = builder.build();

キャッシュ制御ディレクティブの設定

ResponseBuilder クラスの cacheControl() メソッドを使用すると、レスポンスにキャッシュ制御ヘッダーを設定することができます。cacheControl() メソッドは、応答のキャッシュ制御ディレクティブを指定する javax.ws.rs.CacheControl オブジェクトを取ります。

CacheControl クラスには、HTTP 仕様でサポートされるすべてのキャッシュ制御ディレクティブに対応するメソッドがあります。ディレクティブが簡単な on または off の値である場合、setter メソッドは boolean の値を取ります。ディレクティブは max-age ディレクティブなどの数値が必要であるため、setter は int の値を取ります。

応答へのヘッダーの追加 は、no-store キャッシュ制御ディレクティブを設定するコードを表しています。

応答へのヘッダーの追加

import javax.ws.rs.core.Response;
import javax.ws.rs.core.CacheControl;
import org.apache.cxf.jaxrs.impl.ResponseBuilderImpl;

CacheControl cache = new CacheControl();
cache.setNoCache(true);

ResponseBuilderImpl builder = new ResponseBuilderImpl();
builder.cacheControl(cache);
Response r = builder.build();