基于Play Framework替换JSON值:用映射列表修改并保存输出
处理Play Framework中JSON的批量字段替换问题
看起来你需要基于给定的替换映射列表,批量更新JSON中的字段值。下面我会用Play Framework的JSON API给出具体的实现方案,涵盖顶层字段替换、嵌套字段替换以及仅更新存在字段等常见场景。
1. 基础准备:导入依赖与定义原始JSON
首先确保你已经引入Play JSON的依赖(在build.sbt中):
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.9.2" // 版本可根据你的Play版本调整
然后定义你的原始JSON和替换列表:
import play.api.libs.json._ import scala.collection.mutable // 你的原始JSON val originalJson = Json.parse("""{ "field_a": "dummy", "field_b": "dummy", "nest": { "nest_a": "dummy", "nest_b": 87 }, "field_c": null, "field_d": null, "field_e": "chocolate", "field_f": "sugar", "array": [ "dummy entry" ], "id": "Anything" }""").as[JsObject] // 你的替换映射列表(示例) val substitutionsList: List[mutable.Map[String, String]] = List( mutable.Map("field_b" -> "dummy string", "field_d" -> "updated_d_value"), mutable.Map("field_e" -> "vanilla", "field_b" -> "overridden_b_value") // 后面的映射会覆盖前面的同键值 )
2. 核心步骤:合并替换规则并应用到JSON
2.1 合并替换映射(解决重复键冲突)
首先将所有替换映射合并为一个不可变Map,确保后面的替换规则会覆盖前面的同键规则:
// 合并所有替换规则到一个不可变Map val mergedSubstitutions = substitutionsList.foldLeft(Map.empty[String, String]) { (acc, map) => acc ++ map.toMap }
2.2 替换顶层字段
如果只需要更新顶层字段,直接遍历合并后的Map,调用JsObject的+方法更新字段即可:
// 应用顶层字段替换 val updatedJson = mergedSubstitutions.foldLeft(originalJson) { (json, (key, value)) => json + (key -> JsString(value)) } // 打印格式化后的结果 println(Json.prettyPrint(updatedJson))
执行后,field_b会被替换为overridden_b_value,field_d变为updated_d_value,field_e变为vanilla,其他字段保持原样。
2.3 支持嵌套字段替换
如果需要替换嵌套字段(比如nest.nest_a),可以编写一个递归函数来处理路径解析:
// 递归更新嵌套字段的工具函数 def updateNestedField(json: JsObject, path: String, value: JsValue): JsObject = { path.split('.').toList match { // 路径是顶层字段,直接更新 case last :: Nil => json + (last -> value) // 路径包含嵌套层级,递归处理 case head :: tail => json.get(head) match { case Some(nestedObj: JsObject) => json + (head -> updateNestedField(nestedObj, tail.mkString("."), value)) case _ => json // 如果嵌套路径不存在,不做修改 } } } // 应用包含嵌套字段的替换(比如添加"nest.nest_a" -> "updated_nest_a"到替换列表) val updatedJsonWithNested = mergedSubstitutions.foldLeft(originalJson) { (json, (key, value)) => updateNestedField(json, key, JsString(value)) }
2.4 仅更新已存在的字段
如果不想添加原始JSON中不存在的字段,只需在更新前判断字段是否存在:
// 仅更新原始JSON中已存在的字段 val updatedJsonOnlyExisting = mergedSubstitutions.foldLeft(originalJson) { (json, (key, value)) => if (json.keys.contains(key)) json + (key -> JsString(value)) else json }
3. 保存输出结果
最后,你可以将修改后的JSON保存到文件或返回给客户端:
// 保存到文件 import java.io.PrintWriter new PrintWriter("updated.json") { write(Json.prettyPrint(updatedJson)); close() } // 如果是Play控制器中,直接返回JSON结果 // Ok(updatedJson)
内容的提问来源于stack exchange,提问作者Curious_Bop
相关产品推荐
相关产品推荐

