如何使用gson反序列化base64编码的json数据 [英] how to deserialize base64 encoded json data with gson

查看:135
本文介绍了如何使用gson反序列化base64编码的json数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个像这样的json:

I have a json like this:

{code:1, message:"ok", data:"W3tpZDoxLCBuYW1lOiJUb20ifSx7aWQ6MiwgbmFtZToiSmFjayJ9LHtpZDozLCBuYW1lOiJMdWNpYSJ9XQ=="}

,只有数据是使用base64编码的,实际数据是:

, only data is encoded using base64, the real data is:

[{id:1, name:"Tom"},{id:2, name:"Jack"},{id:3, name:"Lucia"}]

.如何使用gson一步反序列化此json?

. How to use gson to deserialize this json in one step?

推荐答案

Gson在此处提出了几个选择,但以下似乎是最短的选择.考虑以下 Response User 类:

Gson suggests a couple of options here, but the following seems to be the shortest one. Consider the following Response and User classes:

final class Response<T> {

    @SerializedName("code")
    final int code = Integer.valueOf(0);

    @SerializedName("message")
    final String message = null;

    @SerializedName("data")
    @JsonAdapter(Base64TypeAdapterFactory.class)
    final T data = null;

}

final class User {

    final int id = Integer.valueOf(0);
    final String name = null;

    @Override
    public String toString() {
        return id + ":" + name;
    }

}

上面的

@JsonAdapter(Base64TypeAdapterFactory.class)告诉Gson为给定字段选择一个特殊类型的适配器.此类型适配器将负责Base64解码,并且可以在反序列化过程中使用类型令牌对实际类型进行专门化.

@JsonAdapter(Base64TypeAdapterFactory.class) above tells Gson to pick a special type adapter for the given field. This type adapter will be responsible for Base64 decoding and the actual type can be specialized using type tokens during deserialization.

final class Base64TypeAdapterFactory
        implements TypeAdapterFactory {

    // Gson can instantiate this one itself, no need to expose it
    private Base64TypeAdapterFactory() {
    }

    @Override
    public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
        final TypeAdapter<String> stringTypeAdapter = gson.getAdapter(String.class);
        final TypeAdapter<T> dataTypeAdapter = gson.getAdapter(typeToken);
        return Base64TypeAdapter.of(stringTypeAdapter, dataTypeAdapter);
    }

    private static final class Base64TypeAdapter<T>
            extends TypeAdapter<T> {

        private static final Decoder base64Decoder = Base64.getDecoder();

        private final TypeAdapter<String> stringTypeAdapter;
        private final TypeAdapter<T> dataTypeAdapter;

        private Base64TypeAdapter(final TypeAdapter<String> stringTypeAdapter, final TypeAdapter<T> dataTypeAdapter) {
            this.stringTypeAdapter = stringTypeAdapter;
            this.dataTypeAdapter = dataTypeAdapter;
        }

        static <T> TypeAdapter<T> of(final TypeAdapter<String> stringTypeAdapter, final TypeAdapter<T> dataTypeAdapter) {
            return new Base64TypeAdapter<>(stringTypeAdapter, dataTypeAdapter)
                    .nullSafe(); // Just let Gson manage nulls itself. It's convenient
        }

        @Override
        public void write(final JsonWriter jsonWriter, final T value) {
            throw new UnsupportedOperationException();
        }

        @Override
        public T read(final JsonReader jsonReader)
                throws IOException {
            // Decode the payload first as a Base64-encoded message
            final byte[] payload = base64Decoder.decode(stringTypeAdapter.read(jsonReader));
            try ( final JsonReader payloadJsonReader = new JsonReader(new InputStreamReader(new ByteArrayInputStream(payload))) ) {
                // And tell Gson to not refuse unquoted property names
                payloadJsonReader.setLenient(true);
                return dataTypeAdapter.read(payloadJsonReader);
            } catch ( final EOFException ignored ) {
                return null;
            }
        }

    }

}

现在您可以轻松对其进行测试:

Now you can easily test it:

final Response<List<User>> response = gson.fromJson(..., new TypeToken<Response<List<User>>>() {
}.getType());
System.out.println(response.code);
System.out.println(response.message);
System.out.println(response.data);

输出:

1
ok
[1:Tom, 2:Jack, 3:Lucia]

这篇关于如何使用gson反序列化base64编码的json数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆