寻找一个干净的解决方案,以使用play框架验证json中的输入

时间:2014-10-24 09:02:47

标签: json scala playframework

直接读取预期字段(无论是否可选)并验证它们,但如果在给定的json中检测到意外字段,我将无法正确抛出异常。如果游戏框架可以用一两个语句来帮助它,那就太棒了。是的,我可以处理json并获取所有字段的名称,并将它们与预期的列表进行比较,这看起来有点复杂(当json输入的格式很复杂时)。

例如,输入json预计如下:

{
  "param": 1,
  "period": 2,  
  "threshold": 3,
  "toggle": true
}

和scala代码从json输入中复用类EventConfig:

import play.api.libs.json._
import play.api.libs.functional.syntax._

case class EventConfig(param: Int, period: Int, threshold: Int, toggle: Boolean)

object EventConfig {
  implicit val jsonReads: Reads[EventConfig] = (
    (__ \ "param").read[Int] and 
    (__ \ "period").read[Int] and 
    (__ \ "threshold").read[Int] and 
    (__ \ "toggle").read[Boolean]
  )(EventConfig.apply _)
}

如果在json中检测到意外字段(例如

),我想抛出异常
{
  "param": 1,
  "period": 2,  
  "threshold": 3,
  "toggle": true,
  "foo": "bar"
}

2 个答案:

答案 0 :(得分:2)

你签出了验证吗?

我不知道如何在此页面上深层链接您,但请查看https://www.playframework.com/documentation/2.1.3/ScalaJson并搜索标题:使用validate [T]进行最安全的转换

该页面的一些例子:

scala> import play.api.libs.json._

scala> val jsres: JsResult[String] = JsString("toto").validate[String]
jsres: JsSuccess("toto")

scala> val jsres: JsResult[String] = JsNumber(123).validate[String]
jsres: play.api.libs.json.JsResult[String] =         JsError(List((,List(ValidationError(validate.error.expected.jsstring,WrappedArray())))))

jsres.map{ s: String => …}
jsres.flatMap{ s: String => JsSuccess(s) }

jsres.fold( 
 errors: Seq[(JsPath, Seq[ValidationError])] => // manage errors,
 s: String => // manage value 
)

如果我完全理解你的问题 - 我认为你最感兴趣的是在JsResult上使用验证和折叠,这样你就可以处理成功/快乐路径然后错误(你可以返回400个错误请求等等,或者你想要处理它。)

伪造的代码

def something  = Action.async(parse.json) { request =>
 val maybeEventConfig = request.body.validate[EventConfig]
maybeEventConfig.fold(
 error => {},
 eventConfig => {}
 )}

答案 1 :(得分:0)

我想对LimbSoup上面说的内容+1,如果你的方式发送额外的标签,则不一定需要抛出错误;毕竟,如果客户在您期望的字段名称中输入拼写错误,那么您的Reads将抛出异常,您可以处理该异常以向您的客户提供适当的反馈。

但是,如果你仍然认为你需要这个,你可以考虑使用JSON Schema(JSD的XSD等价物):http://json-schema.org/

验证器的Java实现,您当然可以与Scala一起使用。 https://github.com/fge/json-schema-validator

我再次强调,您现有的代码已经在预期字段的拼写错误上窒息。考虑一下你是否真的需要这个。

[编辑]
我只是想重申一下我没有明确验证文件的原始观点。我们的想法是,您的代码应该容忍对收到的数据进行更改。它应尽可能少地假设数据结构。这个概念被称为宽容读者。请参阅Martin Fowler's more eloquent explanation