我使用openapi生成器maven-plugin在我的spring-boot应用程序中生成API模型
pom. xml:
<...>
<dependencies>
<...>
<dependency>
<groupId>org.openapitools</groupId>
<artifactId>jackson-databind-nullable</artifactId>
<version>0.2.2</version>
</dependency>
<...>
</dependencies>
<...>
<build>
<plugins>
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>6.0.1</version>
<executions>
<execution>
<id>CLIENT-EVENT</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>
${project.basedir}/src/main/resources/swagger/client_event.json
</inputSpec>
<generatorName>spring</generatorName>
<generateApiDocumentation>false</generateApiDocumentation>
<generateApiTests>false</generateApiTests>
<generateApis>false</generateApis>
<generateSupportingFiles>false</generateSupportingFiles>
<generateModelDocumentation>false</generateModelDocumentation>
<generateModelTests>false</generateModelTests>
<generateModels>true</generateModels>
<generateAliasAsModel>false</generateAliasAsModel>
<modelPackage>ru.sb.compliance.lcm.dto.client.event</modelPackage>
<modelsToGenerate>CreateClientEventRequestData,CreateClientEventResponseData</modelsToGenerate>
<configOptions>
<delegatePattern>true</delegatePattern>
<dateLibrary>java8</dateLibrary>
</configOptions>
<library>spring-boot</library>
<typeMappings>
<typeMapping>OffsetDateTime=LocalDateTime</typeMapping>
</typeMappings>
<importMappings>
<importMapping>java.time.OffsetDateTime=java.time.LocalDateTime</importMapping>
</importMappings>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<...>
模型中生成的LocalDate/LocalDateTime字段如下所示:
public class CreateClientEventRequestData {
@JsonProperty("factDt")
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private LocalDateTime factDt;
<...>
public CreateClientEventRequestData factDt(LocalDateTime factDt) {
this.factDt = factDt;
return this;
}
@Valid
@Schema(name = "factDt", description = "дата и время мероприятия", required = false)
public LocalDateTime getFactDt() {
return factDt;
}
public void setFactDt(LocalDateTime factDt) {
this.factDt = factDt;
}
<...>
}
当我在API中使用这个模型时,factDt
像数组一样被序列化:
"data": {
<...>,
"factDt":[2022,11,11,20,18,34,71000000],
<...>
}
我想得到的是
public class CreateClientEventRequestData {
@JsonProperty("factDt")
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd.MM.yyyy HH:mm:ss")
private LocalDateTime factDt;
<...>
}
因此factDt
像字符串一样序列化:
"data": {
<...>,
"factDt": "11.11.2022 20:18:34",
<...>
}
如果没有设置@JsonFormat注释,则无法在spring-boot中设置默认序列化模式
我尝试了几个SO建议,但都不奏效,以下是我尝试的:
即使使用这样的最小示例,设置日期格式也不起作用:
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.setTimeZone(TimeZone.getDefault());
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.setDateFormat(new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"));
System.out.println(
// prints LocalDateTime in default ISO format and not in "dd.MM.yyyy HH:mm:ss" format...
objectMapper.writeValueAsString(LocalDateTime.now())
);
}
所有这些都使得从swagger生成模型而不是在代码中实现它们的想法非常不足……
非常感谢你的帮助
从最后开始,您的最小LocalDateTime
序列化示例应该是这样的:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.setTimeZone(TimeZone.getDefault());
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
String dateFormat = "dd.MM.yyyy HH:mm:ss";
objectMapper.setDateFormat(new SimpleDateFormat(dateFormat));
SimpleModule module = new SimpleModule();
module.addSerializer(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(dateFormat)));
objectMapper.registerModule(module);
log.info("serialized local date time = {}", objectMapper.writeValueAsString(LocalDateTime.now()));
这会产生预期的输出:
2022-11-19 23:45:21.794 INFO 24320 --- [ main] c.e.s.SpringWebDemoApplication : serialized local date time = "19.11.2022 23:45:05"
至于您的主要问题,添加以下bean将在序列化期间完成所需的LocalDateTime
格式化工作,而无需对生成的模型类进行任何更改:
private static final String dateTimeFormat = "yyyy-MM-dd HH:mm:ss";
@Bean
public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
return builder -> {
builder.simpleDateFormat(dateTimeFormat);
builder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(dateTimeFormat)));
};
}
确保您的项目中没有其他Spring自动配置ObjectMapper
的配置可能会覆盖这些设置。