用circe重命名JSON字段

时间:2016-10-28 13:26:28

标签: json scala circe

我想在我的case类和JSON中使用不同的字段名称,因此我需要一种舒适的方式来重命名,编码和解码。

有人有一个好的解决方案吗?

5 个答案:

答案 0 :(得分:2)

您可以使用Custom key mappings via annotations。最通用的方法是来自JsonKey的{​​{1}}批注。来自文档的示例:

io.circe.generic.extras._

这需要软件包import io.circe.generic.extras._, io.circe.syntax._ implicit val config: Configuration = Configuration.default @ConfiguredJsonCodec case class Bar(@JsonKey("my-int") i: Int, s: String) Bar(13, "Qux").asJson // res5: io.circe.Json = JObject(object[my-int -> 13,s -> "Qux"])

答案 1 :(得分:1)

implicit val decodeFieldType: Decoder[FieldType] =
  Decoder.forProduct5("nth", "isVLEncoded", "isSerialized", "isSigningField", "type")
                     (FieldType.apply)

如果您有许多不同的字段名称,这是一种简单的方法。 https://circe.github.io/circe/codecs/custom-codecs.html

答案 2 :(得分:0)

您可以使用编码器上的prepare功能从通用编码器中导出编码器并重新映射您的字段名称。

您可以使用解码器上的Select FullName from tblVisitor;函数来转换传递给通用解码器的JSON。

你也可以从头开始编写,但它可能是一大堆样板,这些解决方案应该都是少数几行。

答案 3 :(得分:0)

以下是Decoder的代码示例(由于不会删除旧字段,所以比特详细):

  val pimpedDecoder = deriveDecoder[PimpClass].prepare {
    _.withFocus {
      _.mapObject { x =>
        val value = x("old-field")
        value.map(x.add("new-field", _)).getOrElse(x)
      }
    }
  }

答案 4 :(得分:0)

以下函数可用于重命名 circe 的 JSON 字段:

import io.circe._

object CirceUtil {
  def renameField(json: Json, fieldToRename: String, newName: String): Json =
    (for {
      value <- json.hcursor.downField(fieldToRename).focus
      newJson <- json.mapObject(_.add(newName, value)).hcursor.downField(fieldToRename).delete.top
    } yield newJson).getOrElse(json)
}

您可以像这样在 Encoder 中使用它:

implicit val circeEncoder: Encoder[YourCaseClass] = deriveEncoder[YourCaseClass].mapJson(
  CirceUtil.renameField(_, "old_field_name", "new_field_name")
)

额外

单元测试

import io.circe.parser._
import org.specs2.mutable.Specification

class CirceUtilSpec extends Specification {

  "CirceUtil" should {
    "renameField" should {
      "correctly rename field" in {
        val json = parse("""{ "oldFieldName": 1 }""").toOption.get
        val resultJson = CirceUtil.renameField(json, "oldFieldName", "newFieldName")
        resultJson.hcursor.downField("oldFieldName").focus must beNone
        resultJson.hcursor.downField("newFieldName").focus must beSome
      }

      "return unchanged json if field is not found" in {
        val json = parse("""{ "oldFieldName": 1 }""").toOption.get
        val resultJson = CirceUtil.renameField(json, "nonExistentField", "newFieldName")
        resultJson must be equalTo json
      }
    }
  }
}