http の結果を変更する際にも同様のケースがありました。Java でこれに対処するための私のアプローチを共有したいと思います。
Play 2.0.3 の Scala ソース コードを調べたところ、 Java でクラスplay.core.j.JavaResultExtractor
のレスポンス ボディ、Cookie、ヘッダー、およびステータスを取得し、レスポンス ボディの内容を書き込むことができることがわかりました。Result
play.core.j.JavaResults
それにもかかわらず、現在のレスポンスボディを変更されたボディに簡単に置き換える方法はまだわかりません。おそらく、これを Scala の実装で扱う方が簡単かもしれませんが、それでも Scala は難解すぎて読めないことがわかりました :-(
私が見つけた方法play.mvc.Results.Status
は、 を使用しplay.core.j.JavaResults
てコンテンツ本文を記述する方法を確認することです。私が言及したクラスはok()
、 、notFound()
、 、およびJava のクラスで生成するforbidden()
他の同様のメソッドの中心です。このクラスの実装は次のようになります: (読みやすくするために Scala クラスをリファクタリングしました)Result
Controller
// scala classes
import play.api.mvc.Codec;
import play.api.mvc.Content;
import play.core.j.JavaResults;
// ...
public static class Status implements Result {
final private play.api.mvc.Result wrappedResult;
// ...
// there are a lot of constructors for this class to reference from
// this particular constructor is the general approach for most cases
public Status(play.api.mvc.Results.Status status, Content content, Codec codec) {
// ...
wrappedResult = status.apply(
content,
JavaResults.writeContent(codec),
JavaResults.contentTypeOf(content.contentType() + "; charset=" + codec.charset())
);
}
}
上記のコードを実装する場合は、play.api.mvc.Content
インターフェースも実装する必要があります。全体として、私が言ったことからコードを実装すると、次のようになります。
import play.api.mvc.Codec;
import play.api.mvc.Content;
import play.core.j.JavaResultExtractor;
import play.core.j.JavaResults;
// ...
public static class GZipResult extends Action<GZip> {
@Override
public Result call(Http.Context ctx) throws Throwable {
Result result = delegate.call(ctx);
if (requestSupportsGZip(ctx)) {
// copy parts of current response
final int statusCode = JavaResultExtractor.getStatus(result);
final Map<String,String> headers = JavaResultExtractor.getHeaders(result);
final byte[] body = JavaResultExtractor.getBody(result);
// create a gzip result
result = new GZipResult(statusCode, new String(body), headers.get("Content-Type"));
// add appropriate headers here
// ...
}
return result;
}
}
private static class GZipResult implements Result {
final private play.api.mvc.Result wrappedResult;
public GZipResult(final int StatusCode, final String content, final String contentType) {
if(content == null) throw new NullPointerException("null content");
// i guess this is the good place in transforming the content body
String gzippedContent = someMethodToGzipContent(content);
this.wrappedResult = JavaResults.Status(statusCode).apply(
// implement the play.api.mvc.Content interface
new Content() {
@Override public String body() { return gzippedContent; }
@Override public String contentType() { return contentType; }
},
JavaResults.writeContent(Codec.utf_8),
JavaResults.contentTypeOf(contentType))
);
}
// ...
}
上記の実装により、http の結果を変更できます。これがあなたの特定のユースケースに役立つことを願っています。
乾杯!
アップデート
上記のコードは、http の結果を変更する際のほとんどのユースケースを解決できます。あなたの特定のケース、つまり gzip 応答では、gzip された本体が in にbyte[]
ないため、別のアプローチが必要String
です。このplay.mvc.Results.Status
クラスは、処理のメソッドも提供しbyte[]
ます。実装は次のようになります。
// scala classes
import play.core.j.JavaResults;
// ...
public static class Status implements Result {
final private play.api.mvc.Result wrappedResult;
// ...
public Status(play.api.mvc.Results.Status status, byte[] content) {
// ...
wrappedResult = status.apply(
content,
JavaResults.writeBytes(),
JavaResults.contentTypeOfBytes()
);
}
}
私の更新前の私の実装に基づいて、コードにこれを行う方法を理解できます。もう実装する必要はなくplay.api.mvc.Content
、応答で適切な content-type を返すようにしてください。
幸せなコーディング:-)