【发布时间】:2014-07-13 04:01:26
【问题描述】:
我正在尝试编写一个插入 Play Framework 控制器的 JSON 反序列化器,以代替标准的 Play JSON 库。理由是能够直接使用杰克逊。感谢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)
}
}
}
}
或者,
如果你们知道在 Jackson 之上将自定义 JSON 反序列化器插入 Play 的更好方法,那也是可以接受的。毕竟,这就是我要在这里做的事情。
【问题讨论】:
-
case Left((r, in)) => Done(Left(r), El(in))没有任何意义 - 如果有任何剩余的输入,则紧接上面的case Left(b)分支将被遵循。我想你可能想要的是case Left(r) => Done(Left(r), Empty)。但是,我认为如果您使用transform而不是apply,您可以完全取消第二个flatMap。 -
@wingedsubmariner 想尝试用完整的代码输入答案吗?我可以用手握住。
标签: json scala playframework compiler-errors playframework-2.3