457 Stimmen

Gson: Wie kann man bestimmte Felder von der Serialisierung ohne Annotationen ausschließen?

Ich versuche, Gson zu lernen, und habe Probleme mit dem Feldausschluss. Hier sind meine Klassen

public class Student {    
  private Long                id;
  private String              firstName        = "Philip";
  private String              middleName       = "J.";
  private String              initials         = "P.F";
  private String              lastName         = "Fry";
  private Country             country;
  private Country             countryOfBirth;
}

public class Country {    
  private Long                id;
  private String              name;
  private Object              other;
}

Ich kann den GsonBuilder verwenden und eine ExclusionStrategy für einen Feldnamen hinzufügen wie firstName o country aber ich scheine es nicht zu schaffen, Eigenschaften bestimmter Felder auszuschließen, wie country.name .

Anwendung der Methode public boolean shouldSkipField(FieldAttributes fa) enthält FieldAttributes nicht genügend Informationen, um das Feld mit einem Filter wie country.name .

P.S.: Ich möchte Anmerkungen vermeiden, da ich dies verbessern und RegEx verwenden möchte, um Felder herauszufiltern.

bearbeiten : Ich versuche zu sehen, ob es möglich ist, das Verhalten von Struts2 JSON-Plugin

mit Gson

<interceptor-ref name="json">
  <param name="enableSMD">true</param>
  <param name="excludeProperties">
    login.password,
    studentList.*\.sin
  </param>
</interceptor-ref>

Bearbeiten: Ich habe die Frage mit folgendem Zusatz erneut gestellt:

Ich habe ein zweites Feld desselben Typs hinzugefügt, um das Problem weiter zu klären. Im Grunde möchte ich Folgendes ausschließen country.name aber nicht countrOfBirth.name . Ich möchte auch Land als Typ nicht ausschließen. Die Typen sind also dieselben, es ist die tatsächliche Stelle im Objektdiagramm, die ich genau bestimmen und ausschließen möchte.

9voto

MadMurdok Punkte 560

Ich habe diese Strategie angewandt: Ich habe jedes Feld ausgeschlossen, das no markiert mit @SerialisierterName Bemerkung, d.h.:

public class Dummy {

    @SerializedName("VisibleValue")
    final String visibleValue;
    final String hiddenValue;

    public Dummy(String visibleValue, String hiddenValue) {
        this.visibleValue = visibleValue;
        this.hiddenValue = hiddenValue;
    }
}

public class SerializedNameOnlyStrategy implements ExclusionStrategy {

    @Override
    public boolean shouldSkipField(FieldAttributes f) {
        return f.getAnnotation(SerializedName.class) == null;
    }

    @Override
    public boolean shouldSkipClass(Class<?> clazz) {
        return false;
    }
}

Gson gson = new GsonBuilder()
                .setExclusionStrategies(new SerializedNameOnlyStrategy())
                .create();

Dummy dummy = new Dummy("I will see this","I will not see this");
String json = gson.toJson(dummy);

Sie gibt zurück

{"VisibleValue": "Das werde ich sehen"}

7voto

Damian Punkte 7962

Ein anderer Ansatz (besonders nützlich, wenn Sie eine Entscheidung zum Ausschluss eines Feldes zur Laufzeit treffen müssen) besteht darin, einen TypeAdapter mit Ihrer gson-Instanz zu registrieren. Beispiel unten:

Gson gson = new GsonBuilder()
.registerTypeAdapter(BloodPressurePost.class, new BloodPressurePostSerializer())

Im folgenden Fall würde der Server einen von zwei Werten erwarten, aber da es sich bei beiden um Ints handelt, würde Gson beide serialisieren. Mein Ziel war es, jeden Wert auszulassen, der Null (oder weniger) aus dem Json ist, der an den Server gesendet wird.

public class BloodPressurePostSerializer implements JsonSerializer<BloodPressurePost> {

    @Override
    public JsonElement serialize(BloodPressurePost src, Type typeOfSrc, JsonSerializationContext context) {
        final JsonObject jsonObject = new JsonObject();

        if (src.systolic > 0) {
            jsonObject.addProperty("systolic", src.systolic);
        }

        if (src.diastolic > 0) {
            jsonObject.addProperty("diastolic", src.diastolic);
        }

        jsonObject.addProperty("units", src.units);

        return jsonObject;
    }
}

3voto

j2emanue Punkte 56131

In Kotlin kann @Transient verwendet werden, um das Feld zu ignorieren... z. B.

data class MyClass{
@Transient var  myVar: Boolean
//....
}

1voto

devitoper Punkte 41

Ich arbeite nur, indem ich die @Expose Bemerkung, hier meine Version, die ich verwende

compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'

En Model Klasse:

@Expose
int number;

public class AdapterRestApi {

In der Adapter Klasse:

public EndPointsApi connectRestApi() {
    OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(90000, TimeUnit.SECONDS)
            .readTimeout(90000,TimeUnit.SECONDS).build();

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(ConstantRestApi.ROOT_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build();

    return retrofit.create  (EndPointsApi.class);
}

1voto

Michał Ziobro Punkte 9219

Ich habe Kotlin Version

@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD)
internal annotation class JsonSkip

class SkipFieldsStrategy : ExclusionStrategy {

    override fun shouldSkipClass(clazz: Class<*>): Boolean {
        return false
    }

    override fun shouldSkipField(f: FieldAttributes): Boolean {
        return f.getAnnotation(JsonSkip::class.java) != null
    }
}

und wie Sie dies zu Retrofit GSONConverterFactory hinzufügen können:

val gson = GsonBuilder()
                .setExclusionStrategies(SkipFieldsStrategy())
                //.serializeNulls()
                //.setDateFormat(DateFormat.LONG)
                //.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
                //.setPrettyPrinting()
                //.registerTypeAdapter(Id.class, IdTypeAdapter())
                .create()
        return GsonConverterFactory.create(gson)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X