JSONにシリアライズする必要がある型のキーを持つスカラマップがあります。オブジェクトの文字列にキー名を必要とするJSONの性質のため、単純なマッピングは直接できません。ジャクソン:任意の非文字列キーを使用した(デ)シリアライズマップ
実装したいのは、マップをJSONにシリアル化する前にセットに変換してから、デシリアライズ後にセットからマップに変換することです。
私は、のキーシリアルシリアを使用して他の方法を知っています。タイプです。 Serialising Map with Jacksonしかし、私は任意のキーの種類に適用されるソリューションが必要です。この点に関しては、セットとバックへの変換は、私には最良の選択肢のように見えます。
MapSerializerModule.scalaを下記のjackson-module-scalaから修正して、ラッパーオブジェクトを使ってSetにシリアライズすることができましたが、JSONを使用して始めたマップにデシリアライズするためには、
シリアライズとデシリアライゼーションの両方をコントロールする必要があるので、JSONの外観は重要ではありません。
case class Wrapper[K, V](
value: Set[(K, V)]
)
class MapConverter[K, V](inputType: JavaType, config: SerializationConfig)
extends StdConverter[Map[K, V], Wrapper[K, V]] {
def convert(value: Map[K, V]): Wrapper[K, V] = {
val set = value.toSet
Wrapper(set)
}
override def getInputType(factory: TypeFactory) = inputType
override def getOutputType(factory: TypeFactory) =
factory.constructReferenceType(classOf[Wrapper[_, _]], inputType.getContentType)
.withTypeHandler(inputType.getTypeHandler)
.withValueHandler(inputType.getValueHandler)
}
object MapSerializerResolver extends Serializers.Base {
val MAP = classOf[Map[_, _]]
override def findMapLikeSerializer(
config: SerializationConfig,
typ: MapLikeType,
beanDesc: BeanDescription,
keySerializer: JsonSerializer[AnyRef],
elementTypeSerializer: TypeSerializer,
elementValueSerializer: JsonSerializer[AnyRef]): JsonSerializer[_] = {
val rawClass = typ.getRawClass
if (!MAP.isAssignableFrom(rawClass)) null
else new StdDelegatingSerializer(new MapConverter(typ, config))
}
}
object Main {
def main(args: Array[String]): Unit = {
val objMap = Map(
new Key("k1", "k2") -> "k1k2",
new Key("k2", "k3") -> "k2k3")
val om = new ObjectMapper()
om.registerModule(DefaultScalaModule)
om.registerModule(ConverterModule)
val res = om.writeValueAsString(objMap)
println(res)
}
}
私はあなたに答えがありません:アノテーションとランタイムリフレクションはすべての悪の源です。その世界を離れて、タイプベースのアプローチに移行する – Edmondo1984