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

Swagger自动生成Java客户端DateTimeParseException问题排查

解决Swagger生成Java客户端解析无Z后缀ISO日期的异常问题

这个问题我之前帮同事排查过,本质是Swagger Codegen生成的Java客户端默认的Jackson日期序列化/反序列化配置没有兼容不带Z后缀的ISO 8601格式。下面给你几个循序渐进的解决办法,从根源修复到临时兼容都有:

方案1:重新生成客户端时指定兼容的日期配置(推荐)

如果还能重新生成客户端,直接在生成命令里指定日期库和格式参数,从根源避免问题。用swagger-codegen命令时加上--additional-properties参数:

swagger-codegen generate -i your-swagger-spec.yaml -l java -o ./your-client-dir \
  --additional-properties dateLibrary=java8-localdatetime,jacksonDateFormat=yyyy-MM-dd'T'HH:mm:ss.SSS
  • dateLibrary=java8-localdatetime:让客户端使用Java 8的LocalDateTime替代旧的java.util.Date,更符合现代Java时间API规范
  • jacksonDateFormat:指定兼容不带Z后缀的日期格式,这样生成的客户端会自动用这个格式解析日期

方案2:在现有项目中覆盖Jackson配置(无需重新生成客户端)

如果不想重新生成客户端,可以在你的业务项目里自定义Jackson的ObjectMapper,覆盖客户端默认的解析规则:

如果你用的是Spring Boot项目

创建一个Jackson配置类,全局生效:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Configuration
public class CustomJacksonConfig {
    // 匹配不带Z的ISO日期格式
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");

    @Bean
    @Primary
    public ObjectMapper customObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        JavaTimeModule timeModule = new JavaTimeModule();

        // 注册自定义的反序列化器,兼容无Z格式
        timeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DATE_FORMATTER));
        // 如果需要序列化时也输出同样格式,加上这个
        timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DATE_FORMATTER));

        mapper.registerModule(timeModule);
        // 如果服务端返回的无Z日期实际是UTC时间,别忘了设置时区
        mapper.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
        return mapper;
    }
}

如果是非Spring项目

手动给Swagger生成的ApiClient设置自定义的ObjectMapper:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

// 初始化ApiClient时配置
ApiClient apiClient = new ApiClient();
ObjectMapper mapper = apiClient.getJSON().getObjectMapper();

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
JavaTimeModule module = new JavaTimeModule();
module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));

mapper.registerModule(module);
mapper.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));

// 把配置好的mapper设置回ApiClient
apiClient.setJSON(new JSON(mapper));

方案3:兼容旧版java.util.Date的情况

如果生成的客户端用的是java.util.Date而不是Java 8时间类,直接设置Jackson的日期格式即可:

ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"));
mapper.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));

问题根源补充

Swagger Codegen默认生成的客户端,Jackson的日期解析规则是严格匹配带Z后缀的UTC格式(比如2017-07-18T03:41:57.427Z),而不带Z的ISO格式不在默认解析范围内,所以会抛出反序列化异常。上面的方案都是通过调整Jackson的解析规则,让它兼容这种格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:05:04