将 JSON 反序列化为瞬态字段

gio*_*ino 2 java serialization json transient gson

我有一个包含这些字段的类:

private transient List<Peer> peers;
private final String name;
private final int points;
private final int size;
Run Code Online (Sandbox Code Playgroud)

使用Gson我想反序列化这个 JSON String 请求:

{
    "name": "game1",
    "points": "11",
    "size": "10",
    "peers": [
        {
            "address": "localhost",
            "port": 1234,
            "fullAddress": "localhost:1234"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

我的问题是该Peer对象不会反序列化到peersList 中,除非我不将该字段声明为瞬态

有没有办法使用 Gson 只在序列化期间而不是在反序列化期间有一些场瞬态?

Lyu*_*riv 5

你有两个选择。

excludeFieldsWithoutExposeAnnotation()

Gson 提供@Expose了服务于确切目的。这里唯一需要注意的是,您必须对每个字段进行注释:

private static final Gson gson = new GsonBuilder()
        .excludeFieldsWithoutExposeAnnotation()
        .create();
Run Code Online (Sandbox Code Playgroud)
@Expose(serialize = false) final List<Peer> peers;
@Expose final String name;
@Expose final int points;
@Expose final int size;
Run Code Online (Sandbox Code Playgroud)

addSerializationExclusionStrategy(...)

说,你可以很容易地引入这样的东西:

@Target(FIELD)
@Retention(RUNTIME)
@interface ReadOnly {
}
Run Code Online (Sandbox Code Playgroud)

现在,一旦声明了这个,你就可以向Gson实例注册一个策略:

@Target(FIELD)
@Retention(RUNTIME)
@interface ReadOnly {
}
Run Code Online (Sandbox Code Playgroud)
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();
Run Code Online (Sandbox Code Playgroud)

你可以很容易地使用@Expose选项#2,只需使用类似于f.getAnnotation(Expose.class) != null && !f.getAnnotation(Expose.class).serialize()策略中的东西来处理它,但我觉得@ReadOnly更方便一些。

对于这两个选项,以下代码

@ReadOnly final List<Peer> peers;
final String name;
final int points;
final int size;
Run Code Online (Sandbox Code Playgroud)

产生以下结果:

本地主机:1234
{"name":"game1","points":11,"size":10}