Java Gson 在序列化期间排除字段
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40909205/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Gson Exclude fields during serialization
提问by ThexBasic
I have a ConfigInstance
class which contains a password
and a password_hash
.
Now I want to serialize the object using gson but exclude the password
field.
我有一个ConfigInstance
包含 apassword
和 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 */}
}
As you can see, I have tried using @Expose(serialize = false)
but it doesn't seem to do anything. Also I already set the field to private since I figured that this would "override" the @Expose
如您所见,我尝试使用,@Expose(serialize = false)
但似乎没有任何作用。此外,我已经将该字段设置为私有,因为我认为这会“覆盖”@Expose
but running following code:
但运行以下代码:
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());
}
}
still results in the following file content without Errors:
仍然会导致以下文件内容没有错误:
{
"database_address": "127.0.0.1",
"database_port": 1521,
"database_user": "test",
"database_pass": "test1234",
"database_pass_hash": "B9FE2C011B59F0D0D383D70073E48A19"
}
So what am I doing wrong? I am pretty clueless right now and would appreciate any help since THISdoesn't seem to work.
那么我做错了什么?我现在很无能,希望得到任何帮助,因为这似乎不起作用。
Thanks in advance.
提前致谢。
采纳答案by bosco
In order to get this result, you need to annotate all the fields with the @Expose
:
为了获得此结果,您需要使用以下内容注释所有字段@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;
And configure Gson to only expose fields that are annotated and ignore the rest as shown in the following:
并将 Gson 配置为仅公开已注释的字段并忽略其余字段,如下所示:
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create();
Then, you'll get:
然后,你会得到:
{
"database_address": "127.0.0.1",
"database_port": 1521,
"database_user": "test",
"database_pass_hash": "B9FE2C011B59F0D0D383D70073E48A19"
}
Also, when deserialising the string you'll still have the password attribute as well.
此外,在反序列化字符串时,您仍将拥有 password 属性。
Still, you have the possibility to configure a Gson Serializerto accomplish this.
尽管如此,您仍然可以配置Gson Serializer来完成此操作。
回答by kPieczonka
If you like particular field not be serialized give it a transient keyword
如果你喜欢特定的字段不被序列化,给它一个瞬态关键字
private transient String database_pass;
visit https://sites.google.com/site/gson/gson-user-guide#TOC-Finer-Points-with-Objectsfor more information
访问https://sites.google.com/site/gson/gson-user-guide#TOC-Finer-Points-with-Objects了解更多信息
回答by utkusonmez
This is another way.
这是另一种方式。
serialization:
序列化:
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();
deserialization:
反序列化:
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();
回答by Jakub Turcovsky
If you want to disable only serialization or only deserialization, you can play with @Expose
annotation's attributes, e.g.:
如果您只想禁用序列化或反序列化,您可以使用@Expose
注释的属性,例如:
@Expose(serialize = false, deserialize = true)
Default option is true, so deserialize is unnecessary here.
默认选项为 true,因此这里不需要反序列化。
回答by Olmstov
@utkusonmez This answer works albeit the method mentioned is wrong. It should be using 'addSerializationExclusionStrategy' instead of 'addDeserializationExclusionStrategy'
@utkusonmez 这个答案有效,尽管提到的方法是错误的。它应该使用“addSerializationExclusionStrategy”而不是“addDeserializationExclusionStrategy”
So the answer would look like
所以答案看起来像
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*))
回答by Klotzi111
It's a late answer but it may help someone.
这是一个迟到的答案,但它可能会帮助某人。
You only have to do the @Expose(serialize = false, deserialize = false)
or just what you want.
你@Expose(serialize = false, deserialize = false)
只需要做你想做的。
If you have serialize
and deserialize
true
its not nesseccary to have @Expose
at all.
如果你有serialize
而且deserialize
true
根本没有必要@Expose
。
Create this Class:
创建这个类:
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()));
}
}
and then build Gson with GsonBuilder
然后用 GsonBuilder 构建 Gson
Gson gson = new GsonBuilder()
.addSerializationExclusionStrategy(new NoModuleExclusionStrategy(false))
.addDeserializationExclusionStrategy(new NoModuleExclusionStrategy(true))
.create();
Your ConfigInstance Class will look like follows
您的 ConfigInstance 类将如下所示
{
"database_address": "127.0.0.1",
"database_port": 1521,
"database_user": "test",
"database_pass_hash": "B9FE2C011B59F0D0D383D70073E48A19"
}
回答by ntsh
Here's a very simple solution with just one line of code, without any @Expose annotation or exclusion strategy.
这是一个非常简单的解决方案,只有一行代码,没有任何 @Expose 注释或排除策略。
The default behaviour that is implemented in Gson is that null object fields are ignored. So, all you need to do is set the password field to null before serializing.
Gson 中实现的默认行为是忽略空对象字段。因此,您需要做的就是在序列化之前将密码字段设置为 null。
map.setPassword(null); // or map.password = null;
String jsonConfig = gson.toJson(map); // This won't serialize null password field