我想使用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
只是String的包装器,我希望这些变量的相应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}
我能想到的最好的方法是为Brand
定义自定义序列化程序和密钥序列化程序:
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}
是否有更好(或更简洁)的方法将这些值类(或任何案例类)序列化为字符串?
答案 0 :(得分:0)
嗯,我不认为,有一种方法可以让它做你想做的一切,没有什么是你不想一气呵成的......
我想到的最好的事情就是将Brand
替换为Product1
,将b.name
替换为b._1
(我也认为,您的密钥序列化程序是错误的 - 它应该是写出b.getClass.getSimpleName
,而不是b.name
)。
对于写出单个类而言,这并不会使它更加冗长,但至少可以消除为每种类型创建单独的序列化器的需要。
当然,缺点是每个单场案例类最终会以这种方式编写,这可能比你想要的更多......