如何为 spray+akka actor 设置隐式 json 转换
How to setup implicit json convertion for spray+akka actor
我是 Java 开发人员,对 Scala 还很陌生。
我正在实施一些使用 spray 和 akka 的休息 API
API 应该公开某种用户 CRUD。我只会在这个问题中使用创建用户...
trait DefaultJsonFormats extends DefaultJsonProtocol with SprayJsonSupport with MetaMarshallers {}
class RegistrationService(registration: ActorRef)
(implicit executionContext: ExecutionContext)
extends Directives with DefaultJsonFormats {
implicit val timeout = Timeout(2.seconds)
implicit val userFormat = jsonFormat3(User)
implicit val registerFormat = jsonFormat1(Register)
implicit val registeredFormat = jsonFormat1(Registered)
val route =
path("register") {
post { handleWith { ru: Register => (registration ? ru).mapTo[Registered] } }
}
//------演员
object RegistrationActor {
case class User(id:String, name:String)
case class Register(user: User)
case class Registered(status: String)
case object NotRegistered
}
class RegistrationActor(implDef: String) extends Actor {
def receive: Receive = {
case Register(user)=>
val status=// create user real code with return status
sender ! new Registered(status)
} }
在这种方法中,json 序列化和反序列化非常烦人。对于我需要处理的每个对象 API 我必须定义适当的格式
implicit val userFormat = jsonFormat3(User)
implicit val registerFormat = jsonFormat1(Register)
implicit val registeredFormat = jsonFormat1(Registered)
我想避免这样的定义并使用一些通用的 json 转换器和 return 一个 pojo 对象,这样转换将在后台进行
问题是如何更改此代码以默认使用 Gson/Jackson/Spray 默认转换器并避免定义隐式... json格式?
For every object I need to deal with API I must define the appropriate format
通常在“JsonProtocol”class 中执行一次并在需要的地方导入,而不是每次都定义新格式:
import MyJsonProtocol._
val route =
path("register") {
post { handleWith { ru: Register => (registration ? ru).mapTo[Registered] } }
how can I change this code to use by default Gson/Jackson/Spray default converter and avoid definition of the implicit ... jsonFormats?
您需要声明一个从 Registered
到 HttpResponse
的隐式编组器(或像 String
这样的中间值),它由 Jackson 而不是 spray-json
支持,然后导入该编组器而不是 SprayJsonSupport
.
查看 the implementation of SprayJsonSupport 了解如何执行此操作。如果您对隐式转换感到满意,这非常简单。
您还可以在 Spray 的 Json4sSupport 中看到这是如何完成的——该特性为所有类型 T
实现了 Marshaller[T, String]
。然后,在运行时,Json4s
库将尝试将该对象序列化为 JSON.
In this approach the json serialization and desiarelization is pretty annoying
与杰克逊的方法相比,spray-json
的方法有两个主要优点:
- 没有反射,所以运行时更快
- 这不是 JSON 格式的运行时决定,因此在编译时会发现任何问题
我是 Java 开发人员,对 Scala 还很陌生。
我正在实施一些使用 spray 和 akka 的休息 API API 应该公开某种用户 CRUD。我只会在这个问题中使用创建用户...
trait DefaultJsonFormats extends DefaultJsonProtocol with SprayJsonSupport with MetaMarshallers {}
class RegistrationService(registration: ActorRef)
(implicit executionContext: ExecutionContext)
extends Directives with DefaultJsonFormats {
implicit val timeout = Timeout(2.seconds)
implicit val userFormat = jsonFormat3(User)
implicit val registerFormat = jsonFormat1(Register)
implicit val registeredFormat = jsonFormat1(Registered)
val route =
path("register") {
post { handleWith { ru: Register => (registration ? ru).mapTo[Registered] } }
}
//------演员
object RegistrationActor {
case class User(id:String, name:String)
case class Register(user: User)
case class Registered(status: String)
case object NotRegistered
}
class RegistrationActor(implDef: String) extends Actor {
def receive: Receive = {
case Register(user)=>
val status=// create user real code with return status
sender ! new Registered(status)
} }
在这种方法中,json 序列化和反序列化非常烦人。对于我需要处理的每个对象 API 我必须定义适当的格式
implicit val userFormat = jsonFormat3(User)
implicit val registerFormat = jsonFormat1(Register)
implicit val registeredFormat = jsonFormat1(Registered)
我想避免这样的定义并使用一些通用的 json 转换器和 return 一个 pojo 对象,这样转换将在后台进行
问题是如何更改此代码以默认使用 Gson/Jackson/Spray 默认转换器并避免定义隐式... json格式?
For every object I need to deal with API I must define the appropriate format
通常在“JsonProtocol”class 中执行一次并在需要的地方导入,而不是每次都定义新格式:
import MyJsonProtocol._
val route =
path("register") {
post { handleWith { ru: Register => (registration ? ru).mapTo[Registered] } }
how can I change this code to use by default Gson/Jackson/Spray default converter and avoid definition of the implicit ... jsonFormats?
您需要声明一个从 Registered
到 HttpResponse
的隐式编组器(或像 String
这样的中间值),它由 Jackson 而不是 spray-json
支持,然后导入该编组器而不是 SprayJsonSupport
.
查看 the implementation of SprayJsonSupport 了解如何执行此操作。如果您对隐式转换感到满意,这非常简单。
您还可以在 Spray 的 Json4sSupport 中看到这是如何完成的——该特性为所有类型 T
实现了 Marshaller[T, String]
。然后,在运行时,Json4s
库将尝试将该对象序列化为 JSON.
In this approach the json serialization and desiarelization is pretty annoying
与杰克逊的方法相比,spray-json
的方法有两个主要优点:
- 没有反射,所以运行时更快
- 这不是 JSON 格式的运行时决定,因此在编译时会发现任何问题