文件

§攔截 HTTP 要求

Play 的 Java API 提供兩種攔截動作呼叫的方式。第一種稱為 ActionCreator,它提供一個 createAction 方法,用於建立動作組合中使用的初始動作。它會處理呼叫動作的實際方法,這允許您攔截請求。

第二種方式是實作您自己的 HttpRequestHandler,這是 Play 中所有 HTTP 請求的主要進入點。這包括來自 Java 和 Scala 動作的請求。

§動作建立器

ActionCreator 介面有兩個可以實作的方法

還有一個 DefaultActionCreator 介面,您可以使用預設實作來延伸它。

注意:如果您正在實作自訂 ActionCreator,因為您需要在執行動作之前對動作套用橫切關注,建立 篩選器 是達成相同目的的更慣用的方式。

可以透過在根目錄套件中建立一個名為 ActionCreator 的類別來提供自訂動作建立器,該類別實作 play.http.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。這會取得請求以取得處理常式,並傳回一個包含 RequestHeaderHandlerHandlerForRequest 實例。

傳回請求標頭的原因是為了讓資訊(例如路由資訊)可以新增到請求中。透過這種方式,路由器可以標記請求並加上路由資訊,例如哪個路由與請求相符,這對於監控或甚至注入橫切功能很有用。

一個非常簡單的請求處理常式,僅委派給路由器,可能如下所示

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);
  }
}

請注意,我們需要注入 JavaHandlerComponents 並呼叫 handler.withComponents 以取得 Java 處理常式。這是 Java 動作運作的必要條件。如果您延伸 DefaultHttpRequestHandler 並呼叫 super.handlerForRequest(),這也會自動為您處理。

請注意,HttpRequestHandler 目前有兩個具有預設實作的舊版方法,這些方法已移至 ActionCreator

§設定 http 要求處理程式

如果您使用 BuiltInComponents 來建構應用程式,請覆寫 httpRequestHandler 方法,以傳回自訂處理程式的執行個體。

如果您使用執行時期依賴性注入 (例如 Guice),可以在執行時期動態載入要求處理程式。最簡單的方法是在根目錄建立一個稱為 RequestHandler 的類別,並實作 HttpRequestHandler

如果您不想將要求處理程式放在根目錄,或者您想要能夠為不同的環境設定不同的要求處理程式,您可以透過設定 application.conf 中的 play.http.requestHandler 設定屬性來執行此操作

play.http.requestHandler = "com.example.RequestHandler"

下一步:非同步 HTTP 編寫程式


在此文件當中發現錯誤?此頁面的原始程式碼可在此處找到 here。在閱讀 文件指南 後,歡迎您貢獻一個 Pull Request。有問題或建議要分享?請前往 我們的社群論壇,與社群展開對話。