Java Gson Исключить поля во время сериализации
У меня есть класс ConfigInstance
, который содержит password
и a password_hash
.
Теперь я хочу сериализовать объект с помощью gson, но исключить поле 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 */}
}
Как вы можете видеть, я попытался использовать @Expose(serialize = false)
, но он ничего не делает. Также я уже установил поле в приватное, так как понял, что это "переопределит" @Expose
но выполняется следующий код:
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());
}
}
все еще приводит к следующему содержимому файла без ошибок:
{
"database_address": "127.0.0.1",
"database_port": 1521,
"database_user": "test",
"database_pass": "test1234",
"database_pass_hash": "B9FE2C011B59F0D0D383D70073E48A19"
}
Так что я делаю неправильно? Я довольно невнятный прямо сейчас и буду признателен за любую помощь, поскольку ЭТО, похоже, не работает.
Спасибо заранее.
Ответы
Ответ 1
Чтобы получить этот результат, вам необходимо аннотировать все поля с помощью @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;
И настройте Gson только для того, чтобы выставлять аннотированные поля и игнорировать остальные, как показано ниже:
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create();
Затем вы получите:
{
"database_address": "127.0.0.1",
"database_port": 1521,
"database_user": "test",
"database_pass_hash": "B9FE2C011B59F0D0D383D70073E48A19"
}
Кроме того, при десериализации строки у вас все равно будет атрибут пароля.
Тем не менее, у вас есть возможность настроить Gson Serializer, чтобы выполнить это.
Ответ 2
Если вам нравится, чтобы определенное поле не было сериализованным, дайте ему ключевое слово переходного периода
private transient String database_pass;
посетите https://sites.google.com/site/gson/gson-user-guide#TOC-Finer-Points-with-Objects для получения дополнительной информации
Ответ 3
Это другой способ.
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();
Ответ 4
Если вы хотите отключить только сериализацию или только десериализацию, вы можете играть с атрибутами аннотации @Expose
, например:
@Expose(serialize = false, deserialize = true)
Значение по умолчанию - true, поэтому здесь не требуется десериализация.
Ответ 5
@utkusonmez
Этот ответ работает, хотя упомянутый метод неверен.
Он должен использовать 'addSerializationExclusionStrategy' вместо 'addDeserializationExclusionStrategy'
Итак, ответ будет выглядеть как
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*))
Ответ 6
Вы можете сделать трюк с этим:
Gson gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.STATIC)
.create();
Затем во всех полях, которые вы хотите выделить из объекта, просто добавьте модификатор "статический"
@Expose(serialize = false)
private static String database_pass;
Вы можете использовать модификатор Transient или что-то вам подходит