json - 如何解决此Scala/Play编译错误(返回错误的类型)?

标签 json scala playframework compiler-errors playframework-2.3

我正在尝试编写一个插入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/

相关文章:

javascript - 比较来自 JSON 的信息,返回列表中的顶部结果

javascript - 如何将 JSON 日期插入模板

斯卡拉 : Pattern matching against generic list types

scala - (按任意键继续)在 Scala 中

java - Neo4j 密码来计算和显示两个给定节点之间的所有关系

scala - 使用在 sqlu 语句中返回什么来返回更新的列,slickexception

javascript - 来自 Alfresco 的 json 多维数组

python - Pandas - 规范化 Json 列表

scala - 在 IntelliJ 中使用 Scala 工作表很困难

javascript - selenium 和 javascript,以 fancybox 为例子玩自动测试