使用Play2 + Spray处理包含JSON的POST时出错

时间:2018-02-22 12:08:32

标签: scala playframework-2.0 spray

在寻找大量的教程和帖子并且无法解决这个显而易见的微不足道的问题之后,我希望Stackoverflow再次得到我的救援。

我正在尝试在Scala + Play2 + Spray应用程序中接收带有POST的JSON,解析并存储它。我已经在不同的类中构建了这些东西,试图保持控制器清洁:

对象定义:ElementManager.scala

case class Element (id:Int, paramOne:String){
  override def toString = id.toString + ": " + paramOne 
}

object MyJsonProtocol extends DefaultJsonProtocol {
  implicit object ElementJsonFormat extends RootJsonFormat[Element] {
    def write(e: Element) = JsObject(
      "id" -> JsNumber(e.id),
      "paramOne" -> JsString(e.paramOne))

    def read(value: JsValue) = {
      value.asJsObject.getFields("id", "paramOne") match {
        case Seq(JsNumber(id), JsString(paramOne)) =>
          new Element(id.toInt, paramOne)
        case _ => throw new DeserializationException("problem deserializing Element ")
      }
    }
  }
}

控制器。 ElementController。它已从https://playframework.com/documentation/2.0/ScalaJsonRequests

复制
@Singleton
class JsonController @Inject() (cc: ControllerComponents, storage:ElementManager) extends AbstractController(cc) {
  def storepost = Action(parse.json) { request =>
    val elementResult = request.body.validate[Element]
    elementResult.fold(
      errors => {
        BadRequest(Json.obj("status" ->"KO", "message" -> JsError.toJson(errors)))
      },
      element => {
        Element.save(element)
        Ok(Json.obj("status" ->"OK", "message" -> ("Element '"+element.id+"' saved.") ))
      }
    )
  }

呼叫:

curl  --header "Content-type: application/json"  --request POST   --data '{"id": 3, "paramOne":"test"}'  http://localhost:9000/storepost

方法" storepost"应该接收JSON,将其解析为Element和store。但是,我一直收到以下错误。

Json deserializer found for type services.Element. Try to implement an implicit Reads or Format for this type.
[error]     val elementResult = request.body.validate[Element]

发生了什么事?为什么"阅读"我实现的函数无效解析这个?我应该实现" Reads"旁边的"阅读"功能? (虽然这看起来并不优雅)。有没有更好的方法来获取POST解析它的信息?

奖金问题:答案是否会与" PUT"方法?我假设没有,但我必须在项目中将其用于其他一些事情......

喝彩!

1 个答案:

答案 0 :(得分:0)

使用格式进行序列化和反序列化:

implicit val formatElement = Json.Format[Element]

然后你可以use request.body.validate[Element]

这样可行。