如何将LocalDate字段转换为JSON?Gson转换UserDto遇解析异常求助
这个问题我之前碰到过好多次,本质是Gson和Spring默认的JSON处理组件(Jackson)对LocalDate的序列化格式不兼容导致的:Gson默认会把LocalDate转成带year、month等字段的嵌套JSON对象,而Spring的Jackson消息转换器期望的是ISO-8601格式的字符串(比如"2024-05-20"),所以解析时就会抛出你看到的“意外的START_OBJECT,期望VALUE_STRING”错误。
下面给你两个可行的解决方案:
方案一:给Gson添加Java 8日期类型支持
方法1:用官方扩展库快速解决
Gson有专门支持Java 8时间API的扩展库,直接引入就能搞定。如果是Maven项目,先在pom.xml里加依赖:
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson-java8</artifactId> <version>2.10.1</version> <!-- 建议用最新稳定版 --> </dependency>
然后创建Gson实例时注册这个模块:
Gson gson = new GsonBuilder() .registerModule(new JavaTimeModule()) .create();
这样Gson就会自动把LocalDate序列化成标准的日期字符串,和Jackson的期望完全匹配,报错自然就消失了。
方法2:自定义序列化/反序列化器(无额外依赖)
如果不想加新依赖,也可以自己写处理类来控制LocalDate的转换逻辑:
// 序列化器:把LocalDate转成ISO格式字符串 class LocalDateSerializer implements JsonSerializer<LocalDate> { @Override public JsonElement serialize(LocalDate src, Type typeOfSrc, JsonSerializationContext context) { return new JsonPrimitive(src.format(DateTimeFormatter.ISO_LOCAL_DATE)); } } // 反序列化器:把字符串转成LocalDate class LocalDateDeserializer implements JsonDeserializer<LocalDate> { @Override public LocalDate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { return LocalDate.parse(json.getAsString(), DateTimeFormatter.ISO_LOCAL_DATE); } }
接着把这两个类注册到GsonBuilder里:
Gson gson = new GsonBuilder() .registerTypeAdapter(LocalDate.class, new LocalDateSerializer()) .registerTypeAdapter(LocalDate.class, new LocalDateDeserializer()) .create();
方案二:改用Spring自带的Jackson转换JSON
其实你的Spring控制器本身就是用Jackson处理请求体的,测试时直接用Jackson的ObjectMapper来转换UserDto,能从根源上避免格式不兼容问题:
ObjectMapper objectMapper = new ObjectMapper(); objectMapper.registerModule(new JavaTimeModule()); // 注册Java8时间模块 objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); // 强制序列化为字符串格式 String json = objectMapper.writeValueAsString(userDto);
用这个生成的JSON发送测试请求,和控制器接收的格式完全一致,肯定不会出错。
内容的提问来源于stack exchange,提问作者silverwind
相关产品推荐
相关产品推荐

