我正在使用书籍Reactive Web Applications: Covers Play, Akka, and Reactive Streams切断我的牙齿。第4章,除其他外,教授如何编写过滤器,但本书中显示的代码无法编译,因为在Play 2.4.x中,Enumerator[Array[Byte]]
曾经是play.api.http.HttpEntity
而在2.5中。 x是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)
在书中:
<!DOCTYPE html>
<html>
<head>
<title>Autofresh</title>
<link rel="stylesheet" type="text/css" href="styles/styles.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript" >
window.onload;
function detectmob() {
if( navigator.userAgent.match(/Android/i)
|| navigator.userAgent.match(/webOS/i)
|| navigator.userAgent.match(/iPhone/i)
|| navigator.userAgent.match(/iPad/i)
|| navigator.userAgent.match(/iPod/i)
|| navigator.userAgent.match(/BlackBerry/i)
|| navigator.userAgent.match(/Windows Phone/i)
){
return true;
}
else {
return false;
}
}
if(detectmob()){
window.alert('success');
$("#content").width("100%");
} else {
window.alert('fail');
}
</script>
</head>
<body>
<div id="content" class="mcontent">
<div id="header">
//image goes here
<div id="navbar">
</div>
</div>
<div id="video"></div>
<div id="registration">
</div>
</div>
</body>
</html>
正如您所看到的,我的过滤器版本可以正常工作,但它阻碍了未来。我想知道是否有更好的方法可以不阻塞地执行此操作?
P.S。:在将我的问题视为重复之前,请注意我已阅读以下所有主题并将响应主体转换为字符串,这不是我想要的。
Scala play http filters: how to find the request body
Play framework filter that modifies json request and response
答案 0 :(得分:2)
如果你想避免Await.result
,你可以这样做:
nextFilter(rh).flatMap { result =>
...
maybeNewBody map { newBody =>
result.copy(body = Strict(newBody, contentType))
}
} else Future.successful(result)
(请注意map
更改为flatMap
)