java - unknown - kotlin transient




Java Gson Exclude fields during serialization (6)

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.

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

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 THIS doesn't seem to work.

Thanks in advance.


@utkusonmez This answer works albeit the method mentioned is wrong. It should be using 'addSerializationExclusionStrategy' instead of '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*))

Here's a very simple solution with just one line of code, without any @Expose annotation or exclusion strategy.

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.

map.setPassword(null); // or map.password = null;
String jsonConfig = gson.toJson(map); // This won't serialize null password field

If you want to disable only serialization or only deserialization, you can play with @Expose annotation's attributes, e.g.:

@Expose(serialize = false, deserialize = true)

Default option is true, so deserialize is unnecessary here.


In order to get this result, you need to annotate all the fields with the @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 = 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.


Still, you have the possibility to configure a Gson Serializer to accomplish this.


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();

You can do the trick with this:

Gson gson = new GsonBuilder()
            .excludeFieldsWithModifiers(Modifier.STATIC)
            .create();

Then in all fields you want to excelude from the Object just add the modifier "static"

@Expose(serialize = false)
private static String database_pass;

You can use the Transient modifier or something suits you





gson