Die Registrierung mehrere Adapter mit GSON nicht funktioniert
Ich habe ein Problem die Registrierung mehrere typeAdapters mit meinem GsonBuilder. Scheint, wie nur ein Feuer aus, und es nimmt nie die zweite in Erwägung. Wenn ich es mit einem jeden von selbst, es scheint zu funktionieren. Aber ich brauche Sie für die Arbeit mit beiden und scheint, dass ich etwas falsch machen. Auch ich bin derzeit mit GSON v2.2.4.
Zip-Objekt einfache form:
public class Zip {
private String zipCode;
private String city;
private String state;
public Zip(){}
}
ZipSerializer:
public class ZipSerializer implements JsonSerializer<Zip>{
@Override
public JsonElement serialize(Zip obj, Type type, JsonSerializationContext jsc) {
Gson gson = new Gson();
JsonObject jObj = (JsonObject)gson.toJsonTree(obj);
jObj.remove("state");
return jObj;
}
}
JsonResponse Objekt einfache form:
public class JsonResponse {
private String jsonrpc = "2.0";
private Object result = null;
private String id = null;
public JsonResponse(){}
}
JsonResponseSerializer:
public class JsonResponseSerializer implements JsonSerializer<JsonResponse> {
@Override
public JsonElement serialize(JsonResponse obj, Type type, JsonSerializationContext jsc) {
Gson gson = new Gson();
JsonObject jObj = (JsonObject)gson.toJsonTree(obj);
jObj.remove("id");
return jObj;
}
}
Test Beispiel:
public class Test {
public static void main(String[] args) {
Zip zip = new Zip();
zip.setCity("testcity");
zip.setState("OH");
zip.setZipCode("12345");
JsonResponse resp = new JsonResponse();
resp.setId("1");
resp.setResult(zip);
resp.setJsonrpc("2.0");
Gson gson1 = new GsonBuilder()
.registerTypeAdapter(JsonResponse.class, new JsonResponseSerializer())
.registerTypeAdapter(Zip.class, new ZipSerializer())
.setPrettyPrinting()
.create();
String json = gson1.toJson(resp);
System.out.println(json);
}
}
Ausgabe:
{
"jsonrpc": "2.0",
"result": {
"zipCode": "12345",
"city": "testcity",
"state": "OH"
}
}
Erwartete Ausgabe: (Hinweis ZipSerializer nicht Feuer aus)
{
"jsonrpc": "2.0",
"result": {
"zipCode": "12345",
"city": "testcity"
}
}
Ich simpled-down-test-Fall für diese. Ich weiß, dass ich verwenden können, exclusionStrategy in diesem Beispiel, um Ergebnisse zu erzielen, aber das eigentliche Problem ist viel komplexer, und dies war der beste Weg für mich zu porträtieren und replizieren mein Problem.
Dank
<---------------------------- LÖSUNG ------------------------------->
Habe ich es geschafft zu Lesen Gson benutzerdefinierte seralizer für eine variable (von vielen) in einem Objekt mit TypeAdapter und es half mir sehr.
Erstellte ich eine base customTypeAdapterFactory und dann verlängert es für jede Klasse, benötigt Besondere Serialisierung.
CustomizedTypeAdapterFactory
public abstract class CustomizedTypeAdapterFactory<C> implements TypeAdapterFactory {
private final Class<C> customizedClass;
public CustomizedTypeAdapterFactory(Class<C> customizedClass) {
this.customizedClass = customizedClass;
}
@SuppressWarnings("unchecked") //we use a runtime check to guarantee that 'C' and 'T' are equal
public final <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
return type.getRawType() == customizedClass
? (TypeAdapter<T>) customizeMyClassAdapter(gson, (TypeToken<C>) type)
: null;
}
private TypeAdapter<C> customizeMyClassAdapter(Gson gson, TypeToken<C> type) {
final TypeAdapter<C> delegate = gson.getDelegateAdapter(this, type);
final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
return new TypeAdapter<C>() {
@Override public void write(JsonWriter out, C value) throws IOException {
JsonElement tree = delegate.toJsonTree(value);
beforeWrite(value, tree);
elementAdapter.write(out, tree);
}
@Override public C read(JsonReader in) throws IOException {
JsonElement tree = elementAdapter.read(in);
afterRead(tree);
return delegate.fromJsonTree(tree);
}
};
}
/**
* Override this to muck with {@code toSerialize} before it is written to
* the outgoing JSON stream.
*/
protected void beforeWrite(C source, JsonElement toSerialize) {
}
/**
* Override this to muck with {@code deserialized} before it parsed into
* the application type.
*/
protected void afterRead(JsonElement deserialized) {
}
}
ZipTypeAdapterFactory (Tat dies, um mit JsonResponseTypeAdapterFactory)
public class ZipTypeAdapterFactory extends CustomizedTypeAdapterFactory<Zip> {
ZipTypeAdapterFactory() {
super(Zip.class);
}
@Override
protected void beforeWrite(Zip source, JsonElement toSerialize) {
JsonObject obj = (JsonObject) toSerialize;
obj.remove("state");
}
}
Test-Code:
Gson gson1 = new GsonBuilder()
.registerTypeAdapterFactory(new JsonResponseTypeAdapterFactory())
.registerTypeAdapterFactory(new ZipTypeAdapterFactory())
.setPrettyPrinting()
.create();
String json = gson1.toJson(resp);
System.out.println(json);
Danke an alle für die Hilfe.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Problem in Ihrem
JsonResponseSerializer
. Erstellen Sie eine neue Gson Instanz, dann wird auf diese neue InstanzZipSerializer
ist nicht registriert. Das ist, warum Sie Ihren zweiten serializer wird nie aufgerufen.Wenn Sie erreichen wollen, delegation und komplexe Serialisierung, Blick auf
TypeAdapterFactory
.Als Sie sagte, wenn Sie wollen einfach filtern Felder von der Serialisierung definieren
ExclusionStrategy
.