Reputation: 714
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.
Upvotes: 25
Views: 44134
Reputation: 1506
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();
Upvotes: 25
Reputation: 759
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
Upvotes: 0
Reputation: 64
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.
If you have serialize
and deserialize
true
its not nesseccary to have @Expose
at all.
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
Gson gson = new GsonBuilder()
.addSerializationExclusionStrategy(new NoModuleExclusionStrategy(false))
.addDeserializationExclusionStrategy(new NoModuleExclusionStrategy(true))
.create();
Your ConfigInstance Class will look like follows
{
"database_address": "127.0.0.1",
"database_port": 1521,
"database_user": "test",
"database_pass_hash": "B9FE2C011B59F0D0D383D70073E48A19"
}
Upvotes: 3
Reputation: 593
@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*))
Upvotes: 11
Reputation: 2126
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.
Upvotes: 7
Reputation: 3976
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.
Upvotes: 37
Reputation: 404
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-Objects for more information
Upvotes: 22