Json 如何将自定义封送拆收器添加到akka http?
作为scala和akka http的初学者,我正在尝试连接到序列化过程中 该项目使用akka@2.5.2和阿克卡-http@10.0.10“。此外,它还包含Json 如何将自定义封送拆收器添加到akka http?,json,scala,marshalling,spray,akka-http,Json,Scala,Marshalling,Spray,Akka Http,作为scala和akka http的初学者,我正在尝试连接到序列化过程中 该项目使用akka@2.5.2和阿克卡-http@10.0.10“。此外,它还包含akka-http-spray-json依赖项 在代码库中,我们使用Java.Util.Currency(它可能已被弃用,这并不重要,因为我仍然想知道如何添加自定义封送拆收器。) 给定此示例控制器: def getCurrencyExample: Route = { path("currencyExample") { va
akka-http-spray-json
依赖项
在代码库中,我们使用Java.Util.Currency
(它可能已被弃用,这并不重要,因为我仍然想知道如何添加自定义封送拆收器。)
给定此示例控制器:
def getCurrencyExample: Route = {
path("currencyExample") {
val currency: Currency = Currency.getInstance("EUR")
val code: String = currency.getCurrencyCode
val shouldBeFormated = collection.immutable.HashMap(
"currencyCode" -> code,
"currencyObject" -> currency
)
complete(shouldBeFormated)
}
}
我得到这样一个响应,其中currency对象变为空:
{
currencyObject: { },
currencyCode: "EUR",
}
我预计会出现以下情况:
{
currencyObject: "EUR",
currencyCode: "EUR",
}
currency
对象应该转换为JSON字符串。由于我不想手动转换每个响应,所以我想挂接到编组过程中,并在后台完成
我只想为Java.Util.Currency
对象添加一个自定义marhaller,但即使是我也不确定如何继续。
这里描述了多种方法,我不确定哪种方法适合我的需要,或者从哪里开始
我尝试创建自己的
CurrencyJsonProtocol
:
package com.foo.api.marshallers
import java.util.Currency
import spray.json.{DefaultJsonProtocol, JsString, JsValue, RootJsonFormat}
object CurrencyJsonProtocol extends DefaultJsonProtocol {
implicit object CurrencyJsonFormat extends RootJsonFormat[Currency] {
override def read(json: JsValue): Currency = {
Currency.getInstance(json.toString)
}
override def write(obj: Currency): JsValue = {
JsString(obj.getCurrencyCode)
}
}
}
然而,仅仅是文件的存在就破坏了我的项目:
[error] RouteDefinitons.scala:90:16: type mismatch;
[error] found : scala.collection.immutable.HashMap[String,java.io.Serializable]
[error] required: akka.http.scaladsl.marshalling.ToResponseMarshallable
[error] complete(shouldBeFormated)
[error] ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
我也不知道为什么。(由于我的包名被称为
marshaller
,它崩溃了。这完全破坏了项目的编译。你有JsonFormat[Currency]
?如果有,请修复它
如果没有,则应遵循以下步骤并创建:
案例类CurrencyResult(货币:货币,代码:字符串)
trait JsonSupport
中:aJsonFormat[Currency]
trait JsonSupport
中:aJsonFormat[CurrencyResult]
作为上述第1点的替代方案,您可能可以将地图键入为:
map[String,JsValue]
我使用Spray支持已有多年。也许我应该尝试另一种。无论如何,在Spray中,类型的自定义格式化程序很简单。例如squants.market.currency
据我所知,你有所有的部分,你只需要把它们放在一起 Spray json支持封送常见类型,如Int、String、Boolean、List、Map等。但它不知道如何封送“Currency”。为了解决这个问题,您已经为“Currency”对象创建了一个自定义封送器。您只需将其插入正确的位置。您所要做的就是从
Curre导入封送器ncyJsonProtocol
插入控制器,如下所示:
import CurrencyJsonProtocol.\uu
此外,请确保您还具有以下导入:
导入spray.httpx.SprayJsonSupport_
导入spray.json.DefaultJsonProtocol.\uz
你应该会自动把它捡起来
要了解它是如何工作的,您需要了解scala中的。虽然像我这样来自java世界的人看起来很神奇,但我可以向您保证这对我没有帮助。这对我没有帮助,因为它假定了一些我不具备的知识。您能解释一下吗?此外,我想对任何Case类中的任何货币对象进行操作no m请查看我的更新问题,因为我尝试使用自定义JsonProtocol,但它破坏了我的项目,我不知道原因。这是因为序列化程序不在范围内。只需导入它,它就应该编译。使用Spray,您应该扩展SprayJsonSupport。请注意,您应该添加依赖库Dependencies+=”com.typesafe.akka“%%”akka http spray json“%”10.1.1"我不完全确定这是问题所在。你看到我更新的问题了吗?json转换必须有一些类型信息。但是,使用HashMap会丢失这些类型信息。这就是为什么我建议你在我的回答中使用
case类
,这样你就不会丢失所需的类型编队,以多写一个JsonFormat
为代价。刚刚更新了我的answer@FredericA我有很多响应对象,都是case类,其中很多都有不同嵌套级别和顺序的currency对象。hash映射只是一个例子来展示这个问题。我想要currency对象无论类出现在何处,都要在任何情况下转换。当前,我只得到{}
。从我目前的理解来看,似乎我必须为每个case类创建一个看似冗余和冗长的封送拆收器。您必须为每个case类创建一个JsonFormat
,是的。但是,对于Currency
等成员,您只需编写一次JsonFormat
,它们将通过隐式解析。单独编写每个JsonFormat
被认为是正常的,因为它们代表了模块/应用程序的公共接口。也就是说,我仍然不明白为什么您的货币
被格式化为{}
您已经有了JsonFormat
吗?
import squants.market.{ Currency, Money }
import squants.market._
trait MoneyJsonProtocol extends DefaultJsonProtocol {
implicit object CurJsonFormat extends JsonFormat[Currency] {
def write(currency: Currency): JsValue = JsString(currency.code)
def read(value: JsValue): Currency = value match {
case JsString(currency) =>
defaultCurrencyMap.get(currency) match {
case Some(c) => c
case None => // throw an exception, for example
}
case _ => // throw another exception, for example
}
}
implicit def toJavaBigDecimal(b: math.BigDecimal): java.math.BigDecimal = b.underlying
}