Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json 如何使用Jackson将Scala值类序列化为字符串?_Json_Scala_Serialization_Jackson - Fatal编程技术网

Json 如何使用Jackson将Scala值类序列化为字符串?

Json 如何使用Jackson将Scala值类序列化为字符串?,json,scala,serialization,jackson,Json,Scala,Serialization,Jackson,我想使用Scala的值类(或普通的case类)为程序中的某些字符串提供更强的类型。当我使用Jackson序列化这些类的实例时,我希望它们是字符串 例如: case class Brand(name: String) extends AnyVal val brands = Seq(Brand("Coke"), Brand("Disney")) val brandCount = Map(Brand("Coke") -> 5, Brand("Disney") -> 10) 由于Brand

我想使用Scala的值类(或普通的case类)为程序中的某些字符串提供更强的类型。当我使用Jackson序列化这些类的实例时,我希望它们是字符串

例如:

case class Brand(name: String) extends AnyVal
val brands = Seq(Brand("Coke"), Brand("Disney"))
val brandCount = Map(Brand("Coke") -> 5, Brand("Disney") -> 10)
由于
Brand
只是字符串的包装,因此我希望这些变量对应的JSON序列化为:

brands:     ["Coke", "Disney"]
brandCount: {"Coke": 5, "Disney": 10}
默认情况下,我得到:

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule

val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)

println(mapper.writeValueAsString(brands))
// ==> [{"name":"Coke"},{"name":"Disney"}]
println(mapper.writeValueAsString(brandCount))
// ==> {"Brand(Coke)":5,"Brand(Disney)":10}
我能想到的最好办法是为
品牌定义一个自定义序列化程序和键序列化程序

import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.databind.JsonSerializer
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.core.JsonGenerator

class BrandSerializer extends JsonSerializer[Brand] {
  override def serialize(
    b: Brand,
    json: JsonGenerator,
    provider: SerializerProvider
  ): Unit = {
    json.writeString(b.name)
  }
}

class BrandKeySerializer extends JsonSerializer[Brand] {
  override def serialize(
    b: Brand, 
    json: JsonGenerator,
    provider: SerializerProvider
  ): Unit = {
    json.writeFieldName(b.name)
  }
}

val serializers = new SimpleModule("Serializers");
serializers.addSerializer(classOf[Brand], new BrandSerializer())
serializers.addKeySerializer(classOf[Brand], new BrandKeySerializer());

val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
mapper.registerModule(serializers)

println(mapper.writeValueAsString(brands))
// ==> ["Coke","Disney"]
println(mapper.writeValueAsString(brandCount))
// ==> {"Coke":5,"Disney":10}

有没有更好(或更不详细)的方法将这些值类(或任何case类)序列化为字符串?

好吧,我不认为,有什么方法可以让它做你想要的一切,一次就不需要任何东西。。。 你能想到的最好的办法是用
Product1
替换
Brand
,用
b.name
替换
b.。_1
(我还认为,你的密钥序列化程序是错误的——它应该写出
b.getClass.getSimpleName
,而不是
b.name

这不会减少编写单个类的冗长,但至少可以消除为每种类型创建单独序列化程序的需要


当然,缺点是每一个field case类最终都会以这种方式编写,这可能比您希望的要多。

使用jackson是一种要求吗?是的,我使用的框架使用jackson呈现HTTP JSON响应。