J'ai une classe ConfigInstance
qui contient une password
et un password_hash
. Maintenant, je veux sérialiser l'objet à l'aide de gson mais exclure le champ 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 */}
}
Comme vous pouvez le constater, j’ai essayé d’utiliser @Expose(serialize = false)
mais cela ne semble rien faire. De plus, j'ai déjà défini le champ sur privé car je pensais que cela "écraserait" le @Expose
mais en exécutant le code suivant:
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());
}
}
entraîne toujours le contenu du fichier suivant sans erreur:
{
"database_address": "127.0.0.1",
"database_port": 1521,
"database_user": "test",
"database_pass": "test1234",
"database_pass_hash": "B9FE2C011B59F0D0D383D70073E48A19"
}
Alors qu'est-ce que je fais mal? Je suis assez désemparé en ce moment et apprécierais toute aide puisque CE ne semble pas fonctionner.
Merci d'avance.
Pour obtenir ce résultat, vous devez annoter tous les champs avec le @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;
Et configurez Gson pour n’exposer que les champs annotés et ignorer le reste, comme indiqué ci-dessous:
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create();
Ensuite, vous aurez:
{
"database_address": "127.0.0.1",
"database_port": 1521,
"database_user": "test",
"database_pass_hash": "B9FE2C011B59F0D0D383D70073E48A19"
}
De plus, lors de la désérialisation de la chaîne, vous aurez toujours l'attribut password.
Néanmoins, vous avez la possibilité de configurer un Gson Serializer pour accomplir cela.
C'est une autre façon.
sérialisation:
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();
désérialisation:
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();
Si vous aimez un domaine particulier ne pas être sérialisé, donnez-lui un mot clé transitoire.
private transient String database_pass;
visitez https://sites.google.com/site/gson/gson-user-guide#TOC-Finer-Points-with-Objects pour plus d'informations
@utkusonmez Cette réponse fonctionne même si la méthode mentionnée est incorrecte . Elle devrait utiliser 'addSerializationExclusionStrategy' au lieu de 'addDeserializationExclusionStrategy'
Donc, la réponse ressemblerait à
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*))
Si vous souhaitez désactiver uniquement la sérialisation ou la désérialisation, vous pouvez jouer avec les attributs de l'annotation @Expose
, par exemple:
@Expose(serialize = false, deserialize = true)
L'option par défaut est true, la désérialisation est donc inutile ici.
C'est une réponse tardive, mais cela peut aider quelqu'un.
Vous devez seulement faire @Expose(serialize = false, deserialize = false)
ou juste ce que vous voulez.
Si vous avez serialize
et deserialize
true
, il n'est pas nécessaire d'avoir @Expose
du tout.
Créer cette classe:
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()));
}
}
puis construisez Gson avec GsonBuilder
Gson gson = new GsonBuilder()
.addSerializationExclusionStrategy(new NoModuleExclusionStrategy(false))
.addDeserializationExclusionStrategy(new NoModuleExclusionStrategy(true))
.create();
Votre classe ConfigInstance ressemblera à ce qui suit
{
"database_address": "127.0.0.1",
"database_port": 1521,
"database_user": "test",
"database_pass_hash": "B9FE2C011B59F0D0D383D70073E48A19"
}
Voici une solution très simple avec une seule ligne de code, sans stratégie d'annotation ou d'exclusion @Expose.
Le comportement par défaut implémenté dans Gson est que les champs d'objet null sont ignorés . Il suffit donc de définir le champ du mot de passe sur null avant la sérialisation.
map.setPassword(null); // or map.password = null;
String jsonConfig = gson.toJson(map); // This won't serialize null password field