Reputation: 575
I have a class with these fields:
private transient List<Peer> peers;
private final String name;
private final int points;
private final int size;
Using Gson I want to deserialize this JSON String request:
{
"name": "game1",
"points": "11",
"size": "10",
"peers": [
{
"address": "localhost",
"port": 1234,
"fullAddress": "localhost:1234"
}
]
}
My problem is that the Peer
object does not get deserialized into the peers
List unless I don't declare the field as transient.
Is there a way, with Gson, to have some field transient only during serialization but not during deserialization?
Upvotes: 2
Views: 1703
Reputation: 21115
You have two options.
Gson provides @Expose
that serves the exact purpose. The only caveat here is that you have to annotate every field:
private static final Gson gson = new GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.create();
@Expose(serialize = false) final List<Peer> peers;
@Expose final String name;
@Expose final int points;
@Expose final int size;
Say, you can easily introduce something like this:
@Target(FIELD)
@Retention(RUNTIME)
@interface ReadOnly {
}
Now, once this one is declared, you can register a strategy to the Gson
instance:
private static final Gson gson = new GsonBuilder()
.addSerializationExclusionStrategy(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(final FieldAttributes f) {
return f.getAnnotation(ReadOnly.class) != null;
}
@Override
public boolean shouldSkipClass(final Class<?> clazz) {
return false;
}
})
.create();
@ReadOnly final List<Peer> peers;
final String name;
final int points;
final int size;
You can easily use @Expose
for the option #2 by just handling it with something like f.getAnnotation(Expose.class) != null && !f.getAnnotation(Expose.class).serialize()
in the strategy, but I find @ReadOnly
somewhat more convenient.
For both options, the following code
public static void main(final String... args)
throws IOException {
try ( final JsonReader jsonReader = getPackageResourceJsonReader(Q43893428.class, "foo.json") ) {
final Foo foo = gson.fromJson(jsonReader, Foo.class);
for ( final Peer peer : foo.peers ) {
System.out.println(peer.fullAddress);
}
System.out.println(gson.toJson(foo));
}
}
produces the following result:
localhost:1234
{"name":"game1","points":11,"size":10}
Upvotes: 5