Я режу зубы на Play, используя книгу Reactive Web Applications: Covers Play, Akka, and Reactive Streams. Глава 4, помимо прочего, учит писать фильтр, но код, показанный в книге, не компилируется, потому что в Play 2.4.x Result.body
используется как Enumerator[Array[Byte]]
, а в 2.5.x это play.api.http.HttpEntity
.Play Framework: Как изменить тело ответа без блокировки?
Моя версия фильтра, как показано ниже:
class ScoreFilter @Inject()(implicit val mat: Materializer, ec: ExecutionContext) extends Filter {
override def apply(nextFilter: (RequestHeader) => Future[Result])(rh: RequestHeader) =
nextFilter(rh).map { result =>
if (result.header.status == OK || result.header.status == NOT_ACCEPTABLE) {
val correct = result.session(rh).get("correct").getOrElse(0)
val wrong = result.session(rh).get("wrong").getOrElse(0)
val score = s"\nYour current score is: $correct correct " +
s"answers and $wrong wrong answers"
val contentType = result.body.contentType
val scoreByteString = ByteString(score.getBytes(UTF_8))
val maybeNewBody = result.body.consumeData.map(_.concat(scoreByteString))
import scala.concurrent.duration._
val newBody = Await.result(maybeNewBody, 10 seconds)
result.copy(body = Strict(newBody, contentType))
} else {
result
}
}
}
В книге:
// result.body returns a play.api.http.HttpEntity which doesn't have an andThen method
val newBody = result.body andThen Enumerator(score.getBytes(UTF_8))
result.copy(body = newBody)
Как вы можете видеть, моя версия фильтра работает, но он блокирует на будущее. Мне интересно, есть ли лучший способ сделать это без блокировки?
P.S .: Прежде чем уволить мой вопрос как дубликат, имейте в виду, что я прочитал все следующие потоки, и они преобразуют тело ответа в строку, чего я не хочу.
Scala play http filters: how to find the request body
Play framework filter that modifies json request and response
Play 2.4: intercept and modify response body
Это работает, но мне нужно изменить тело на «Строгий». Мне любопытно, можно ли этого избежать, используя 'Iteratees' и' Enumerators'? –
Единственными опциями для 'HttpEntity' являются' Strict', 'Streamed' и' Chunked'. согласно документации, 'Strict' - это то, что вы хотите здесь, так как у вас есть содержимое в памяти: https://playframework.com/documentation/2.5.2/api/java/play/http/HttpEntity.html – handler
Вот что я Однако я думал, что в фильтре мы всегда будем знать тип тела. Как вы сказали, есть 3. Я послал по электронной почте автора Мануэля Бернхардта. Будет опубликован здесь, если он предоставит альтернативу. Тем временем я приму свой ответ. –