Reputation: 2942
I have Spring boot application and LocalDateTime properties serialized as JSON array, instead of String.
As I found while search on web, all I need is to set up in application.properties
spring.jackson.serialization.write-dates-as-timestamps=false
I also tried to put jackson-datatype-jsr310 to dependencies, but no luck either
Also I tried to add annotation:
@DateTimeFormat(iso = ISO.DATE_TIME)
it not helps too.
I saw a lot of people get in something similar, but their solutions seems related to Spring Boot 1.x, while I use 2.04
Also I use Lombok, but not sure is it affects serialization format.
How can I track down and fix the date serialization format to be ISO date String?
Here response example (start is LocalDateTime and I want to have it as ISO String):
{
"id": 3,
"enabled": true,
"outletId": 5,
"reason": "hello",
"start": [
2019,
9,
10,
10,
42,
11
],
"status": "AVAILABLE"
}
Here the REST controller method response object:
@Data
@Entity
@Table(indexes = { @Index(columnList = ("outletId"),name="outlet_id_index"),
@Index(columnList = ("start"),name="start_index"),
@Index(columnList = ("outletId, start"),name="outlet_id_start_index")})
public class OutletChron extends BaseEntity {
private Long outletId;
private String reason;
@DateTimeFormat(iso = ISO.DATE_TIME)
private LocalDateTime start;
@Enumerated(EnumType.STRING)
@Column(length = 30)
private OutletStatus status;
}
Here my POM:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.banquets</groupId>
<artifactId>Banquet</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Banquet</name>
<description></description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web-services</artifactId>
</dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency> -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
UPDATE
I build a new project just to test, and I found there String format was default for LocalDateTime mapping. I was able to track down that format changes once I configure swagger. So without this swagger config I have String format:
@Configuration
@EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurationSupport {
@Autowired
ServletContext servletContext;
@Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.demo"))
.build();
}
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
UPDATE this Swagger config seems works (Date format is String and I can access Swagger UI at http://localhost:8000/api/swagger-ui.html
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket apiDocket() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}
Upvotes: 6
Views: 6434
Reputation: 6254
Spring boot 2.x does not required to import JSR310 specifications as now its part of spring framework now so no need to import them and string formatting will automatically work.
If you need to override some default configuration of spring boot then you need to implement WebMvcConfigurer
instead of extending WebMvcConfigurationSupport
.
In your case, if you want to put static files somewhere else not in default resources folder then you might need to override addResourceHandlers
and register paths.
If resources in default path then not required and just removing extending WebMvcConfigurationSupport
will work for default string formatting.
UPDATED ANSWER:
If you use WebMvcConfigurationSupport
that means uts an indication that it shouldn't auto-configure Spring MVC, means default settings will not work and you have to define all things here by overriding its support methods. So instead of WebMvcConfigurationSupport
implement WebMvcConfigurer
instead.
Here is the updated config.
@Configuration
@EnableSwagger2
public class SwaggerConfig implements WebMvcConfigurer {
@Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.demo"))
.build();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
Upvotes: 7
Reputation: 4451
For me the following works:
@JsonFormat(pattern = "dd.MM.yyyy HH:mm")
private LocalDateTime startTime;
This will print the date in a string format e.g. like 11.09.2018 15:44
Upvotes: 3
Reputation: 3951
Create object mapper manually
@Bean
@Primary
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
JavaTimeModule timeModule = new JavaTimeModule();
mapper.registerModule(timeModule);
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
return mapper;
}
Upvotes: 1