组合类中的多态lift

编程入门 行业动态 更新时间:2024-10-24 12:25:58
本文介绍了组合类中的多态lift-json反序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在尝试使用Lift-Json将json对象自动反序列化为scala类,并且内部使用一个坐标类来存储GeoJson信息.

I am trying to automatically deserialize json object to a scala class using Lift-Json with a coordinate class inside used to store GeoJson information.

case class Request(name:String, geometry:Geometry) sealed abstract class Geometry case class Point(coordinates:(Double,Double)) extends Geometry case class LineString(coordinates:List[Point]) extends Geometry case class Polygon(coordinates:List[LineString]) extends Geometry

我想反序列化这样的json字符串:

I want to deserialize a json string like this:

{ name:"test", geometry:{ "type": "LineString", "coordinates": [ [100.0, 0.0], [101.0, 1.0] ] } }

进入Request案例类,并在Geometry字段中使用正确的LineString运行时类.我想我应该使用TypeHint,但是如何?这是正确的方法还是我应该创建三个不同的请求(RequestPoint,RequestLineString和RequestPolygon)? 这将是反序列化的Scala代码:

into a Request case class with the right LineString runtime class in the Geometry field. I guess I should use a TypeHint but how?. Is this the correct approach or should I create three different Request (RequestPoint,RequestLineString and RequestPolygon)? This would be the Scala code to deserialize:

val json = parse(message) json.extract[Request]

推荐答案

是的,您需要对诸如Geometry之类的求和类型使用类型提示.这是一个示例:

Yes, you need to use type hints for sum types like Geometry. Here's one example:

implicit val formats = DefaultFormats.withHints(ShortTypeHints(List(classOf[Point], classOf[LineString], classOf[Polygon]))) val r = Request("test", LineString(List(Point(100.0, 0.0), Point(101.0, 1.0)))) Serialization.write(r) { "name":"test", "geometry":{ "jsonClass":"LineString", "coordinates":[{"jsonClass":"Point","coordinates":{"_1$mcD$sp":100.0,"_2$mcD$sp":0.0}},{"jsonClass":"Point","coordinates":{"_1$mcD$sp":101.0,"_2$mcD$sp":1.0}}]} }

并不是您想要的.由于要更改Point的默认序列化方案,因此需要为该类型提供一个自定义序列化器.

Not quite what you wanted. Since you want to change the default serialization scheme for Points, you need to provide a custom serializer for that type.

class PointSerializer extends Serializer[Point] { private val Class = classOf[Point] def deserialize(implicit format: Formats) = { case (TypeInfo(Class, _), json) => json match { case JArray(JDouble(x) :: JDouble(y) :: Nil) => Point(x, y) case x => throw new MappingException("Can't convert " + x + " to Point") } } def serialize(implicit format: Formats) = { case p: Point => JArray(JDouble(p.coordinates._1) :: JDouble(p.coordinates._2) :: Nil) } } // Configure it implicit val formats = DefaultFormats.withHints(ShortTypeHints(List(classOf[Point], classOf[LineString], classOf[Polygon]))) + new PointSerializer Serialization.write(r) { "name":"test", "geometry":{ "jsonClass":"LineString", "coordinates":[[100.0,0.0],[101.0,1.0]] } }

更好,但如果您需要将名为"jsonClass"的默认字段更改为类型",则还需要进行其他配置:

Better, but you need one more configuration if you need to change the default field named as 'jsonClass' to 'type':

implicit val formats = new DefaultFormats { override val typeHintFieldName = "type" override val typeHints = ShortTypeHints(List(classOf[Point], classOf[LineString], classOf[Polygon])) } + new PointSerializer Serialization.write(r) { "name":"test", "geometry":{ "type":"LineString", "coordinates":[[100.0,0.0],[101.0,1.0]] } }

更多推荐

组合类中的多态lift

本文发布于:2023-08-04 06:01:24,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1293596.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:组合   类中   多态   lift

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!