2016-08-02 14 views
2

Ich habe json das enthält:Gson: Deserialize Json in abstrakte Klasse

{"timeZone": "America/Los_Angeles"} 

unter vielen anderen Tasten, und ich möchte es in java.util.TimeZone deserialisieren. TimeZone ist nur ein Feld in einer Klasse, die ich mit diesem json instanziieren möchte.

Das Problem ist, dass TimeZone eine abstrakte Klasse ist, und es sollte mit instanziert werden:

public static synchronized TimeZone getTimeZone(String ID) { 
     return getTimeZone(ID, true); 

, die eine konkrete Klasse verwendet ZoneInfo zu instanziiert. Der Deserializer ruft jedoch standardmäßig den Konstruktor TimeZone auf. Also habe ich:

java.lang.RuntimeException: Failed to invoke public java.util.TimeZone() with no args 

Ich frage mich, wie Gson zu konfigurieren, dass ein TimeZone aus der obigen json instanziiert?

+0

haben Sie versucht, nicht abstrakte Klasse wie SimpleTimeZone zu verwenden? – JAVAC

+0

Id Gefahr, dies zu sagen ist nicht möglich. Der Serializer muss instanziiert werden, um den Ausgabewert zu erstellen, und abstrakte Klassen können nicht instanziiert werden. – Felype

+0

@JAVAC Das kommt aus einer Bibliotheksklasse, die ich leider nicht ändern kann. –

Antwort

5

Sie benötigen würde so etwas wie ein Gson TypeAdapter und registrieren Sie es mit Ihren Gson Instanz zu erstellen.

Ich bin mir nicht sicher, wie/ob dies für Ihr spezielles Datenformat arbeiten, aber hier ist ein Beispiel, das ich in meinen eigenen Projekten verwendet habe:

public class TimeZoneAdapter extends TypeAdapter<TimeZone> { 
    @Override 
    public void write(JsonWriter out, TimeZone value) throws IOException { 
    out.value(value.getID()); 
    } 

    @Override 
    public TimeZone read(JsonReader in) throws IOException { 
    return TimeZone.getTimeZone(in.nextString()); 
    } 
} 

Sie würden es dann registrieren, wenn ein Gebäude Gson Instanz wie folgt:

GsonBuilder builder = new GsonBuilder(); 
builder.registerTypeAdapter(TimeZone.class, new TimeZoneAdapter()); 

Gson gson = builder.create(); 

Hoffe, das hilft!

0

Sie haben InstanceCreator

private class TimeZoneInstanceCreator implements InstanceCreator<TimeZone> { 
    public TimeZone createInstance(Type type) { 
     return TimeZone.getTimeZone("America/Los_Angeles");; 
    } 
} 

erstellen und es dann registrieren:

gson.registerTypeAdapter(TimeZone.class, new TimeZoneInstanceCreator()); 
+0

Ich glaube nicht, dass ich den Wert "Amerika/Los_Angeles" hart codieren kann. Es sollte der von json übergebene Wert sein, oder? –

+1

Das ist falsch. Ein 'InstanceCreator' soll nur die Instanz erzeugen. Gson folgt dann seinem regulären Fluss, um Felder aus dem JSON zu setzen. Das ist nicht, was hier gefragt wird. –