簡體   English   中英

通過scala-pickling序列化后從json中刪除tpe

[英]remove tpe from json after serialization via scala-pickling

有沒有一種簡單的方法可以序列化為json,而對象內部沒有“ tpe”字段? 我需要將案例類序列化為json結構,然后通過電線發送它們(以后將不會反序列化它們)。 我有一個特定的api,所以..我不需要其他字段。

對於下圖所示的Person

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

我想看看以下內容:

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

我建議您看一看Spray-json或argonaut。 或play-json(如果您已經在使用Play)。

Scala酸洗並不是真正的json庫,它不是為公共API生成JSON而創建的,它不靈活,您不能先定義JSON協議,然后再提供酸洗序列化以匹配協議。 酸洗用於計算機到計算機的序列化,其中沒有人真正關心應用之間的字節數。

可能最簡單的方法是將Hint某種方式傳遞給JSONPickleBuilder 快速的方法是通過從PickleTools調用hintStaticallyElidedType()方法來覆蓋JSONPickleFormat的構建器。

這是一種代碼片段來演示它:

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)的輸出將如您println(pickledPersonObject.value)

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

這樣,您將與進一步的泡菜更新保持一致。

PS:如果有人知道達到相同行為的更優雅,更便捷的方法,請告訴我們:-)

對於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)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM