在 scala play 中重组 json
Restructure a json in scala play
以下代码获取请求正文并验证并创建一个 json:
对象 ValidateDBConfigJson {
implicit val reads: Reads[ValidateDetails] = (
(JsPath \ "name").read[String].filter(JsonValidationError("Invalid name"))(_.length > 0) and
(JsPath \ "email").read[String].filter(JsonValidationError("Invalid email"))(_.length > 0) and
)(ValidateDetails.apply _)
}
def index() = Action { implicit request =>
val bodyAsJson = request.body.asJson.get
bodyAsJson.validate[ValidateDetails] match {
case success: JsSuccess[ValidateDetails] => {
Ok(Json.parse("succeeded!"))
}
case JsError(error) =>
BadRequest(JsError.toJson(error))
}
}
json 看起来像这样:
{
"obj.name": [
{
"msg": [
"error.expected.jsstring"
],
"args": []
}
],
"obj.email": [
{
"msg": [
"Invalid email"
],
"args": []
}
]
}
我想要按以下格式构建:
{
"ErrorMessages" :
[
"error.expected.jsstring",
"Invalid email"
]
}
序言:当我使用 Play 解析 JSON 时,我更喜欢使用 case class/objects 而不是隐式读取,所以这个答案将涵盖执行此操作的方法。使用隐式读取可能有更简单的方法,但我对隐式读取不太熟悉。
首先,为您将从 JSON 中获取的所有内容定义一个 case class
:
object Input {
case class Err(msg: Seq[String], args: Seq[String])
object Err {
implicit val format: OFormat[Err] = Json.format[Err]
}
case class ValidateDetails(`obj.name`: Seq[Err], `obj.email`: Seq[Err])
object ValidateDetails {
implicit val format: OFormat[ValidateDetails] = Json.format[ValidateDetails]
}
}
注意:Play 不知道如何处理用户定义的案例 class,所以我也为 Err
做了一个。 implicit val format: OFormat[ValidateDetails] = Json.format[ValidateDetails]
和 implicit val format: OFormat[Err] = Json.format[Err]
行很神奇,可以为您完成所有 reads/writes。
接下来,为您的输出 JSON 定义一个案例 class 并定义一个函数,它将您的输入案例 class 转换为输出案例:
object Output {
case class OutputJson(`ErrorMessages`: Seq[String])
object OutputJson {
implicit val format: OFormat[OutputJson] = Json.format[OutputJson]
}
// take msg Seq from name & email and add together into single Seq
def inputToOutput(input: Input.ValidateDetails): OutputJson = {
OutputJson(input.`obj.name`.flatMap(_.msg) ++ input.`obj.email`.flatMap(_.msg))
}
}
最后,将其放入映射到 routes
文件中的 POST 路由的方法中:
def index() = Action { implicit request =>
val bodyAsJson = request.body.asJson.get
bodyAsJson.validate[Input.ValidateDetails] match {
case success: JsSuccess[Input.ValidateDetails] =>
// turn the JSON into the Output case class and parse that as JSON
val output: JsValue = Json.toJson(Output.inputToOutput(success.value))
Ok(output)
case JsError(error) =>
BadRequest(JsError.toJson(error))
}
}
现在,如果您 运行 端口 9000 上的 Play 应用程序和 POST 到 http://localhost:9000/ 具有以下 JSON 正文...
{
"obj.name": [
{
"msg": [
"error.expected.jsstring"
],
"args": []
}
],
"obj.email": [
{
"msg": [
"Invalid email"
],
"args": []
}
]
}
...输出将是:
{
"ErrorMessages": [
"error.expected.jsstring",
"Invalid email"
]
}
我希望这能回答您的问题。
以下代码获取请求正文并验证并创建一个 json: 对象 ValidateDBConfigJson {
implicit val reads: Reads[ValidateDetails] = (
(JsPath \ "name").read[String].filter(JsonValidationError("Invalid name"))(_.length > 0) and
(JsPath \ "email").read[String].filter(JsonValidationError("Invalid email"))(_.length > 0) and
)(ValidateDetails.apply _)
}
def index() = Action { implicit request =>
val bodyAsJson = request.body.asJson.get
bodyAsJson.validate[ValidateDetails] match {
case success: JsSuccess[ValidateDetails] => {
Ok(Json.parse("succeeded!"))
}
case JsError(error) =>
BadRequest(JsError.toJson(error))
}
}
json 看起来像这样:
{
"obj.name": [
{
"msg": [
"error.expected.jsstring"
],
"args": []
}
],
"obj.email": [
{
"msg": [
"Invalid email"
],
"args": []
}
]
}
我想要按以下格式构建:
{
"ErrorMessages" :
[
"error.expected.jsstring",
"Invalid email"
]
}
序言:当我使用 Play 解析 JSON 时,我更喜欢使用 case class/objects 而不是隐式读取,所以这个答案将涵盖执行此操作的方法。使用隐式读取可能有更简单的方法,但我对隐式读取不太熟悉。
首先,为您将从 JSON 中获取的所有内容定义一个 case class
:
object Input {
case class Err(msg: Seq[String], args: Seq[String])
object Err {
implicit val format: OFormat[Err] = Json.format[Err]
}
case class ValidateDetails(`obj.name`: Seq[Err], `obj.email`: Seq[Err])
object ValidateDetails {
implicit val format: OFormat[ValidateDetails] = Json.format[ValidateDetails]
}
}
注意:Play 不知道如何处理用户定义的案例 class,所以我也为 Err
做了一个。 implicit val format: OFormat[ValidateDetails] = Json.format[ValidateDetails]
和 implicit val format: OFormat[Err] = Json.format[Err]
行很神奇,可以为您完成所有 reads/writes。
接下来,为您的输出 JSON 定义一个案例 class 并定义一个函数,它将您的输入案例 class 转换为输出案例:
object Output {
case class OutputJson(`ErrorMessages`: Seq[String])
object OutputJson {
implicit val format: OFormat[OutputJson] = Json.format[OutputJson]
}
// take msg Seq from name & email and add together into single Seq
def inputToOutput(input: Input.ValidateDetails): OutputJson = {
OutputJson(input.`obj.name`.flatMap(_.msg) ++ input.`obj.email`.flatMap(_.msg))
}
}
最后,将其放入映射到 routes
文件中的 POST 路由的方法中:
def index() = Action { implicit request =>
val bodyAsJson = request.body.asJson.get
bodyAsJson.validate[Input.ValidateDetails] match {
case success: JsSuccess[Input.ValidateDetails] =>
// turn the JSON into the Output case class and parse that as JSON
val output: JsValue = Json.toJson(Output.inputToOutput(success.value))
Ok(output)
case JsError(error) =>
BadRequest(JsError.toJson(error))
}
}
现在,如果您 运行 端口 9000 上的 Play 应用程序和 POST 到 http://localhost:9000/ 具有以下 JSON 正文...
{
"obj.name": [
{
"msg": [
"error.expected.jsstring"
],
"args": []
}
],
"obj.email": [
{
"msg": [
"Invalid email"
],
"args": []
}
]
}
...输出将是:
{
"ErrorMessages": [
"error.expected.jsstring",
"Invalid email"
]
}
我希望这能回答您的问题。