Suche nach einem guten Beispiel für polymorphe Serialisierung Deserialisierung Jacksonfür ein gutes Beispiel für polymorphe Serialisierung Deserialisierung der Suche unter Verwendung von Jackson mit scala
mit scala Verwendung bekam eine Ausnahme:
Exception in thread „main“ Blockquote org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unerkannte Feld "Tiere" (Klasse Zoo), nicht als ignorable markiert
nach dem folgenden Code versuchen:
import org.codehaus.jackson.annotate.{ JsonTypeInfo, JsonSubTypes }
import org.codehaus.jackson.annotate.JsonSubTypes.Type
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include= JsonTypeInfo.As.PROPERTY,
property = "type"
)
@JsonSubTypes(Array(
new Type(value= classOf[Cat] , name = "cat"),
new Type(value= classOf[Dog] , name = "dog")
)
)
abstract class Animal {
val name:String = "NoName"
}
class Cat extends Animal{
val favoriteToy = "edi"
}
class Dog extends Animal{
val breed = "German Shepherd"
val color = "brown"
}
class Zoo {
val animals = new scala.collection.mutable.ListBuffer[Animal]
}
import org.codehaus.jackson.map.ObjectMapper
object Foo {
def main (args:Array[String]) {
val mapper = new ObjectMapper()
mapper.setPropertyNamingStrategy(CamelCaseNamingStrategy)
val source = scala.io.Source.fromFile("input.json")
val input = source.mkString
source.close
val zoo = mapper.readValue(input,classOf[Zoo])
println(mapper.writeValueAsString(zoo))
}
import org.codehaus.jackson.map.introspect.{AnnotatedField, AnnotatedMethod}
import org.codehaus.jackson.map.{MapperConfig, PropertyNamingStrategy}
object CamelCaseNamingStrategy extends PropertyNamingStrategy{
override def nameForGetterMethod (config: MapperConfig[_], method: AnnotatedMethod, defaultName: String) =
{
translate(defaultName)
}
override def nameForSetterMethod (config: MapperConfig[_], method: AnnotatedMethod, defaultName: String) = {
translate(defaultName)
}
override def nameForField (config: MapperConfig[_], field: AnnotatedField, defaultName: String) = {
translate(defaultName)
}
def translate(defaultName:String) = {
val nameChars = defaultName.toCharArray
val nameTranslated = new StringBuilder(nameChars.length*2)
for (c <- nameChars){
if (Character.isUpperCase(c)){
nameTranslated.append("_")
}
nameTranslated.append(Character.toLowerCase(c))
}
nameTranslated.toString
}
}
Datei input.json
{
"animals":
[
{"type":"dog","name":"Spike","breed":"mutt","color":"red"},
{"type":"cat","name":"Fluffy","favoriteToy":"spider ring"}
]
}
Nate, was Jackson-Version und welche Scala-Version haben Sie ausgeführt? Ich bekomme com.fasterxml.jackson.databind.JsonMappingException: Kann keine Instanz von TestJackson $ Animal, Problem erstellen: abstrakte Typen müssen entweder zu konkreten Typen gemappt werden, einen eigenen Deserializer haben oder mit zusätzlichen Typinformationen auf Scala 2.10 instanziiert werden .4 mit dem neuesten Jackson 2.4.3 –
Ich habe meinen Beitrag aktualisiert, um die spezifischen Importe einzuschließen (dieser Fehler klingt wie ein falscher Import). Dies sollte bei allen Versionen von Scala 2.9+ und Jackson 2.2+ (wenn nicht früher) funktionieren. Ich benutzte speziell Scala 2.11.2 und Jackson 2.4.3. Solange ein Jackson-Modul-Scala-Glas für die Kombination gebaut ist, sollte es funktionieren. Sie können sie hier finden: http://search.maven.org/#search%7Cga%7C1%7Cjackson-module-scala – Nate
Großartig, funktioniert jetzt. Vielen Dank! –