早些时候,我在应用程序中使用了import com.fasterxml.jackson
。 因为我使用了akka http,所以我想尝试与Marshal/Unmarshal和spray.json.toJson.compactPrint
一起生活。 没有额外的包(com.fasterxml.jackson
)依赖。
但我坚持简单的案例
旧工作代码:
...
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
val obj: AnyRef = new Object()
val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
val json = mapper.writeValueAsString(obj)
新代码:
import spray.json._
val obj: AnyRef = new Object()
val json = obj.toJson.compactPrint
此原因异常
找不到 AnyRef 的 JsonWriter 或 JsonFormat 类型类 obj.toJson.compactPrint
请帮忙!
更新:
这是代码的真实部分 - 为了更好地理解我需要什么 效果很好。 com.fasterxml.jackson mapper 没有将 AnyRef 写入 json 字符串的限制
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
object mapper {
private val _mapper = new ObjectMapper()
_mapper.registerModule(DefaultScalaModule)
def get: ObjectMapper = _mapper
}
import akka.actor.{Actor, Props, ReceiveTimeout}
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpResponse}
object RequestHandler {
def props(ctx: ImperativeRequestContext): Props = Props(new RequestHandler(ctx))
}
class RequestHandler(ctx: ImperativeRequestContext) extends Actor {
import context._
import concurrent.duration._
setReceiveTimeout(30.second)
def receive: Receive = {
case ReceiveTimeout =>
ctx.complete(HttpResponse(500, entity = "timeout"))
stop(self)
case x: AnyRef =>
ctx.complete(HttpEntity(ContentTypes.`application/json`, mapper.get.writeValueAsString(x)))
stop(self)
}
}
我不确定你到底在抱怨什么。喷洒JSON库,因为它是典型的Scala库比Jackson更类型安全。特别是toJson
基于编译时类型而不是符文时类型工作。显然,没有安全的方法可以将任何AnyRef
(又名Object
)转换为JSON,因为该变量后面可能存在任何类型的对象。请考虑以下示例:
val obj: AnyRef = new Thread()
val json = obj.toJson.compactPrint
要喷洒 JSON,此代码看起来与您的示例完全相同。显然,您不能将Thread
写入 JSON。不同之处在于,使用杰克逊,您将获得某种运行时错误。使用Spray JSON,它甚至无法编译。如果您使用一些可以安全地转换为 JSON 的特定类型 - Spray JSON 将为您工作。
如果问题是您希望拥有一些接受参数的泛型方法,并且其中一个步骤将转换为 JSON,则应使用泛型和约束来指定该类型,如下所示:
def foo[T : JsonWriter](bar : T) = {
//do something
bar.toJson.compactPrint
//do something more
}
更新:更现实的示例
这是一个为我编译并按预期运行的示例:
import spray.json._
import DefaultJsonProtocol._
case class Foo(i: Int)
implicit val fooFormat = jsonFormat1(Foo)
case class Bar(ii: Int, ss: String)
implicit val barFormat = jsonFormat2(Bar)
def printJson[T: JsonWriter](obj: T):Unit = {
println(obj.toJson.compactPrint)
}
printJson(Foo(42))
printJson(Bar(123, "this works!"))