JSON mappnig unxepectable case



早些时候,我在应用程序中使用了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!"))

相关内容

  • 没有找到相关文章

最新更新