我正在尝试编写一个插入Play Framework Controller 的JSON解串器,以代替标准的Play JSON库。基本原理是能够直接使用Jackson。多亏了a recipe by Maarten Winkels,我已经能够提出一个可插拔的反序列化器,但是由于我不理解的编译错误,我陷入了困境(免责声明:我是Scala新手)。
编译错误源于以下事实:显然JsonObjectParser.apply
的一个分支试图返回Object
的实例,而应该是Result
。我不明白为什么会这样。我的问题是,如何解决此错误?
编译错误
编译错误如下所示:
/Users/arve/Projects/test/JsonObjectParser.scala:26: type mismatch;
[error] found : Object
[error] required: play.api.mvc.Result
[error] case Left((r, in)) => Done(Left(r), El(in))
JsonObjectParser.scala
这是有问题的源代码:
import java.io.{ByteArrayInputStream, InputStream}
import play.api.Play
import play.api.libs.iteratee.Input._
import play.api.libs.iteratee._
import play.api.mvc._
import scala.concurrent.ExecutionContext.Implicits.global
class JsonObjectParser[A: Manifest](deserializer: (InputStream) => A) extends BodyParser[A] {
val JsonMaxLength = 4096
def apply(request: RequestHeader): Iteratee[Array[Byte], Either[Result, A]] = {
Traversable.takeUpTo[Array[Byte]](JsonMaxLength).apply(Iteratee.consume[Array[Byte]]().map { bytes =>
scala.util.control.Exception.allCatch[A].either {
deserializer(new ByteArrayInputStream(bytes))
}.left.map { e =>
(Play.maybeApplication.map(_.global.onBadRequest(request, "Invalid Json")).getOrElse(
Results.BadRequest), bytes)
}
}).flatMap(Iteratee.eofOrElse(Results.EntityTooLarge))
.flatMap {
case Left(b) => Done(Left(b), Empty)
case Right(it) => it.flatMap {
// Won't compile
case Left((r, in)) => Done(Left(r), El(in))
case Right(a) => Done(Right(a), Empty)
}
}
}
}
或者,
如果你们知道将自定义JSON解串器插入Play的更好方法,那么在Jackson的上方,那也是可以接受的。毕竟,这就是我要在这里做的。
最佳答案
eofOrElse
Iteratee
将前一个Iteratee
的结果包装到Either
中。因为上一个Iteratee的结果已经是Either
,所以最终会得到类似Either[Result, Either[Result, A]]
的内容。调用joinRight
可以将其转换为我们所需的Either[Result, A]
。另外_.global.onBadRequest(request, "Invalid Json")
返回的是Future[SimpleResult]
,而不是SimpleResult
-我已经删除了该代码。
下面,我应用了这些修复程序,并简化了从.left.map
调用返回的元组,并且还使用了transform
而不是apply
来消除最后的flatMap
。
class JsonObjectParser[A: Manifest](deserializer: (InputStream) => A) extends BodyParser[A] {
val JsonMaxLength = 4096
def apply(request: RequestHeader): Iteratee[Array[Byte], Either[SimpleResult, A]] = {
Traversable.takeUpTo[Array[Byte]](JsonMaxLength).transform {
Iteratee.consume[Array[Byte]]().map { bytes =>
scala.util.control.Exception.allCatch[A].either {
deserializer(new ByteArrayInputStream(bytes))
}.left.map { _ =>
Results.BadRequest
}
}
}.flatMap(Iteratee.eofOrElse(Results.EntityTooLarge)).map(_.joinRight)
}
}
关于json - 如何解决此Scala/Play编译错误(返回错误的类型)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24679991/