Болевые точки
При разработке с помощью Spring mvc мы часто сталкиваемся со строками времени в определенном формате из внешнего интерфейса, которые нельзя использовать с новыми функциями java8.java.time
Параметры определенного типа в пакете получаются напрямую. Мы используем содержащиеjava.time
Тип упаковки
Прием параметра также сообщит о проблеме с десериализацией, а также будут некоторые проблемы с форматированием в интерфейсе возврата с типом времени. Сегодня мы подошли к их полному решению.
предложение
На самом деле, наиболее научное предложение состоит в том, чтобы использовать временные метки для единообразного представления времени. Это наиболее совершенный вариант, позволяющий избежать проблем совместимости интерфейсных браузеров, а также избежать проблем с сериализацией/десериализацией некоторых других промежуточных программ. Но это может быть более ясно и семантически выражено во времени.
У этих двух методов есть свои достоинства, и если мы настаиваем на использовании библиотеки классов времени java8, выхода нет. Ниже мыjava.time.LocalDateTime
Решайте эти проблемы одну за другой.
локальная аннотация
В Интернете есть много статей, в которых говорится, что аннотация направлена из внешнего интерфейса в задний, то есть внешний интерфейс передает формат параметра времени на задний конец, что не является неправильным! Но есть небольшая проблема, этот метод можно использовать только в тех случаях, когда не задействована десериализация. То есть применяются следующие сценарии:
@GetMapping("/local")
public Map<String, String> data(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime localDateTime) {
Map<String, String> map = new HashMap<>(1);
map.put("data", localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
return map;
}
Это не сработает, если вы используете его в следующем сценарии:
@Data
public class UserInfo {
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime birthday;
private String name;
private Integer age;
}
@PostMapping("/user")
public Object postData(@RequestBody UserInfo userInfo) {
System.out.println("userInfo = " + userInfo);
return userInfo;
}
Причина в том, что параметры запроса Post находятся в теле и должны быть десериализованы в объекты. По умолчанию используется библиотека классов jackson для десериализации и не вызывает@DateTimeFormat
Механизм аннотации.
Затем нам нужно использовать аннотации форматирования Джексона.@JsonFormat
. мы будем классом сущностиUserInfo
Измените его на следующее:
@Data
public class UserInfo {
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime birthday;
private String name;
private Integer age;
}
Вышеупомянутые две аннотации могут сосуществовать, но должны быть четко указаны их соответствующие сценарии использования. Вот еще одна маленькая деталь: формат должен соответствовать типу времени. Напримерyyyy-MM-dd
вести перепискуjava.time.LocalDate
.
Если вы можете персонализировать его немного больше@JsonFormat
возможно@JsonDeserialize
а также@JsonSerialize
заменять. но ихusing
Параметр должен быть реализован вами как соответствующий тип времени.
если@JsonFormat
,@JsonDeserialize
а также@JsonSerialize
одновременно существуют@JsonFormat
приоритет выше.
Преимущества местного лечения
Преимущество местного лечения заключается в восьми словах: сто цветов расцветают, сто школ спорят. Разнообразие и персонализация могут быть сохранены. Но часть приносит новую проблему: нет единого стандарта и несовместимости. Это делает обслуживание неудобным. Поэтому иногда мы можем управлять им глобально в зависимости от потребностей бизнеса. Ниже мы объясним, как выполнить глобальную настройку.
Конфигурация глобального формата времени
Глобализация фактически основана на@DateTimeFormat
а также@JsonFormat
Есть два сценария для настройки. за@DateTimeFormat
В сценарии мы реализуем интерфейс, предоставляемый Spring:
DateTimeFormatter :
// 时间格式化
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
Интерфейс преобразования типов:
org.springframework.core.convert.converter.Converter<S,T>
выполнить:
@Bean
public Converter<String, LocalDateTime> localDateConverter() {
return new Converter<String, LocalDateTime>() {
@Override
public LocalDateTime convert(String source) {
return LocalDateTime.parse(source, FORMATTER);
}
};
}
Или отформатируйте интерфейс:
org.springframework.format.Formatter<T>
выполнить :
@Bean
public Formatter<LocalDateTime> localDateFormatter() {
return new Formatter<LocalDateTime>() {
@Override
public LocalDateTime parse(String text, Locale locale) throws ParseException {
return LocalDateTime.parse(text, FORMATTER);
}
@Override
public String print(LocalDateTime object, Locale locale) {
return object.format(FORMATTER);
}
};
}
Реализация вышеуказанных двух интерфейсов должна быть зарегистрирована как Spring Bean, и вы можете выбрать один из двух при настройке, где S — это источник, который на самом деле является временной строкой внешнего интерфейса. T - это Target, который является целью, которая представляет тип времени java, который вам нужно преобразовать или отформатировать.
Затем для сериализации и десериализации времени мы можем настроить следующим образом (на основе джексона по умолчанию, в качестве примера возьмем LocalDateTime):
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder
// 反序列化
.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(FORMATTER))
// 序列化
.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(FORMATTER));
}
Точно так же пользовательский компоновщик jsonMapper должен быть зарегистрирован как Spring Bean.
Основы глобальной конфигурации
Некоторые преимущества и недостатки глобальной конфигурации были объяснены выше, здесь я все же хочу рассказать об основных моментах, чтобы вы не наступили на яму. Глобальная конфигурация аналогична локальной конфигурации. Такой же образец должен быть согласован. Это требует от нас быть глобально последовательными. Мы можем реализовать более одной глобальной конфигурации дляLocalDate
,OffsetDateTime
приспособление. В то же время, если мы обращаемся к другому промежуточному ПО, которому необходимо использовать сериализацию/десериализацию, например, к Redis и RabbitMQ, мы также должны обратить внимание на адаптацию.
##Суммировать Благодаря приведенному выше введению в локальные и глобальные методы обработки формата времени я считаю, что проблема времени Spring mvc, которая вас беспокоит, больше не будет существовать. Если вы считаете, что написали это правильно, пожалуйста, перешлите это другим учащимся, поставьте лайк и подпишитесь на них.
关注公众号:码农小胖哥,获取更多资讯