Scala 播放[2.5.x]自定义主体解析器以获取原始主体,并将其与请求捆绑在一起
我有一个post请求,其中包含一个hmac头,我需要将主体与之匹配。这个头是使用请求的原始主体创建的,我没有办法更改它。请求的内容类型是application/json。目前似乎没有办法访问请求的原始主体以及json编码的请求主体,因此我尝试创建一个自定义主体解析器和操作,将原始主体和原始请求捆绑在一起并传递它们 我试图复制这个家伙的实现,但它是2.5版之前的版本,所以使用迭代对象而不是akka流 以下是我到目前为止的情况: BodyParser和Case类Scala 播放[2.5.x]自定义主体解析器以获取原始主体,并将其与请求捆绑在一起,scala,playframework,playframework-2.5,Scala,Playframework,Playframework 2.5,我有一个post请求,其中包含一个hmac头,我需要将主体与之匹配。这个头是使用请求的原始主体创建的,我没有办法更改它。请求的内容类型是application/json。目前似乎没有办法访问请求的原始主体以及json编码的请求主体,因此我尝试创建一个自定义主体解析器和操作,将原始主体和原始请求捆绑在一起并传递它们 我试图复制这个家伙的实现,但它是2.5版之前的版本,所以使用迭代对象而不是akka流 以下是我到目前为止的情况: BodyParser和Case类 object RequestArch
object RequestArchiver {
case class RawRequest[A](request: Request[A], raw: ByteString) extends WrappedRequest[A](request)
case class WrappedPayload[A](wrapped: A, raw: ByteString)
def wrappedBodyParser[B](wrapped: BodyParser[B]) (implicit exCtx: ExecutionContext): BodyParser[WrappedPayload[B]] =
BodyParser("raw-memo") { (request: RequestHeader) =>
val raw: Accumulator[ByteString, Either[Result, RawBuffer]] = BodyParsers.parse.raw(request)
val ret = raw.map {
case Left(result) =>
Left(result)
case Right(buffer: RawBuffer) =>
val bytes = buffer.asBytes().getOrElse(ByteString.empty)
Right(WrappedPayload(wrapped(request), bytes))
}
ret
}
}
这不会编译时出错
Error:(33, 5) type mismatch;
found : play.api.libs.streams.Accumulator[akka.util.ByteString,Product with Serializable with scala.util.Either[play.api.mvc.Result,controllers.RequestArchiver.WrappedPayload[play.api.libs.streams.Accumulator[akka.util.ByteString,Either[play.api.mvc.Result,B]]]]]
required: play.api.libs.streams.Accumulator[akka.util.ByteString,Either[play.api.mvc.Result,controllers.RequestArchiver.WrappedPayload[B]]]
ret
^
现在我明白了这是想告诉我什么,我知道我只是不知道如何修复它。我想解决方案在链接中victorops示例的第15行和第24行之间,但我不知道如何将这些行转换为2.5版本
在重要情况下的自定义操作
def extractRaw[A](parser: BodyParser[A])(block: (RawRequest[A]) => Future[Result])(implicit ctx: ExecutionContext) =
Action.async(RequestArchiver.wrappedBodyParser(parser)) { implicit request =>
val rawRequest = RawRequest(Request(request, request.body.wrapped), request.body.raw)
block(rawRequest)
}
我是新手,但是如何使用更简单的
raw
body解析器呢。我做了一个快速测试
class Tester extends Controller {
def handleRaw = Action(parse.raw) { implicit request =>
request.body.asBytes().map(b => Ok(s"Request body has ${b.size} bytes")).getOrElse(NoContent)
}
}
curl-v——数据“a=b&c=d”http://localhost:9000/test/raw
* Trying ::1...
* Connected to localhost (::1) port 9000 (#0)
> POST /test/raw HTTP/1.1
> Host: localhost:9000
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Length: 7
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 7 out of 7 bytes
< HTTP/1.1 200 OK
< Content-Length: 85
< Content-Type: text/plain; charset=utf-8
< Date: Mon, 15 Aug 2016 09:41:30 GMT
<
Request body has 7 bytes
* Connection #0 to host localhost left intact
*正在尝试::1。。。
*已连接到本地主机(::1)端口9000(#0)
>POST/test/raw HTTP/1.1
>主机:localhost:9000
>用户代理:curl/7.43.0
>接受:*/*
>内容长度:7
>内容类型:application/x-www-form-urlencoded
>
*上传已完全发送:7个字节中有7个