2017-05-10 31 views
1

我想使用Scala的值類(或正常情況下的類)給我的程序中的某些字符串提供更強的類型。當我使用Jackson序列化這些類的實例時,我希望它們是字符串。如何使用Jackson將Scala值類作爲字符串序列化?

例如:

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} 

我能想到的最好的是定義一個自定義序列化程序和對於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

是利用傑克遜的要求? – Josef

+0

是的,我正在使用一個框架,呈現使用傑克遜的HTTP JSON響應。 – Ryan

回答

0

嗯,我不認爲,有辦法讓它做你想做的一切,沒有你不想在一起去... 你可以做的最好的事情想到的是替換BrandProduct1b.nameb._1(我也認爲,你的關鍵串行器是錯誤的 - 它應該寫出b.getClass.getSimpleName,而不是b.name)。

這不會使寫出單個類的過程變得冗長,但至少可以消除爲每種類型創建單獨的序列化程序的需要。

的缺點,當然,是單場測試用例類最終會這樣寫,這可能比你想什麼..更多

相關問題