如何在Play 2.3中执行自定义操作组合以记录请求和响应?
我正在开发Play 2.3(Java)应用程序,我需要一个自定义的Action Composition来记录请求和响应。 到目前为止,我已经得到了请求的主体,但没有回应:
import play.libs.F; import play.mvc.Action; import play.mvc.Http; import play.mvc.Result; public class LogAction extends Action.Simple { public F.Promise call(Http.Context ctx) throws Throwable { //Request body String requestBody = ctx.request().body().asText(); //Need to get response body here //String responseBody = ??? return delegate.call(ctx); } }
如何在这种情况下获得响应主体? 如果在java中很难做到,它也可能在scala中,但它必须使用java控制器方法@With
注释。
@Override public F.Promise call(Http.Context ctx) throws Throwable { Promise call = delegate.call(ctx); return call.map((r) -> { byte[] body = JavaResultExtractor.getBody(r, 0l); Logger.info(new String(body)); return r; }); }
您可以使用play.core.j.JavaResultExtractor
从响应中提取正文。 请记住, getBody(..)
阻塞,直到响应准备就绪,因此请考虑调用onRedeem
而不是map
。
你尝试过这样的事情:
public class VerboseAction extends play.mvc.Action.Simple { public F.Promise call(Http.Context ctx) throws Throwable { Logger.info("Calling action for " + ctx); F.Promise resultPromise = delegate.call(ctx); resultPromise.map(result -> { Logger.info(result.toScala().header().status()); Logger.info(result.toScala().body().toString()); return result; }); return resultPromise; } }
正文将作为play.api.libs.iteratee.Enumerator
返回。 现在困难的部分是使用它。 首先,您需要了解Iteratee
的概念以及Enumerator
在其中扮演的角色。 提示:将Enumerator
视为数据生产者 ,并将Iteratee
视为此数据的使用者 。
现在,在这个Enumerator
您可以运行一个Iteratee
,它将数据块转换为您想要的类型。
坏消息是你需要实现play.api.libs.iteratee.Iteratee
trait。 正如您所看到的,它位于api
子包中,这意味着它是Play中Scala世界的一部分。 也许在这种情况下,你可以更轻松地使用Scala完成这部分任务。 不幸的是,我无法为您提供一些示例实现,但我希望这不会那么难。 我认为这在Play的Java方面确实缺少了。