如何在maven-openapi-generator-plugin中自定义DateTime格式?
我来帮你解决这个问题,结合你提到的场景——用maven-openapi-generator生成带@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)注解的日期字段,想要自定义格式比如2022-01-22T15:33:11.654 +3:00GMT,且该字段不影响业务逻辑——给你几个可行的方案:
方案一:自定义OpenAPI Generator模板(最直接的生成控制)
openapi-generator支持通过自定义Mustache模板来修改生成的代码结构,你可以直接替换日期字段的注解:
复制默认模板到本地:
找到openapi-generator官方提供的Java实体类模板(一般是model.mustache和处理日期类型的片段模板),复制到你项目的src/main/resources/openapi-templates目录下(如果没有这个目录就新建)。修改模板中的日期注解:
打开模板文件,找到生成@DateTimeFormat注解的代码块,把原来的ISO格式注解替换成你需要的自定义格式:<!-- 原来的代码 --> {{#isDateTime}}@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME){{/isDateTime}} <!-- 修改后 --> {{#isDateTime}}@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS XXX'GMT'"){{/isDateTime}}如果你想让Spring全局配置生效,也可以直接删除这行注解代码。
在Maven插件中指定模板目录:
调整maven-openapi-generator-plugin的配置,添加templateDirectory指向你的自定义模板路径:<plugin> <groupId>org.openapitools</groupId> <artifactId>openapi-generator-maven-plugin</artifactId> <version>你的插件版本</version> <executions> <execution> <goals> <goal>generate</goal> </goals> <configuration> <inputSpec>${project.basedir}/src/main/resources/openapi.yaml</inputSpec> <generatorName>spring</generatorName> <configOptions> <java8>true</java8> <!-- 其他已有配置 --> </configOptions> <!-- 指定自定义模板目录 --> <templateDirectory>${project.basedir}/src/main/resources/openapi-templates</templateDirectory> </configuration> </execution> </executions> </plugin>重新执行生成命令,就能得到带自定义格式注解的实体类了。
方案二:全局Jackson配置覆盖格式(无需修改生成代码)
既然你提到这个字段不影响业务逻辑,可能只是序列化/反序列化的格式需求,那可以通过配置Jackson全局规则来强制使用自定义格式,绕过生成的@DateTimeFormat注解:
配置Jackson序列化/反序列化规则:
创建一个Spring配置类,注册自定义的日期格式处理器:@Configuration public class JacksonDateTimeConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); JavaTimeModule timeModule = new JavaTimeModule(); // 自定义OffsetDateTime序列化格式 timeModule.addSerializer(OffsetDateTime.class, new JsonSerializer<OffsetDateTime>() { @Override public void serialize(OffsetDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException { String formattedDate = value.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS XXX'GMT'")); gen.writeString(formattedDate); } }); // 自定义反序列化规则(如果需要接收该格式的参数) timeModule.addDeserializer(OffsetDateTime.class, new JsonDeserializer<OffsetDateTime>() { @Override public OffsetDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { String dateStr = p.getText().replace("GMT", "").trim(); return OffsetDateTime.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS XXX")); } }); objectMapper.registerModule(timeModule); return objectMapper; } }配置Spring MVC参数绑定格式:
如果需要处理URL参数或表单中的日期格式,还可以添加WebMvc配置:@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addFormatters(FormatterRegistry registry) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS XXX'GMT'"); registry.addFormatterForFieldType(OffsetDateTime.class, new DateTimeFormatterFormatter(formatter)); } }
方案三:忽略生成字段,自定义替代字段(临时应急方案)
如果不想修改模板或全局配置,也可以在生成的实体类中手动添加替代字段,忽略原生成的日期字段:
// 生成的原字段,添加@JsonIgnore忽略它 @JsonIgnore @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) private OffsetDateTime createdAt; // 自定义格式的字段,对外暴露 @JsonProperty("createdAt") public String getCustomCreatedAt() { return createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS XXX'GMT'")); } @JsonProperty("createdAt") public void setCustomCreatedAt(String dateStr) { String processedStr = dateStr.replace("GMT", "").trim(); this.createdAt = OffsetDateTime.parse(processedStr, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS XXX")); }
不过这个方案需要每次生成代码后手动修改,适合临时场景,长期来看还是方案一或二更高效。
备注:内容来源于stack exchange,提问作者grilld9

