我会很感激,如果有人可以扔在如何修改以下游戏框架日志过滤器的指针(参考玩过滤器实现以下):
- 打印和修改传入的JSON请求本体和HTTP报头(例如,用于POST,PUT和补丁)
- 打印和修改卸任JSON响应体和HTTP头
- 的变形例,可以注入/在请求和响应主体替换某些令牌字符串,例如
- REQUEST JSON:{ '一个': 'REPLACE_ME', 'B': 'REPLACE_ME_TOO', 'C': '东西'}
- RESPONSE JSON:{ 'A': 'REPLACE_ME', 'B-B': 'REPLACE_ME_TOO', 'C': '什么'}
import play.api.Logger
import play.api.mvc._
import play.api.libs.concurrent.Execution.Implicits.defaultContext
object LoggingFilter extends EssentialFilter {
def apply(nextFilter: EssentialAction) = new EssentialAction {
def apply(requestHeader: RequestHeader) = {
val startTime = System.currentTimeMillis
nextFilter(requestHeader).map { result =>
val endTime = System.currentTimeMillis
val requestTime = endTime - startTime
Logger.info(s"${requestHeader.method} ${requestHeader.uri}" +
s" took ${requestTime}ms and returned ${result.header.status}")
result.withHeaders("Request-Time" -> requestTime.toString)
}
}
}
}
到目前为止,我曾尝试以下解决方案,这显然是丑陋和残酷的,因为它包含阻塞调用和神秘的运营商。 我仍然不知道如何重新注入修改请求主体。 (所提出的解决方案采用了从码2和3 )。
import play.api.libs.iteratee._
import play.api.mvc._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Await, Future}
import scala.concurrent.duration.Duration
class ReqResFilter extends EssentialFilter {
def apply(next: EssentialAction) = new EssentialAction {
def apply(requestHeader: RequestHeader): Iteratee[Array[Byte], Result] = {
modifyRequest(next, requestHeader).map { result => modifyResponse(result)}
}
}
def bytesToString: Enumeratee[Array[Byte], String] = Enumeratee.map[Array[Byte]] { bytes => new String(bytes)}
def modifyRequest(nextA: EssentialAction, request: RequestHeader): Iteratee[Array[Byte], Result] = {
def step(body: Array[Byte], nextI: Iteratee[Array[Byte], Result])(i: Input[Array[Byte]]):
Iteratee[Array[Byte], Result] = i match {
case Input.EOF =>
val requestBody = new String(body, "utf-8")
val modRequestBody = requestBody.replaceAll("REPLACE_ME", "1224")
println(s"modifyRequest:: Here is the request body ${modRequestBody}")
Iteratee.flatten(nextI.feed(Input.EOF))
case Input.Empty =>
Cont[Array[Byte], Result](step(body, nextI) _)
case Input.El(e) =>
val curBody = Array.concat(body, e)
Cont[Array[Byte], Result](step(curBody, Iteratee.flatten(nextI.feed(Input.El(e)))) _)
}
val nextIteratee: Iteratee[Array[Byte], Result] = nextA(request)
Cont[Array[Byte], Result](i => step(Array(), nextIteratee)(i))
}
def modifyResponse(result: Result): Result = {
val responseBodyFuture: Future[String] = result.body |>>> bytesToString &>> Iteratee.consume[String]()
val responseBody = Await.result(responseBodyFuture, Duration.Inf)
val modResponseBody = responseBody.replaceAll("REPLACE_ME", "1224")
println(s"modifyResponse:: Here is the response body ${modResponseBody}")
new Result(result.header, Enumerator(modResponseBody.getBytes)).withHeaders("New-Header" -> "1234")
}
}