基于GSON日期格式反序列化失败:JsonDeserializer——Gson自定义解析类型错误的字段

629 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情

Gson的序列化操作

Gson 使用 JsonSerializer 接管序列化过程,JsonDeserializer 接管反序列化过程。

JsonSerializer序列化

@Test
public void test() throws IOException {
    JsonSerializer<String> stringJsonSerializer = new JsonSerializer<String>() {
        @Override
        public JsonElement serialize(String arg0, Type arg1, JsonSerializationContext arg2) {
            return new JsonPrimitive(arg0 + "_ADD");
        }
    };
    Gson gson = new GsonBuilder()
        .registerTypeAdapter(String.class, stringJsonSerializer)
        .create();
    System.out.println(gson.toJson("JSON"));
}
运行结果:
"JSON_ADD"

JsonDeserializer 反序列化

@Test
public void test() throws IOException {
    Gson gson = new GsonBuilder()
        .registerTypeAdapter(String.class, new JsonDeserializer<String>() {
            @Override
            public String deserialize(JsonElement json, Type type, JsonDeserializationContext context)
                throws JsonParseException {
                String value = json.getAsString();
                if (value.equals("KEY")) {
                    return "That's it!";
                }
                return "Forget it...";
            }
        }).create();
    System.out.println(gson.fromJson("XYZ", String.class));
    System.out.println(gson.fromJson("KEY", String.class));
    System.out.println(gson.fromJson("ANY", String.class));
}
运行结果:
"Forget it..."
"That's it!"
"Forget it..."

Gson的自定义序列化操作

工作中,通过rabbitmq发送消息给另一个服务,解析数据时候出现错误:parseException: Unparseable date: "1654755670724";原来时发送给服务端数据有Date类型,默认发送了时间戳形式;而对方解析数据默认格式"yyyy-MM-dd HH:mm:ss";导致解析失败。

注册自定义解析器

其实也就是反序列化的问题,找到问题我们具体问题具体解决。可以专门定义一个解析器;Gson允许我们自定义解析某种类型的数据,一般我们使用Gson可能就直接new出来一个,这样实例化:

Gson gson = new GsonBuilder() .registerTypeAdapter(A.class, new ADeserializer()) .registerTypeAdapter(B.class, new BDeserializer()) .create()

得到的gson就会使用自定义的ADeserializerBDeserializer分别反序列化类A和类B。

registerTypeAdapter 方法用于配置Gson的序列化或反序列化,接收两个参数。

第一个参数是注册的类型,即希望自定义解析的数据类型。

定义一个解析器
public class PartnerDeserializer implements JsonDeserializer<Partner> {

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public Partner deserialize(JsonElement json, java.lang.reflect.Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        Partner merged = new Partner();
        if (json.isJsonObject()) {
            //类型正确
            JsonObject jsonObject = json.getAsJsonObject();
            try {
                merged.setBefore(dateFormat.parse(jsonObject.get("before").getAsString()));
                merged.setGetBefore(dateFormat.parse(jsonObject.get("getBefore").getAsString()));
                merged.setNow(dateFormat.parse(jsonObject.get("now").getAsString()));
                merged.setName(jsonObject.get("name").getAsString());
            } catch (ParseException e) {
                e.printStackTrace();
            }

        } else {
            //类型错误
            String value = json.getAsString();
            merged = new Gson().fromJson(value, Partner.class);
        }
        return merged;
    }
}

注册解析器

private Gson gson= new GsonBuilder()
       .registerTypeAdapter(Partner.class, new PartnerDeserializer())
       .create();