【问题标题】:How can I get PureConfig to deserialize JSON as a JValue field?如何让 PureConfig 将 JSON 反序列化为 JValue 字段?
【发布时间】:2020-03-05 03:15:07
【问题描述】:

我的部分配置包含任意 JSON。我想将该 JSON 反序列化为 JValue 以供以后处理。

但是,ConfigSource.load 抱怨找不到 type 密钥。

测试代码:

import org.json4s.JsonAST.JValue
import pureconfig.ConfigReader.Result
import pureconfig._
import pureconfig.generic.auto._

object PureConfig2JValue extends App {
  case class Config(json: JValue)

  val source: ConfigObjectSource = ConfigSource.string("{ \"json\": { \"test\": \"test\" } }")

  val loadedSource: Result[Config] = source.load[Config]

  println(loadedSource)
}

输出:

Left(ConfigReaderFailures(ConvertFailure(KeyNotFound(type,Set()),None,json),List()))

如何让 PureConfig 反序列化为 JValue?

更新:

我将 Gagandeep 的答案改编为我的旧版 PureConfig:

implicit val configReader: ConfigReader[JValue] = new ConfigReader[JValue] {
  override def from(cur: ConfigCursor): Either[ConfigReaderFailures, JValue] =
    cur.asString match {
      case Right(jsonString: String) => Right(parse(jsonString))
      case Left(configReaderFailures: ConfigReaderFailures) => Left(configReaderFailures)
    }
}

它改变了错误信息,我认为这是进步:

Left(ConfigReaderFailures(ConvertFailure(WrongType(OBJECT,Set(STRING)),None,json),List()))

PureConfig 似乎在某处期望一个字符串,但却发现了一个对象。我不确定断开连接在哪里。我使用cur.asString 来确保该项目以其适当的类型返回。

更新 2:

这可能不是最强大的解决方案,但它适用于我的测试用例:

implicit val configReader: ConfigReader[JValue] = new ConfigReader[JValue] {
  override def from(cur: ConfigCursor): Either[ConfigReaderFailures, JValue] = {
    Right(
      // Parse PureConfig-rendered JSON.
      parse(
        // Render config as JSON.
        cur.value.render(ConfigRenderOptions.concise.setJson(true))
      )
    )
  }
}

【问题讨论】:

标签: json scala deserialization json4s pureconfig


【解决方案1】:

JValue 不是类、元组、案例类或密封特征,因此宏无法为其生成自动派生。为它定义一个读者应该会有所帮助。

import org.json4s._
import org.json4s.native.JsonMethods._

implicit val configReader = new ConfigReader[JValue] {
    override def from(cur: ConfigCursor): Result[JValue] = cur.asString.map(parse)
}

【讨论】:

  • 谢谢,看起来不错的答案!我更新了我的问题以显示我在尝试您的代码后遇到的新障碍。如果您发现任何明显的解决方案,请告诉我。
  • 接受,因为这让我走上了正确的道路。我使用的代码在更新的问题中。