You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Circe修改JSON字段类型?优化字符串转整数实现

优化Circe修改JSON字段类型的实现

你的这段代码确实有点繁琐,而且jsObj.asObject.get这种调用是不安全的——万一JSON解析失败或者没有test字段,直接就会抛出异常。我来给你两种优化思路,一种是用Circe原生的更安全的API,另一种是用Circe Optics来简化操作,后者特别适合这种精准修改JSON某个路径值的场景。

一、Circe原生API的安全优化

我们可以利用Circe的HCursor来安全地定位字段、转换值,同时处理可能的异常情况(比如字段不存在、字符串无法转整数):

首先导入必要的包:

import io.circe._
import io.circe.parser._

然后实现代码:

val str = """{"test":"123"}"""

// 安全处理解析和转换的全流程
val result: Either[Error, Json] = for {
  // 解析原始JSON,返回Either处理失败情况
  originalJson <- parse(str)
  // 获取test字段的字符串值,失败则进入Left分支
  testStr <- originalJson.hcursor.get[String]("test")
  // 尝试将字符串转整数,处理转换失败的情况
  testInt <- Either.catchNonFatal(testStr.toInt).leftMap(e => ParsingFailure(s"Failed to parse integer: ${e.getMessage}", e))
  // 修改JSON字段值
  updatedJson <- originalJson.hcursor
    .downField("test")
    .withFocus(_ => Json.fromInt(testInt))
    .top
    .toRight(new Error("Failed to update JSON structure"))
} yield updatedJson

这个版本全程用Either处理所有可能的失败场景,避免了不安全的.get调用,代码也更清晰。

二、Circe Optics的简洁实现

Circe Optics专门用于JSON的“聚焦式”操作,能让你像操作普通数据结构一样精准修改JSON的某个路径,代码会非常简洁。

首先需要导入Optics的包(确保你的依赖里包含了circe-optics):

import io.circe._
import io.circe.parser._
import io.circe.optics.JsonPath._

然后实现代码:

val str = """{"test":"123"}"""

// 定义指向`test`字符串字段的Optic
val testStringField = root.test.string

// 安全处理的版本:解析后修改,同时处理转换异常
val result: Either[Error, Json] = parse(str).flatMap { json =>
  testStringField.modifyF { s =>
    Either.catchNonFatal(Json.fromInt(s.toInt)).leftMap(e => ParsingFailure(s"Invalid integer: $s", e))
  }(json)
}

// 如果不需要严格处理异常(仅做示例),可以更简洁:
val simpleUpdatedJson = testStringField.modify(_.toInt)(parse(str).getOrElse(Json.Null))

Optics的好处在于:

  • 不需要手动操作JsonObject的remove/add,直接针对目标路径修改
  • 代码可读性极高,一眼就能看出是在修改root.test这个字段
  • 可以通过modifyF、modifyOption等方法灵活处理异常或不存在的字段

比如用modifyOption处理转换失败的情况:

val safeUpdatedJson: Option[Json] = parse(str).toOption.flatMap { json =>
  testStringField.modifyOption(s => Either.catchNonFatal(Json.fromInt(s.toInt)).toOption)(json)
}

如果test字段不是字符串,或者字符串无法转整数,这个方法会返回None,避免抛出异常。

内容的提问来源于stack exchange,提问作者Oleg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:30:41