如何使用使用蛇形大小写(下划线符号)而不是驼峰大小写的喷雾 json 解析 json

How to parse json with spray json that uses snake case (underscore notation) instead of camel case

如何使用使用蛇形大小写(下划线符号)而不是驼峰大小写的喷雾 json 解析 json?

例如

case class Test(subjectDescription: String)
"{\"subject_description\":\"Medicine\"}".parseJson.convertTo[Test]

应该可以正常工作,不会抛出异常。

此答案摘自https://groups.google.com/forum/#!msg/spray-user/KsPIqWDK0AY/HcanflgRzMcJ。因为SEO更好所以把它放在SO上。

/**
 * A custom version of the Spray DefaultJsonProtocol with a modified field naming strategy
 */
trait SnakifiedSprayJsonSupport extends DefaultJsonProtocol {
  import reflect._

  /**
   * This is the most important piece of code in this object!
   * It overrides the default naming scheme used by spray-json and replaces it with a scheme that turns camelcased
   * names into snakified names (i.e. using underscores as word separators).
   */
  override protected def extractFieldNames(classTag: ClassTag[_]) = {
    import java.util.Locale

    def snakify(name: String) = PASS2.replaceAllIn(PASS1.replaceAllIn(name, REPLACEMENT), REPLACEMENT).toLowerCase(Locale.US)

    super.extractFieldNames(classTag).map { snakify(_) }
  }

  private val PASS1 = """([A-Z]+)([A-Z][a-z])""".r
  private val PASS2 = """([a-z\d])([A-Z])""".r
  private val REPLACEMENT = "_"
}

object SnakifiedSprayJsonSupport extends SnakifiedSprayJsonSupport

import SnakifiedSprayJsonSupport._

object MyJsonProtocol extends SnakifiedSprayJsonSupport {
  implicit val testFormat = jsonFormat1(Test.apply)
}

像这样:

case class Test(subjectDescription: String)
implicit val testFormat = jsonFormat(Test.apply, "subject_description")
"{\"subject_description\":\"Medicine\"}".parseJson.convertTo[Test]

这里的技巧是 jsonFormat 函数采用 json 对象键的字符串参数。