我有两个案例类。主要的Request
包含两个地图。
第一个映射具有键和值的字符串。
第二个映射有一个字符串键,value是第二个case类的实例KVMapList
。
case class Request (var parameters:MutableMap[String, String] = MutableMap[String, String](), var deps:MutableMap[String, KVMapList] = MutableMap[String, KVMapList]())
case class KVMapList(kvMap:MutableMap[String, String], list:ListBuffer[MutableMap[String, String]])
要求是将Request
转换为JSON表示。
以下代码尝试执行此操作:
import com.fasterxml.jackson.annotation.PropertyAccessor
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility
import com.fasterxml.jackson.databind.ObjectMapper
def test(req:Request):String {
val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.setVisibility(PropertyAccessor.ALL, Visibility.ANY)
var jsonInString: String = null
try {
jsonInString = mapper.writeValueAsString(request)
}
catch {
=case e: IOException => {
e.printStackTrace
}
jsonString
}
然而这不起作用。即使填充了Request
类,输出也是:
{"parameters":{"underlying":{"some-value":""},"empty":false,"traversableAgain":true},"deps":{"sizeMapDefined":false,"empty":false,"traversableAgain":true}}
将JSON对象映射器与相应的Java类一起使用很简单,但尚未在Scala中使用它。非常感谢任何帮助。
答案 0 :(得分:5)
我知道这并没有直接回答你的问题,但是在使用circe之后,我将永远不会回到其他任何地方。
import io.circe.generic.auto._
import io.circe.parser._
import io.circe.syntax._
val req = new Request(...)
val json = req.asJson.noSpaces
val reparsed = decode[Request](json)
另一方面,在案例类中使用可变映射是非惯用的,并且使用自动生成的copy
方法为地图实现不可变操作应该非常简单。
case class Request(parameters: Map[String, String] {
def +(key: String, value: String): Request = {
this.copy(parameters = parameters + (key -> value))
}
}
你应该尽可能地避免可变性,看起来在这里避免它根本不会有太多工作。
答案 1 :(得分:1)
我不确定ScalaObjectMapper
的作用是什么,看起来不是很有用。
如果你在开头添加mapper.registerModule(DefaultScalaModule)
,它应该有效...假设MutableMap
你的意思是mutable.Map
,而不是某种自制类(因为,如果你这样做,你必须自己为它提供一个序列化器。)
(DefaultScalaModule
位于jackson-module-scala库。如果您还没有,请将其添加到您的版本中。