I want to configure jackson to output any date/time values with the following format:
spring.jackson.date-format=yyyy-MM-dd'T'HH:mm:ss
I'm fetching many database rows and return them just as a json map.
@RestController
public class MyService {
@GetMapping
public List<Map<String, Object>> get(Param params) {
return jdbcTemplate.queryForList(sql, params);
}
}
Problem: the databases and jvm default timezone is Europe/Berlin, thus UTC+2. Therefor jackson automatically converts any database-received java.sql.Timestamp to UTC first (subtracts 2 hours), and then outputs them via json.
In the mysql database itself, it's a datetime type.
But I just want jackson to output the timestamps "as is", without prior conversion! Is that possible to skip timezone correction?
I just want to ignore the timezone without conversation. Just cut it.
You could set a time zone in the date format used by ObjectMapper. It will be used for Date and subclasses:
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(dateFormat);
In Spring applications, to configure ObjectMapper, you can do as follows:
@Bean
public ObjectMapper objectMapper() {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(dateFormat);
return mapper;
}
In Spring Boot you can use the property spring.jackson.time-zone to define the timezone:
spring.jackson.time-zone: Europe/Berlin
For more details on the common application properties, refer to the documentation.
Instead of using Timestamp, you could consider LocaDateTime from the JSR-310. It was introduced in Java 8. The "local" date and time classes (LocalDateTime, LocalDate and LocalTime) are not tied to any one locality or time zone. From the LocalDateTime documentation:
This class does not store or represent a time-zone. Instead, it is a description of the date, as used for birthdays, combined with the local time as seen on a wall clock. It cannot represent an instant on the time-line without additional information such as an offset or time-zone.
This answer will give you more details on the new date and time classes.
Jackson has a module that supports JSR-310 types. Add it to your dependencies:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.9</version>
</dependency>
Then register the JavaTimeModule module in your ObjectMapper instance:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
Most JSR-310 types will be serialized using a standard ISO-8601 string representation. If you need a custom format, you can use your own serializer and deserializer implementation. See the documentation for details.
Finally it turned out the simples way is to just set the jacksons ObjectMapper (which uses UTC by defaut) timezone to the jvm defaults:
@Bean
public Jackson2ObjectMapperBuilderCustomizer init() {
return new Jackson2ObjectMapperBuilderCustomizer() {
@Override
public void customize(Jackson2ObjectMapperBuilder builder) {
builder.timeZone(TimeZone.getDefault());
}
};
}
I'd appreciate if anybody knows how I can achieve the same by just using the spring.jackson.time-zone application.property.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With