问题描述
今天在用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无法解析位数太长的时间格式。
解决方式
- 更换序列化框架例如jackson,fastjson等
- 通过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);
}