簡體   English   中英

播放2.5:在自定義http操作中獲取響應正文

[英]Play 2.5: get response body in custom http action

我正在嘗試創建一個自定義的http操作( https://playframework.com/documentation/2.5.x/JavaActionsComposition ),以使用Play 2.5.0 Java記錄請求和響應正文。 到目前為止,這是我得到的:

public class Log extends play.mvc.Action.Simple {

    public CompletionStage<Result> call(Http.Context ctx) {
        CompletionStage<Result> response = delegate.call(ctx);
        //request body is fine
        System.out.println(ctx.request().body().asText())
        //how to get response body string here while also not sabotaging http response flow of the framework?
        //my guess is it should be somehow possible to access it below?
        response.thenApply( r -> {
            //???
            return null;
        });
        return response;
    }

}

日志記錄通常被認為是跨領域的功能。 在這種情況下,在Play中執行此操作的首選方法是使用過濾器:

過濾器API旨在解決不加區分地應用於所有路徑的交叉問題。 例如,以下是一些常見的過濾器用例:

  • 記錄/指標收集
  • GZIP編碼
  • 安全頭

這對我有用:

import java.util.concurrent.CompletionStage;
import java.util.function.Function;
import javax.inject.Inject;
import akka.stream.*;
import play.Logger;
import play.mvc.*;

public class LoggingFilter extends Filter {

    Materializer mat;

    @Inject
    public LoggingFilter(Materializer mat) {
        super(mat);
        this.mat = mat;
    }

    @Override
    public CompletionStage<Result> apply(
            Function<Http.RequestHeader, CompletionStage<Result>> nextFilter,
            Http.RequestHeader requestHeader) {
        long startTime = System.currentTimeMillis();
        return nextFilter.apply(requestHeader).thenApply(result -> {
            long endTime = System.currentTimeMillis();
            long requestTime = endTime - startTime;

            Logger.info("{} {} took {}ms and returned {}",
                requestHeader.method(), requestHeader.uri(), requestTime, result.status());
            akka.util.ByteString body = play.core.j.JavaResultExtractor.getBody(result, 10000l, mat);
            Logger.info(body.decodeString("UTF-8"));

            return result.withHeader("Request-Time", "" + requestTime);
        });
    }
}

到底在做什么

首先,這將創建一個新的過濾器,該過濾器可與您可能擁有的其他過濾器一起使用。 為了獲取響應的主體,我們實際上使用nextFilter一旦獲得響應,我們就可以獲取主體。

從Play 2.5開始, Akka Streams是首選武器。 這意味着,一旦使用JavaResultExtractor ,您將獲得一個ByteString ,然后必須對其進行解碼才能獲取下面的真實字符串。


請記住,在您創建的Action中復制此邏輯應該沒有問題。 由於帖子頂部所述的原因,我只選擇了Filter選項。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM