我是Scala的新手,在这里我正在尝试创建一个基于Argonaut的通用json转换器.我试图搜索谷歌和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 } } }
我想要做的是概括,以便我不需要为将来添加的每个新模型类(如本例中的Currency和Person)添加匹配项.
Argonaut已经具有通用编码和解码功能.
例如,Parse.decodeOption
将String解析为您具有编解码器的任何类型.
你要做的是在运行时决定你是否有一个类型的编解码器,但你可以让编译器为你解决这个问题.
是否可以解码为类型T
取决于是否存在DecodeJson[T]
范围内的隐式实例.(这是一个超类型CodecJson[T]
,你写了几个,所以他们很好.)
不幸的是,编译器不会为您推断出这个约束,因此您必须在类型签名中提及它.一种方法是使用上下文绑定,这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]
.