Redis:Gson反序列化时间戳过长导致报错

问题描述

今天在用Gson进行反序列化json为Java Bean时,报Invalid time zone indicator

com.google.gson.JsonSyntaxException: 1631599981000
	at com.google.gson.internal.bind.DateTypeAdapter.deserializeToDate(DateTypeAdapter.java:87) ~[gson-2.8.6.jar:na]
	at com.google.gson.internal.bind.DateTypeAdapter.read(DateTypeAdapter.java:75) ~[gson-2.8.6.jar:na]
	at com.google.gson.internal.bind.DateTypeAdapter.read(DateTypeAdapter.java:46) ~[gson-2.8.6.jar:na]
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:131) ~[gson-2.8.6.jar:na]
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222) ~[gson-2.8.6.jar:na]
	at com.google.gson.Gson.fromJson(Gson.java:932) ~[gson-2.8.6.jar:na]
	at com.google.gson.Gson.fromJson(Gson.java:897) ~[gson-2.8.6.jar:na]
	at com.google.gson.Gson.fromJson(Gson.java:846) ~[gson-2.8.6.jar:na]
	at com.google.gson.Gson.fromJson(Gson.java:817) ~[gson-2.8.6.jar:na]
Caused by: java.text.ParseException: Failed to parse date ["1631599981000"]: Invalid time zone indicator 8
	at com.google.gson.internal.bind.util.ISO8601Utils.parse(ISO8601Utils.java:274) ~[gson-2.8.6.jar:na]
	at com.google.gson.internal.bind.DateTypeAdapter.deserializeToDate(DateTypeAdapter.java:85) ~[gson-2.8.6.jar:na]
	... 132 common frames omitted
Caused by: java.lang.IndexOutOfBoundsException: Invalid time zone indicator 8
	at com.google.gson.internal.bind.util.ISO8601Utils.parse(ISO8601Utils.java:245) ~[gson-2.8.6.jar:na]
	... 133 common frames omitted

原因

实际上是因为Gson反序列化时间的时候没有设置时区,导致解析时间戳的时候转为Date类型报错,所以Gson无法解析位数太长的时间格式。

解决方式

  1. 更换序列化框架例如jackson,fastjson等
  2. 通过GsonBuilder生成注册Date类型的GSON(推荐)。
private final static Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
          
   
        @Override
        public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
          
   
            return new Date(json.getAsJsonPrimitive().getAsLong());
        }
    }).create();
 
	 /**
     * The Redis template.
     */
    private RedisTemplate<Object, Object> redisTemplate;

	/**
     * Get t.
     * 解决时间戳过长无法转换Date
     * @param <T>    the type parameter
     * @param key    the key
     * @param clazz  the clazz
     * @param expire the expire
     * @return the t
     */
    public <T> T get(String key, Class<T> clazz) {
          
   
        Object value = get(key);
        return value == null ? null : gson.fromJson(JSON.toJSONString(value), clazz);
    }

   /**
     * 普通缓存获取
     *
     * @param key 键
     * @return 值 object
     */
    public Object get(String key) {
          
   
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }
经验分享 程序员 微信小程序 职场和发展