在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:spray/spray-json开源软件地址:https://github.com/spray/spray-json开源编程语言:Scala 100.0%开源软件介绍:spray-json is a lightweight, clean and efficient JSON implementation in Scala. It supports the following features:
spray-json allows you to convert between
as depicted in this diagram: Installationspray-json is available from maven central. If you use SBT you can include spray-json in your project with libraryDependencies += "io.spray" %% "spray-json" % "1.3.6" Usagespray-json is really easy to use. Just bring all relevant elements in scope with import spray.json._
import DefaultJsonProtocol._ // if you don't supply your own Protocol (see below) and do one or more of the following:
In order to make steps 3 and 4 work for an object of type JsonProtocolspray-json uses SJSONs Scala-idiomatic type-class-based approach to connect an existing type This approach has the advantage of not requiring any change (or even access) to In spray-jsons terminology a 'JsonProtocol' is nothing but a bunch of implicit values of type This may sound more complicated than it is.
spray-json comes with a
In most cases however you'll also want to convert types not covered by the Providing JsonFormats for Case ClassesIf your custom type case class Color(name: String, red: Int, green: Int, blue: Int)
object MyJsonProtocol extends DefaultJsonProtocol {
implicit val colorFormat = jsonFormat4(Color)
}
import MyJsonProtocol._
import spray.json._
val json = Color("CadetBlue", 95, 158, 160).toJson
val color = json.convertTo[Color] The There is one additional quirk: If you explicitly declare the companion object for your case class the notation above will
stop working. You'll have to explicitly refer to the companion objects case class Color(name: String, red: Int, green: Int, blue: Int)
object Color
object MyJsonProtocol extends DefaultJsonProtocol {
implicit val colorFormat = jsonFormat4(Color.apply)
} If your case class is generic in that it takes type parameters itself the case class NamedList[A](name: String, items: List[A])
object MyJsonProtocol extends DefaultJsonProtocol {
implicit def namedListFormat[A :JsonFormat] = jsonFormat2(NamedList.apply[A])
} NullOptionsThe Providing JsonFormats for other TypesOf course you can also supply (de)serialization logic for types that aren't case classes. Here is one way to do it: class Color(val name: String, val red: Int, val green: Int, val blue: Int)
object MyJsonProtocol extends DefaultJsonProtocol {
implicit object ColorJsonFormat extends RootJsonFormat[Color] {
def write(c: Color) =
JsArray(JsString(c.name), JsNumber(c.red), JsNumber(c.green), JsNumber(c.blue))
def read(value: JsValue) = value match {
case JsArray(Vector(JsString(name), JsNumber(red), JsNumber(green), JsNumber(blue))) =>
new Color(name, red.toInt, green.toInt, blue.toInt)
case _ => deserializationError("Color expected")
}
}
}
import MyJsonProtocol._
val json = new Color("CadetBlue", 95, 158, 160).toJson
val color = json.convertTo[Color] This serializes Another way would be to serialize object MyJsonProtocol extends DefaultJsonProtocol {
implicit object ColorJsonFormat extends RootJsonFormat[Color] {
def write(c: Color) = JsObject(
"name" -> JsString(c.name),
"red" -> JsNumber(c.red),
"green" -> JsNumber(c.green),
"blue" -> JsNumber(c.blue)
)
def read(value: JsValue) = {
value.asJsObject.getFields("name", "red", "green", "blue") match {
case Seq(JsString(name), JsNumber(red), JsNumber(green), JsNumber(blue)) =>
new Color(name, red.toInt, green.toInt, blue.toInt)
case _ => throw new DeserializationException("Color expected")
}
}
}
} This is a bit more verbose in its definition and the resulting JSON but transports the field semantics over to the JSON side. Note that this is the approach spray-json uses for case classes. Providing JsonFormats for unboxed typesA value class case class PhoneNumber(value: String) extends AnyVal
val num = PhoneNumber("+1 212 555 1111") or a class with multiple members case class Money(currency: String, amount: BigDecimal)
val bal = Money("USD", 100) can be handled as above with implicit object MoneyFormat extends JsonFormat[Money] {
val fmt = """([A-Z]{3}) ([0-9.]+)""".r
def write(m: Money) = JsString(s"${m.currency} ${m.amount}")
def read(json: JsValue) = json match {
case JsString(fmt(c, a)) => Money(c, BigDecimal(a))
case _ => deserializationError("String expected")
}
} JsonFormat vs. RootJsonFormatAccording to the JSON specification not all of the defined JSON value types are allowed at the root level of a JSON
document. A JSON string for example (like In order to distinguish, on the type-level, "regular" JsonFormats from the ones producing root-level JSON objects or
arrays spray-json defines the All default converters in the JsonFormats for recursive TypesIf your type is recursive such as case class Foo(i: Int, foo: Foo) you need to wrap your format constructor with implicit val fooFormat: JsonFormat[Foo] = lazyFormat(jsonFormat(Foo, "i", "foo")) Otherwise your code will either not compile (no explicit type annotation) or throw an NPE at runtime (no Customizing Parser SettingsThe parser can be customized by providing a custom instance of val customSettings =
JsonParserSettings.default
.withMaxDepth(100)
.withMaxNumberCharacters(20)
val jsValue = JsonParser(jsonString, customSettings)
// or
val jsValue = jsonString.parseJson(customSettings) CreditsMost of type-class (de)serialization code is nothing but a polished copy of what Debasish Ghosh made available with his SJSON library. These code parts therefore bear his copyright. Additionally the JSON AST model is heavily inspired by the one contributed by Jorge Ortiz to Databinder-Dispatch. Licensespray-json is licensed under APL 2.0. Mailing listSpray-json is in primarily "maintanance mode", as it contains the basic functionality it is meant to deliver. If you have any questions about it though, please open issues on this repository. Maintanance modespray-json is largely considered feature-complete for the basic functionality it provides. It is currently maintained by the Akka team at Lightbend. Feedback and contributions to the project, no matter what kind, are always very welcome. Along with any patches, please state that the patch is your original work and that you license the work to the spray-json project under the project’s open source license. |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论