gpt4 book ai didi

json - 使用 Argonaut 创建通用 JSON 转换器

转载 作者:行者123 更新时间:2023-12-02 22:36:41 24 4
gpt4 key购买 nike

我是 Scala 新手,在这里我尝试创建一个基于 Argonaut 的通用 json 转换器。我尝试在 google 和 stackoverflow 上搜索,但到目前为止我还没有任何线索。

这是我的代码片段。

import org.springframework.http.converter.AbstractHttpMessageConverter
import org.springframework.http.{MediaType, HttpInputMessage, HttpOutputMessage}
import scala.io.Source
import argonaut._,Argonaut._

case class Currency(code: String)
object Currency {
implicit def CurrencyCodecJson: CodecJson[Currency] = casecodec1(Currency.apply, Currency.unapply)("code")
}

case class Person(firstName: String, lastName: String)
object Person {
implicit def PersonCodecJson: CodecJson[Person] = casecodec2(Person.apply, Person.unapply)("firstName", "LastName")
}

class ArgonautConverter extends AbstractHttpMessageConverter[Object](new MediaType("application", "json", Charset.forName("UTF-8")), new MediaType("application", "*+json", Charset.forName("UTF-8"))) {
val c = classOf[Currency]
val p = classOf[Person]

def writeInternal(t: Object, outputStream: OutputStream) = {
val jsonString = t match {
case c:Currency => c.asJson.ToString()
case p:Person => p.asJson.ToString()
}

def supports(clazz: Class[_]): Boolean = clazz.isAssignableFrom(classOf[CodecJson])// clazz == classOf[Currency] || clazz == classOf[LegalEntity]

def readInternal(clazz: Class[_ <: Object], inputStream: InputStream): Object = {
val jsonString = Source.fromInputStream(inputStream).getLines.mkString
val jsonObject = clazz match {
case `c` => jsonString.decodeOption[Currency]
case `p` => jsonString.decodeOption[Person]
}
jsonObject match {
case Some(j) => j
case None => null
}
}
}

我想做的是概括,这样我就不需要为将来添加的每个新模型类(例如本例中的货币和个人)不断添加匹配。

最佳答案

Argonaut 已经具备通用的编码和解码功能。

例如,Parse.decodeOption会将字符串解析为您拥有编解码器的任何类型。

您要做的是在运行时决定是否有某种类型的编解码器,但您可以让编译器为您计算出这一点。

是否可以解码为类型 T 取决于范围内是否存在 DecodeJson[T] 的隐式实例。 (这是 CodecJson[T] 的父类(super class)型,您已经编写了其中几个,所以它们很好。)

不幸的是,编译器不会为您推断此约束,因此您必须在类型签名中提及它。实现此目的的一种方法是使用上下文绑定(bind),即下面示例中的T : DecodeJson

def read[T : DecodeJson](inputStream: InputStream): Option[T] = {
val jsonString = Source.fromInputStream(inputStream).getLines.mkString
Parse.decodeOption(jsonString)
}

(另外,请注意,您应该真正返回 Option[T] 而不是使用 null。)

类似地,write 可以使用签名来实现:

def write[T : EncodeJSON](t: T, outputStream: OutputStream)

您的 CodecJson[T] 实例也是 EncodeJson[T] 的实例。

关于json - 使用 Argonaut 创建通用 JSON 转换器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20897157/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com