tutorial - Java Gson Excluir campos durante la serialización
gson tutorial (7)
@utkusonmez Esta respuesta funciona aunque el método mencionado es incorrecto. Debería estar usando ''addSerializationExclusionStrategy'' en lugar de ''addDeserializationExclusionStrategy''
Entonces la respuesta se vería como
Gson gson = new GsonBuilder()
.addSerializationExclusionStrategy(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getName().toLowerCase().contains("fieldName");
}
@Override
public boolean shouldSkipClass(Class<?> aClass) {
return false;
}
})
.create();
gson.toJson(*OBJ_TO_SERIALIZE*))
Tengo una clase ConfigInstance
que contiene una password
y un password_hash
. Ahora quiero serializar el objeto usando gson pero excluir el campo de password
.
public class ConfigInstance {
public String database_address;
public int database_port;
public String database_user;
@Expose(serialize = false)
private String database_pass;
public String database_pass_hash;
public String GetPass() { return database_pass; }
public void Encrypt() { /* Creates the hash before serializing*/ }
public void Decrypt() { /* Creates the password after deserializing */}
}
Como puede ver, he intentado usar @Expose(serialize = false)
pero no parece hacer nada. También ya puse el campo a privado ya que pensé que esto "anularía" el @Expose
pero ejecutando el siguiente código:
private void toFile(File file, ConfigInstance map) {
map.Encrypt();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonConfig = gson.toJson(map);
FileWriter writer;
try {
writer = new FileWriter(file);
writer.write(jsonConfig);
writer.flush();
writer.close();
} catch (IOException e) {
System.out.println("Error exporting config: " + e.toString());
}
}
sigue resultando en el siguiente contenido del archivo sin errores:
{
"database_address": "127.0.0.1",
"database_port": 1521,
"database_user": "test",
"database_pass": "test1234",
"database_pass_hash": "B9FE2C011B59F0D0D383D70073E48A19"
}
Entonces, ¿qué estoy haciendo mal? Estoy bastante despistado en este momento y agradecería cualquier ayuda ya que esto no parece funcionar.
Gracias por adelantado.
Aquí hay una solución muy simple con solo una línea de código, sin ninguna estrategia de anotación o exclusión de @Expose.
El comportamiento predeterminado que se implementa en Gson es que los campos de objeto nulo se ignoran . Por lo tanto, todo lo que debe hacer es establecer el campo de contraseña en nulo antes de serializar.
map.setPassword(null); // or map.password = null;
String jsonConfig = gson.toJson(map); // This won''t serialize null password field
Es una respuesta tardía, pero puede ayudar a alguien.
Solo tiene que hacer el @Expose(serialize = false, deserialize = false)
o simplemente lo que desee.
Si ha serialize
y deserialize
true
no es necesario tener @Expose
en absoluto.
Crear esta clase:
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.annotations.Expose;
public class NoModuleExclusionStrategy implements ExclusionStrategy {
private final boolean deserialize;
public NoModuleExclusionStrategy(boolean isdeserialize) {
deserialize = isdeserialize;
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
@Override
public boolean shouldSkipField(FieldAttributes field) {
return !(field.getAnnotation(Expose.class) == null || (deserialize ? field.getAnnotation(Expose.class).deserialize() : field.getAnnotation(Expose.class).serialize()));
}
}
y luego construir Gson con GsonBuilder
Gson gson = new GsonBuilder()
.addSerializationExclusionStrategy(new NoModuleExclusionStrategy(false))
.addDeserializationExclusionStrategy(new NoModuleExclusionStrategy(true))
.create();
Tu clase ConfigInstance se verá como sigue
{
"database_address": "127.0.0.1",
"database_port": 1521,
"database_user": "test",
"database_pass_hash": "B9FE2C011B59F0D0D383D70073E48A19"
}
Esta es otra manera.
publicación por entregas:
Gson gson = new GsonBuilder()
.addSerializationExclusionStrategy(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getName().toLowerCase().contains("fieldName");
}
@Override
public boolean shouldSkipClass(Class<?> aClass) {
return false;
}
})
.create();
deserialización:
Gson gson = new GsonBuilder()
.addDeserializationExclusionStrategy(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getName().toLowerCase().contains("fieldName");
}
@Override
public boolean shouldSkipClass(Class<?> aClass) {
return false;
}
})
.create();
Para obtener este resultado, debe anotar todos los campos con @Expose
:
public class ConfigInstance {
@Expose
public String database_address;
@Expose
public int database_port;
@Expose
public String database_user;
@Expose(serialize = false)
private String database_pass;
@Expose
public String database_pass_hash;
Y configure Gson para que solo exponga los campos que están anotados e ignore el resto como se muestra a continuación:
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create();
Entonces, obtendrá:
{
"database_address": "127.0.0.1",
"database_port": 1521,
"database_user": "test",
"database_pass_hash": "B9FE2C011B59F0D0D383D70073E48A19"
}
Además, cuando deserialice la cadena, también tendrá el atributo de contraseña.
Sin embargo, tiene la posibilidad de configurar un serializador Gson para lograr esto.
Si desea deshabilitar solo la serialización o solo la deserialización, puede jugar con los @Expose
anotación de @Expose
, por ejemplo:
@Expose(serialize = false, deserialize = true)
La opción predeterminada es verdadera, por lo que no es necesario deserializar aquí.
Si te gusta un campo en particular, no se serialice dale una palabra clave transitoria
private transient String database_pass;
Visite https://sites.google.com/site/gson/gson-user-guide#TOC-Finer-Points-with-Objects para obtener más información