How to skip jackson timezone correction in spring-mvc?
Solution 1
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.
Solution 2
Approach #1: Setting a default time zone
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.
Approach #2: Using the Java 8 Date and Time API
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.
Related videos on Youtube
membersound
JEE + Frameworks like Spring, Hibernate, JSF, GWT, Vaadin, SOAP, REST.
Updated on September 28, 2022Comments
-
membersound over 1 year
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-receivedjava.sql.Timestamp
to UTC first (subtracts 2 hours), and then outputs them via json.In the
mysql
database itself, it's adatetime
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.
-
Edwin Dalorzo almost 6 yearsGreat answer! If time zone information is relevant, wouldn’t it be better to use a
ZonedDateTime
instead of aLocalDateTime
or at least aOffsetDateTome
to account for the time differences between databases solely based on their offsets? -
membersound almost 6 years@CassioMazzochiMolin in my case I have to work with a legacy database. I just want to output the datetime values "as is" from the database via the json webservice. Any timezone correction is irrelevant, I just want to show the same value via the webservice that exists in the database (and as the mysql
datetime
type is independent oftimezone
, I also want to prevent timezone corrections in java. -
cassiomolin almost 6 years@membersound You could try to use a converter.
-
WesternGun over 5 yearsHave you tried annotate the field of
java.util.Date
withtimezone="Europe/Berlin"
inJsonFormat
?