§HTTP リクエストのインターセプト
Play の Java API は、アクション呼び出しをインターセプトする 2 つの方法を提供します。最初の方法は `ActionCreator` と呼ばれ、アクション合成で使用される最初の操作を作成するために使用される `createAction` メソッドを提供します。これは、アクションの実際のメソッドを呼び出す処理を行い、リクエストをインターセプトできます。
2 番目の方法は、独自の `HttpRequestHandler` を実装することです。これは、Play のすべての HTTP リクエストの主要なエントリポイントです。これには、Java と Scala のアクションの両方からのリクエストが含まれます。
§アクションクリエーター
`ActionCreator` インターフェースには、実装できる 2 つのメソッドがあります。
- `createAction`:リクエストと、渡されたリクエストに関連付けられたコントローラーのアクションメソッドを受け取ります。アクションは、設定 `play.http.actionComposition.executeActionCreatorActionFirst` によって、最初のアクションまたは最後のアクションのどちらかになります。
- `wrapAction`:実行するアクションを受け取り、アクションに最終的なグローバルインターセプターを追加できるようにします。このメソッドは、同じことを `createAction` と上記の setting を使用して達成できるため、非推奨となりました。
また、`DefaultActionCreator` インターフェースを拡張してデフォルトの実装を使用することもできます。
注記:実行前にアクションにクロスカット懸念事項を適用する必要があるためカスタム ActionCreator を実装する場合は、フィルター を作成する方がより慣用的な方法です。
カスタムアクションクリエーターを提供するには、`play.http.ActionCreator` を実装する `ActionCreator` という名前のクラスをルートパッケージに作成します。
import java.lang.reflect.Method;
import java.util.concurrent.CompletionStage;
import play.mvc.Action;
import play.mvc.Http;
import play.mvc.Result;
public class ActionCreator implements play.http.ActionCreator {
@Override
public Action createAction(Http.Request request, Method actionMethod) {
return new Action.Simple() {
@Override
public CompletionStage<Result> call(Http.Request req) {
return delegate.call(req);
}
};
}
}
このクラスをルートパッケージに配置したくない場合、または異なる環境に対して異なるアクションハンドラーを設定できるようにしたい場合は、`application.conf` で `play.http.actionCreator` 設定プロパティを設定することでこれを行うことができます。
play.http.actionCreator = "com.example.MyActionCreator"
注記:アクション合成 も使用している場合、`createAction` メソッドによって返されるアクションは、デフォルトではアクション合成アクションの後で実行されます。この順序を変更するには、`application.conf` で `play.http.actionComposition.executeActionCreatorActionFirst = true` に設定します。
§HTTP リクエストハンドラー
アプリケーションには、Play の抽象化では満たされない、より高度なニーズがある場合があります。このような場合、アプリケーションは、Play の最下位レベルの HTTP パイプライン API である `HttpRequestHandler` のカスタム実装を提供できます。
カスタム `HttpRequestHandler` を提供することは、最後の手段である必要があります。ほとんどのカスタムニーズは、カスタムルーターまたは フィルター を実装することで満たすことができます。
§カスタムリクエストハンドラーの実装
`HttpRequestHandler` インターフェースには、`handlerForRequest` という 1 つのメソッドが実装されています。これは、ハンドラーを取得するリクエストを受け取り、`RequestHeader` と `Handler` を含む `HandlerForRequest` インスタンスを返します。
リクエストヘッダーが返される理由は、ルーティング情報などの情報をリクエストに追加できるようにするためです。このようにして、ルーターはリクエストにルーティング情報(どのルートがリクエストに一致したかなど)をタグ付けでき、これは監視やクロスカット機能の注入に役立ちます。
ルーターに委任するだけの非常に単純なリクエストハンドラーは、次のようになります。
import javax.inject.Inject;
import play.api.mvc.Handler;
import play.core.j.JavaHandler;
import play.core.j.JavaHandlerComponents;
import play.http.*;
import play.libs.streams.Accumulator;
import play.mvc.*;
import play.routing.Router;
public class SimpleHttpRequestHandler implements HttpRequestHandler {
private final Router router;
private final JavaHandlerComponents handlerComponents;
@Inject
public SimpleHttpRequestHandler(Router router, JavaHandlerComponents components) {
this.router = router;
this.handlerComponents = components;
}
public HandlerForRequest handlerForRequest(Http.RequestHeader request) {
Handler handler =
router
.route(request)
.orElseGet(() -> EssentialAction.of(req -> Accumulator.done(Results.notFound())));
if (handler instanceof JavaHandler) {
handler = ((JavaHandler) handler).withComponents(handlerComponents);
}
return new HandlerForRequest(request, handler);
}
}
Java ハンドラーのために `JavaHandlerComponents` を注入し、`handler.withComponents` を呼び出す必要があることに注意してください。これは、Java アクションが機能するために必要です。`DefaultHttpRequestHandler` を拡張して `super.handlerForRequest()` を呼び出すと、これも自動的に処理されます。
`HttpRequestHandler` には現在、デフォルトの実装を持つ 2 つのレガシーメソッドがあり、それらは `ActionCreator` に移動されています。
§HTTP リクエストハンドラーの設定
`BuiltInComponents` を使用してアプリケーションを構築する場合は、`httpRequestHandler` メソッドをオーバーライドして、カスタムハンドラーのインスタンスを返します。
ランタイム依存性注入(例:Guice)を使用している場合、リクエストハンドラーはランタイム時に動的にロードできます。最も簡単な方法は、`HttpRequestHandler` を実装する `RequestHandler` という名前のクラスをルートパッケージに作成することです。
リクエストハンドラーをルートパッケージに配置したくない場合、または異なる環境に対して異なるリクエストハンドラーを設定できるようにしたい場合は、`application.conf` で `play.http.requestHandler` 設定プロパティを設定することでこれを行うことができます。
play.http.requestHandler = "com.example.RequestHandler"
このドキュメントに誤りを見つけた場合、このページのソースコードは こちら で確認できます。ドキュメントガイドライン を読んでから、プルリクエストを送信してください。質問やアドバイスを共有したいですか? コミュニティフォーラム にアクセスして、コミュニティと会話を始めましょう。