使用lift-json或json4s,在空字符串的情况下,如何将Option [String]的字段映射到None?

时间:2017-05-21 00:45:40

标签: json4s lift-json

这个测试应该解释我正在尝试做什么,谢谢:

import com.typesafe.scalalogging.StrictLogging
import net.liftweb.json._
import org.specs2.mutable.Specification

object Dummy {
  case class Person(first: String, last: String, job: Option[String])
}

case object StringNotEmptySerializer extends CustomSerializer[String](format => (
  {
    case JString(s) => s
    case JNull => null
  },
  {
    case "" => null
    case s: String => JString(s)
  }
))

class JsonNoneStringTest extends Specification with StrictLogging {
  implicit val formats = DefaultFormats + StringNotEmptySerializer

  "Dummy" >> {
    val p1 = Dummy.Person("lola", "", Some("dev"))
    val j1 = compactRender(Extraction.decompose(p1))
    p1.first must_== "lola"
    p1.last must_== ""
    p1.job must_== Some("dev")

    val d2 = """{ "first": "jamie", "last": "", "job": "" }"""
    val p2 = parse(d2).extract[Dummy.Person]
    p2.first must_== "jamie"
    p2.last must_== ""
    p2.job must_== None

    ok
  }
}

1 个答案:

答案 0 :(得分:0)

我向专家寻求帮助,得到了这个答案,可以应用于任何案例类层次结构!

object ObjectUtil {
  import shapeless._
  import shapeless.poly._

  object someEmptyToNone extends ->((os: Option[String]) => os flatMap (s => if (s == "") None else Some(s)))

  def transformEmptyStringsToNone[A](a: A)(implicit ev: Case1.Aux[EverywhereAux[someEmptyToNone.type], A, A]): A =
    ev(a)
}

以下是它的作用:

import ObjectUtil
import com.typesafe.scalalogging.StrictLogging
import net.liftweb.json._
import org.specs2.mutable.Specification

class JsonNoneStringTest extends Specification with StrictLogging {
  "Empty string to null example" >> {
    implicit val formats = DefaultFormats
    import net.liftweb.json._

    case class Person(first: String, last: String, nickname: Option[String], address: Address)
    case class Address(street: String, unit: Option[String], city: String)

    val jamie =
      parse(
        """
          | {
          |   "first" : "jamie",
          |   "last" : "",
          |   "nickname" : "",
          |   "address" : {
          |     "street": "11111 national ave",
          |     "unit": "",
          |     "city": ""
          |   }
          | }
          | """.stripMargin
      ).extract[Person]

    jamie.last must_== ""
    jamie.nickname must_== Some("")
    jamie.address.unit must_== Some("")
    jamie.address.city must_== ""

    val jamie2 = ObjectUtil.transformEmptyStringsToNone(jamie)

    jamie2.last must_== ""
    jamie2.nickname must_== None
    jamie2.address.unit must_== None
    jamie2.address.city must_== ""
  }
}