1

有没有一种简单的方法可以在对象内没有“tpe”字段的情况下序列化为 json?我需要将案例类序列化为 json 结构,然后通过网络发送它们(它们将来不会被反序列化)。我有一个特定的 api,所以.. 我不需要额外的字段。

对于Person下图所示的类:

case class Person(Name: String, Age: int, CandyLover: Boolean)

我希望看到以下内容:

{
  "Name": "Paul",
  "Age": 23,
  "CandyLover": true
}
4

3 回答 3

4

我建议你看看 spray-json 或 argonaut。如果你已经在使用 Play,或者 play-json。

Scala pickling 并不是一个真正的 json 库,它不是为了为公共 API 生成 JSON 而创建的,它不灵活,你不能先定义 JSON 协议,然后再提供 pickling 序列化来匹配协议。Pickling 用于计算机到计算机的序列化,没有人真正关心应用程序之间的字节传输。

于 2015-01-23T00:42:13.520 回答
1

可能最简单的方法是以某种方式传递Hintinto JSONPickleBuilder。快速的方法是JSONPickleFormat通过调用hintStaticallyElidedType()from 的方法来覆盖构建器PickleTools

这是一种代码片段来演示它:

import org.specs2.matcher.JsonMatchers
import org.specs2.mutable.Specification
import org.specs2.specification.Scope

import scala.pickling.Defaults._
import scala.pickling.json.{JSONPickleBuilder, JSONPickleFormat, JsonFormats}
import scala.pickling.{Output, PBuilder, PickleTools, StringOutput}

class PersonJsonFormatsTest extends Specification with JsonMatchers {
  trait Context extends Scope with PersonJsonFormats

  trait PersonJsonFormats extends JsonFormats {
    override implicit val pickleFormat: JSONPickleFormat = new PersonJSONPickleFormat
  }

  class PersonJSONPickleFormat extends JSONPickleFormat {
    override def createBuilder() = new JSONPickleBuilder(this, new StringOutput) with PickleTools {
      hintStaticallyElidedType()
    }
    override def createBuilder(out: Output[String]): PBuilder = new JSONPickleBuilder(this, out) with PickleTools {
      hintStaticallyElidedType()
    }
  }

  "Pickle" should {
    "Serialize Person without $type field in resulting JSON" in new Context {
      case class Person(Name: String, Age: Int, CandyLover: Boolean)

      val pickledPersonObject = Person("Paul", 23, CandyLover = true).pickle
      println(pickledPersonObject.value)
      pickledPersonObject.value must not */("$type" → ".*".r)
    }
  }
}

的输出println(pickledPersonObject.value)将根据您的需要:

{
  "Name": "Paul",
  "Age": 23,
  "CandyLover": true
}

这样,您将与进一步的泡菜更新保持一致。

PS如果有人知道更优雅和方便的方式来达到相同的行为 - 请告诉我们:-)

于 2015-02-27T19:26:15.270 回答
0

对于 scala-pickling 0.10.x:

import scala.pickling._
import scala.pickling.json.{JSONPickle, JSONPickleBuilder, JSONPickleFormat, JsonFormats}
import scala.pickling.pickler.AllPicklers

object serialization extends JsonFormats with Ops with AllPicklers {
  override implicit val pickleFormat: JSONPickleFormat = new JSONPickleFormat {

    private def setHints(h: Hintable): Unit = {
      h.hintStaticallyElidedType()
      h.hintDynamicallyElidedType()
    }

    override def createBuilder(): JSONPickleBuilder = {
      val builder = super.createBuilder()
      setHints(builder)
      builder
    }

    override def createBuilder(out: Output[String]): PBuilder = {
      val builder = super.createBuilder(out)
      setHints(builder)
      builder
    }

    override def createReader(pickle: JSONPickle): PReader = {
      val reader = super.createReader(pickle)
      setHints(reader)
      reader
    }
  }
}

object SerializationTest extends App {
  import serialization._

  case class Person(firstName: String, lastName: String)

  val pickle: JSONPickle = Person("Evelyn", "Patterson").pickle
  val jsonString: String = pickle.value // {"firstName": "Evelyn","lastName": "Patterson"}

  val person: Person = jsonString.unpickle[Person]
}

对于 scala-pickling 0.11.x:

import scala.pickling._
import scala.pickling.json.{JSONPickle, JSONPickleBuilder, JSONPickleFormat}
import scala.pickling.pickler.AllPicklers

object serialization extends AllPicklers {

  private final class CustomJSONPickleFormat(tag: FastTypeTag[_]) extends JSONPickleFormat {

    private def setHints(h: Hintable) {
      h.hintElidedType(tag)
    }

    override def createBuilder(): JSONPickleBuilder = {
      val b = super.createBuilder()
      setHints(b)
      b
    }
    override def createBuilder(out: Output[String]): PBuilder = {
      val b = super.createBuilder(out)
      setHints(b)
      b
    }
    override def createReader(pickle: JSONPickle): PReader = {
      val b = super.createReader(pickle)
      setHints(b)
      b
    }
  }

  implicit val staticOnly = static.StaticOnly // for compile time serialization methods generation

  implicit final class EncodeDecodeOps[T](picklee: T) {
    def encode(implicit pickler: Pickler[T]): String = {
      val pickleFormat = new CustomJSONPickleFormat(pickler.tag)
      functions.pickle(picklee)(pickleFormat, pickler).value
    }

    def decode[A](implicit c: T => String, unpickler: Unpickler[A]): A = {
      val pickleFormat = new CustomJSONPickleFormat(unpickler.tag)
      functions.unpickle[A](json.JSONPickle(picklee))(unpickler, pickleFormat)
    }
  }
}

case class Person(firstName: String, lastName: String) {
   @transient var x = "test"
}

object SerializationTest extends App {
  import serialization._

  val jsonString = Person("Lisa", "Daniels").encode

  println(jsonString)

  val person = jsonString.decode[Person]

  println(person)
}
于 2016-04-12T13:56:47.317 回答