Java Gson在序列化期间排除字段

The*_*sic 21 java serialization gson

我有一个ConfigInstance包含a 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 */}
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我已经尝试过使用@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());
    }
}
Run Code Online (Sandbox Code Playgroud)

仍导致以下文件内容没有错误:

{
  "database_address": "127.0.0.1",
  "database_port": 1521,
  "database_user": "test",
  "database_pass": "test1234",
  "database_pass_hash": "B9FE2C011B59F0D0D383D70073E48A19"
}
Run Code Online (Sandbox Code Playgroud)

那么我做错了什么?我现在很无能为力,感谢任何帮助,因为似乎不起作用.

提前致谢.

bos*_*sco 30

为了获得此结果,您需要使用以下内容注释所有字段@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;
Run Code Online (Sandbox Code Playgroud)

并将Gson配置为仅显示已注释的字段并忽略其余字段,如下所示:

Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create();
Run Code Online (Sandbox Code Playgroud)

然后,你会得到:

{
  "database_address": "127.0.0.1",
  "database_port": 1521,
  "database_user": "test",
  "database_pass_hash": "B9FE2C011B59F0D0D383D70073E48A19"
}
Run Code Online (Sandbox Code Playgroud)

此外,在对字符串进行反序列化时,您仍将拥有密码属性.


不过,您仍然可以配置Gson Serializer来实现这一目标.


utk*_*mez 21

这是另一种方式.

系列化:

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();
Run Code Online (Sandbox Code Playgroud)

反序列化:

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();
Run Code Online (Sandbox Code Playgroud)


小智 19

如果您希望特定字段不被序列化,请为其提供一个临时关键字

private transient String database_pass;
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请访问https://sites.google.com/site/gson/gson-user-guide#TOC-Finer-Points-with-Objects

  • 事实上,我也尝试过这个问题,但问题是Gson完全忽略了瞬态字段,反序列化也是如此.因此,如果在文件中修改了密码,则在反序列化时不会分配database_pass字段, (2认同)

Olm*_*tov 11

@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*))
Run Code Online (Sandbox Code Playgroud)


Jak*_*sky 6

如果只想禁用序列化或仅反序列化,则可以使用@Expose批注的属性,例如:

@Expose(serialize = false, deserialize = true)
Run Code Online (Sandbox Code Playgroud)

默认选项为true,因此此处不需要反序列化。