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.

18voto

Klaudia Rzewnicka Punkte 207

Sie können den json-Baum mit gson erkunden.

Versuchen Sie so etwas wie dies:

gson.toJsonTree(student).getAsJsonObject()
.get("country").getAsJsonObject().remove("name");

Sie können auch einige Eigenschaften hinzufügen:

gson.toJsonTree(student).getAsJsonObject().addProperty("isGoodStudent", false);

Getestet mit gson 2.2.4.

17voto

Domenic D. Punkte 5080

Ich habe eine Klassenfabrik entwickelt, um diese Funktionalität zu unterstützen. Geben Sie eine beliebige Kombination von Feldern oder Klassen ein, die Sie ausschließen möchten.

public class GsonFactory {

    public static Gson build(final List<String> fieldExclusions, final List<Class<?>> classExclusions) {
        GsonBuilder b = new GsonBuilder();
        b.addSerializationExclusionStrategy(new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes f) {
                return fieldExclusions == null ? false : fieldExclusions.contains(f.getName());
            }

            @Override
            public boolean shouldSkipClass(Class<?> clazz) {
                return classExclusions == null ? false : classExclusions.contains(clazz);
            }
        });
        return b.create();

    }
}

Zur Verwendung erstellen Sie zwei Listen (jede ist optional), und erstellen Sie Ihr GSON-Objekt:

static {
 List<String> fieldExclusions = new ArrayList<String>();
 fieldExclusions.add("id");
 fieldExclusions.add("provider");
 fieldExclusions.add("products");

 List<Class<?>> classExclusions = new ArrayList<Class<?>>();
 classExclusions.add(Product.class);
 GSON = GsonFactory.build(null, classExclusions);
}

private static final Gson GSON;

public String getSomeJson(){
    List<Provider> list = getEntitiesFromDatabase();
    return GSON.toJson(list);
}

16voto

Hibbem Punkte 1436

Ich habe dieses Problem mit benutzerdefinierten Kommentaren gelöst. Dies ist meine "SkipSerialisation" Annotation Klasse:

@Target (ElementType.FIELD)
public @interface SkipSerialisation {

}

und dies ist mein GsonBuilder:

gsonBuilder.addSerializationExclusionStrategy(new ExclusionStrategy() {

  @Override public boolean shouldSkipField (FieldAttributes f) {

    return f.getAnnotation(SkipSerialisation.class) != null;

  }

  @Override public boolean shouldSkipClass (Class<?> clazz) {

    return false;
  }
});

Beispiel:

public class User implements Serializable {

  public String firstName;

  public String lastName;

  @SkipSerialisation
  public String email;
}

14voto

lookashc Punkte 849

Kotlins @Transient Anmerkung funktioniert offenbar auch.

data class Json(
    @field:SerializedName("serialized_field_1") val field1: String,
    @field:SerializedName("serialized_field_2") val field2: String,
    @Transient val field3: String
)

出力します。

{"serialized_field_1":"VALUE1","serialized_field_2":"VALUE2"}

9voto

lucasddaniel Punkte 1569

Oder kann sagen, welche Felder nicht mit ausgestellt werden:

Gson gson = gsonBuilder.excludeFieldsWithModifiers(Modifier.TRANSIENT).create();

auf Ihre Klasse auf Attribut:

private **transient** boolean nameAttribute;

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