You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gson反序列化日期报错JsonSyntaxException/ParseException求助

解决Gson反序列化日期列表时的JsonSyntaxException问题

嗨,我知道你折腾了好几个小时都没搞定这个问题,别急,咱们一步步来排查!

首先,你遇到的com.google.gson.JsonSyntaxException: 2020-08-30错误,看起来是Gson在解析日期列表时没有正确使用你配置的日期格式,或者是泛型类型处理出了问题,我给你几个针对性的解决方案:

1. 先排查JSON内容是否正确

你的文件读取逻辑里,处理"END"标记时的删除操作可能有问题:

fileContent.delete(fileContent.length() - 4, fileContent.length());

如果你的"END"行是纯文本END(3个字符),加上之前append的\n,总共是4个字符(\nEND),这个删除操作是对的,但如果你的"END"行带有空格(比如END),trim后匹配但实际字符串长度不止3,就会导致JSON内容被错误截断,间接引发解析报错。

建议你在调用fromJson之前,先打印fileContent.toString(),确认生成的JSON是完整且格式正确的(比如你的示例{"freeDates": ["2020-08-30", "2020-08-31", "2020-09-01", "2020-09-02"]})。

2. 确保泛型类型被正确识别

因为Java泛型擦除的问题,你的GenericRepository中的type参数可能没有正确获取到实体类的泛型信息(比如List<Date>的实际类型)。如果你的GenericRepository是通过Class<T>来传递类型的,Gson无法识别实体类内部的List<Date>泛型,会用默认的日期解析逻辑,忽略你配置的setDateFormat。

解决方法是在GenericRepository中通过ParameterizedType获取正确的泛型类型:

public abstract class GenericRepository<T> {
    protected final Type type;

    protected GenericRepository() {
        // 获取父类的泛型参数
        Type superclass = getClass().getGenericSuperclass();
        if (superclass instanceof ParameterizedType) {
            this.type = ((ParameterizedType) superclass).getActualTypeArguments()[0];
        } else {
            throw new IllegalArgumentException("GenericRepository必须使用泛型子类");
        }
    }

    // 你的getAllEntities方法...
}

这样当你继承GenericRepository时(比如class BookingRepository extends GenericRepository<Booking>),type就会是Booking的完整泛型类型,Gson就能正确识别List<Date>字段。

3. 自定义Date TypeAdapter强制解析格式

如果上面的方法还是不行,那我们直接给Date类型写一个自定义的解析器,绕过Gson默认的集合处理逻辑:

第一步:编写DateTypeAdapter

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateTypeAdapter extends TypeAdapter<Date> {
    // 固定日期格式
    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public void write(JsonWriter out, Date value) throws IOException {
        if (value == null) {
            out.nullValue();
            return;
        }
        out.value(dateFormat.format(value));
    }

    @Override
    public Date read(JsonReader in) throws IOException {
        if (in.peek() == com.google.gson.JsonToken.NULL) {
            in.nextNull();
            return null;
        }
        String dateStr = in.nextString();
        try {
            return dateFormat.parse(dateStr);
        } catch (ParseException e) {
            throw new com.google.gson.JsonSyntaxException("无法解析日期: " + dateStr, e);
        }
    }
}

第二步:注册到GsonBuilder

修改你的Gson实例构建代码,替换setDateFormat为注册自定义Adapter:

private static Gson g = new GsonBuilder()
    .registerTypeAdapter(Date.class, new DateTypeAdapter())
    .setPrettyPrinting()
    .serializeNulls()
    .create();

这个方法会强制Gson用我们指定的格式解析所有Date类型(包括List里的Date),彻底避免格式不匹配的问题。

你可以先试试第三个方法,通常这个方案能直接解决日期列表的解析问题,要是还有问题,再回头检查JSON内容和泛型类型的传递~

内容的提问来源于stack exchange,提问作者Vasilije Bursac

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 23:48:12