2012-07-19 7 views
6

Ich stehe vor den folgenden Problemen. Als Jackson Serializer übergeben wird ein primitiver gewickelt für die Serialisierung, diese primitive serialisiert wie zum Beispiel:Serialisierung von primitiven Stammobjekten mit Jackson

objectMapper = new ObjectMapper(); 

StringWriter w = new StringWriter(); 
objectMapper.writeValue(w, Integer.valueOf(10)); 
System.out.println(w.toString()); 

produziert 10 als Ausgabe. 10 ist jedoch kein gültiger JSON (nach jsonlint) und sollte entweder in eckige Klammern ([10], also ein Einzelelement-Array) oder in geschweifte Klammern ({value:10}, also ein Objekt mit Dummy-Eigenschaft) gehüllt werden. . Das Problem betrifft Zahlen, java.lang.String, java.util.Date, ...

Meine Frage ist: Wie mache ich Jackson, um die Verpackung durchzuführen? Sollte Jackson nicht immer einen gültigen JSON produzieren?

Ich habe Jackson Verhalten mit SerializationConfig.Feature.WRAP_ROOT_VALUE aktiviert analysiert: es funktioniert nicht wie ich es erwarte. Primitive werden jetzt zu gültigem JSON ({"Integer":10}) serialisiert, aber "normale" Java-Beans werden auch umgebrochen, was unerwünscht ist ({"MyBean":{"field":value, ...}} statt).

Wenn jemand Jackson anpassen kann, vielleicht mit benutzerdefinierten Serializer. Die Schwierigkeit bestünde darin, dass der Root-Primitive-Wrapper (der umbrochen werden muss) von der Bean-Primitiv-Eigenschaft (muss nicht umhüllt werden) unterschieden werden muss.

Um die Geschichte zu vervollständigen: Jackson Serializer wird als Nachrichtenkonverter für Spring MVC verwendet, und ich bezweifle, dass es ziemlich einfach ist, einen Haken zum Abfangen von Serialisierung von Primitiven schreiben (die Jackson nicht aufrufen wird aber einfach "[" + String.toString(obj) + "]" zurückgeben). Also würde ich die Lösung mit abgestimmtem Jackson vorziehen.

+0

Ich empfehle, eine Verbesserungsanfrage unter https://github.com/FasterXML/jackson-databind/issues zu protokollieren –

Antwort

3

schließlich der Brauch Serializer

import java.io.IOException; 

import org.codehaus.jackson.JsonGenerationException; 
import org.codehaus.jackson.JsonGenerator; 
import org.codehaus.jackson.map.SerializerProvider; 
import org.codehaus.jackson.map.ser.std.ScalarSerializerBase; 

public class NumberSerializer extends ScalarSerializerBase<Number> { 

    protected NumberSerializer() { 
     super(Number.class); 
    } 

    @Override 
    public void serialize(Number value, JsonGenerator jgen, SerializerProvider provider) throws IOException, 
       JsonGenerationException { 
     if (jgen.getOutputContext().inRoot()) { 
      jgen.writeStartArray(); 
      jgen.writeNumber(value.longValue()); 
      jgen.writeEndArray(); 
     } 
     else { 
      jgen.writeNumber(value.longValue()); 
     } 
    } 
} 

hat einen Job für mich. Der Serializer kann als Modul registriert werden (siehe here).

Hinweis bei der Verwendung dieses Seriazier: Da es alle primitiven in primitive Arrays mit nur einem Element verwandelt, bricht das Reflexionsprinzip in einem Sinne, dass A primitiv ist.

Verwandte Themen