我是Java开发人员,对scala很新。
我正在实现一些使用spray和akka的rest 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转换器并返回一个pojo对象,因此转换将在引擎盖下发生
问题是如何更改此代码以默认使用Gson / Jackson / Spray默认转换器并避免定义隐式... jsonFormats?
答案 0 :(得分:3)
对于我需要处理API的每个对象,我必须定义适当的格式
在" JsonProtocol"中进行一次这是正常的。在需要的地方进行类导入,而不是每次都定义新的格式:
import MyJsonProtocol._
val route =
path("register") {
post { handleWith { ru: Register => (registration ? ru).mapTo[Registered] } }
如何更改此代码以默认使用Gson / Jackson / Spray默认转换器并避免定义隐式... jsonFormats?
你需要声明一个从Registered
到HttpResponse
的隐式编组程序(或者像String
这样的中间值),它由杰克逊而不是spray-json
支持,然后导入那个编组而不是SprayJsonSupport
。
请查看the implementation of SprayJsonSupport以了解如何执行此操作。如果您对隐式转换感到满意,那就相当简单了。
您还可以在Spray中的Json4sSupport中查看这是如何完成的 - 该特征为所有类型Marshaller[T, String]
实现了T
。然后,在运行时,Json4s
库将尝试将对象序列化为JSON。
在这种方法中,json序列化和去混淆非常烦人
spray-json
方法优于杰克逊的两个主要优点: