将Scala案例类转换为JSON

use*_*610 0 scala

我有两个案例类.主要的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]])
Run Code Online (Sandbox Code Playgroud)

要求是转换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
}
Run Code Online (Sandbox Code Playgroud)

然而,这不起作用.即使Request填充了类,输出也是:

{"parameters":{"underlying":{"some-value":""},"empty":false,"traversableAgain":true},"deps":{"sizeMapDefined":false,"empty":false,"traversableAgain":true}}
Run Code Online (Sandbox Code Playgroud)

将JSON对象映射器与相应的Java类一起使用很简单,但尚未在Scala中使用它.非常感谢任何帮助.

fla*_*ian 5

在某种程度上,杰克逊在Scala中的记忆力更大.您应该使用本机Scala库进行JSON处理,特别是在编译时推导JSON序列化程序时,例如circe.

我知道这并没有直接回答你的问题,但在使用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)
Run Code Online (Sandbox Code Playgroud)

另一方面,在案例类中使用可变映射是非惯用的,并且使用自动生成的copy方法为地图实现不可变操作应该是非常简单的.

case class Request(parameters: Map[String, String] {
  def +(key: String, value: String): Request = {
    this.copy(parameters = parameters + (key -> value))
  }
}
Run Code Online (Sandbox Code Playgroud)

你应该尽可能地避免可变性,看起来在这里避免它根本不会有太多工作.