Как пропустить коррекцию часового пояса Джексона в Spring-MVC? - PullRequest
0 голосов
/ 26 апреля 2018

Я хочу настроить jackson для вывода любых значений даты / времени в следующем формате:

spring.jackson.date-format=yyyy-MM-dd'T'HH:mm:ss

Я извлекаю много строк базы данных и возвращаю их как json карту.

@RestController
public class MyService {
    @GetMapping
    public List<Map<String, Object>> get(Param params) {
             return jdbcTemplate.queryForList(sql, params);
    }
}

Проблема: часовой пояс по умолчанию для баз данных и jvm Europe/Berlin, таким образом, UTC + 2. Поэтому Джексон автоматически преобразует все полученные из базы данных java.sql.Timestamp сначала в UTC (вычитает 2 часа), а затем выводит их через json.

В самой базе данных mysql это тип datetime.

Но я просто хочу, чтобы Джексон выводил временные метки "как есть", без предварительного преобразования! Можно ли пропустить коррекцию часового пояса?

Я просто хочу игнорировать часовой пояс без разговоров. Просто обрежь его.

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Наконец оказалось, что проще всего просто установить часовой пояс ObjectMapper (который использует UTC по умолчанию) в часовой пояс jvm по умолчанию:

@Bean
public Jackson2ObjectMapperBuilderCustomizer init() {
    return new Jackson2ObjectMapperBuilderCustomizer() {
        @Override
        public void customize(Jackson2ObjectMapperBuilder builder) {
            builder.timeZone(TimeZone.getDefault());
        }
    };
}

Буду признателен, если кто-нибудь знает, как я могу добиться того же, просто используя spring.jackson.time-zone application.property.

0 голосов
/ 26 апреля 2018

Подход № 1: Установка часового пояса по умолчанию

Вы можете установить часовой пояс в формате даты, используемом ObjectMapper. Он будет использоваться для Date и подклассов:

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));

ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(dateFormat);

В приложениях Spring для настройки ObjectMapper вы можете сделать следующее:

@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;
}

В Spring Boot вы можете использовать свойство spring.jackson.time-zone для определения часового пояса:

spring.jackson.time-zone: Europe/Berlin

Подробнее об общих свойствах приложения см. В документации .

Подход № 2. Использование Java 8 Date & Time API

Вместо использования Timestamp вы можете рассмотреть LocaDateTime из JSR-310 . Он был введен в Java 8. "локальные" классы даты и времени (LocalDateTime, LocalDate и LocalTime) не привязаны ни к одной местности или часовому поясу. Из LocalDateTime документации:

Этот класс не хранит и не представляет часовой пояс. Вместо этого, это описание даты, используемой для дней рождений, в сочетании с местным временем, показанным на настенных часах. Он не может представлять момент на временной шкале без дополнительной информации, такой как смещение или часовой пояс.

Этот ответ даст вам более подробную информацию о новых классах даты и времени.

Джексон имеет модуль, который поддерживает типы JSR-310. Добавьте его в свои зависимости:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.9</version>
</dependency>

Затем зарегистрируйте модуль JavaTimeModule в вашем ObjectMapper экземпляре:

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

Большинство типов JSR-310 будут сериализованы с использованием стандартного строкового представления ISO-8601 . Если вам нужен собственный формат, вы можете использовать свой собственный сериализатор и десериализатор. Подробнее см. документацию .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...