ホームページ >Java >&#&チュートリアル >Spring Boot の日付と時刻を処理する方法
この状況は、時刻が Json 文字列として使用される場合とは異なる方法で処理する必要があります。これは、フロントエンドの JSON の最下層がバックエンドに変換されるためです。 pojoではJsonシリアル化Jacksonツール(HttpMessgeConverter
)を使用しますが、通常のリクエストパラメータとして時刻文字列が渡される場合はConverter
を使用して変換する処理方法の違いがあります。ふたつの間に。
実装org.springframework.core.convert.converter.Converter
、カスタム パラメーター コンバーターを次のように使用します:
@Configuration public class DateConverterConfig { @Bean public Converter<String, LocalDate> localDateConverter() { return new Converter<String, LocalDate>() { @Override public LocalDate convert(String source) { return LocalDate.parse(source, DateTimeFormatter.ofPattern("yyyy-MM-dd")); } }; } @Bean public Converter<String, LocalDateTime> localDateTimeConverter() { return new Converter<String, LocalDateTime>() { @Override public LocalDateTime convert(String source) { return LocalDateTime.parse(source, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); } }; } }
コメント: 上記の 2 つの Bean は、spring mvc のパラメーター パーサーに挿入されます (ParameterConversionService
と呼ばれるようです)。受信文字列が LocalDateTime クラスに変換されるとき、spring はコンバータ この入力パラメータを変換します。
注: カスタムパラメータコンバータ Converter に関して、落とし穴があります。上記の匿名内部クラスをラムダ式に簡略化すると、
@Bean @ConditionalOnBean(name = "requestMappingHandlerAdapter") public Converter<String, LocalDate> localDateConverter() { return source -> LocalDate.parse(source, DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)); }
プロジェクトを再度開始すると例外が発生します。 :
原因: java.lang.IllegalArgumentException: コンバータのソース タイプ 1eefd63bbe027a2807ccada294a3372c とターゲット タイプ 8742468051c85b06f0a0af9e3e506b5c を決定できません [com.example.demo126.config.MappingConverterAdapter$$ Lambda$522/817994751]; クラスはこれらの型をパラメータ化しますか?
理由:
Web プロジェクトが登録を開始するときに初期化されますrequestMappingHandlerAdapter
## WebBindingInitializer
adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer());そして
ConfigurableWebBindingInitializer には
FormattingConversionService が必要です。 と
FormattingConversionService によりすべての
Converter が追加されます。追加時にジェネリック情報を取得する必要があります:
@Override public void addFormatters(FormatterRegistry registry) { for (Converter<?, ?> converter : getBeansOfType(Converter.class)) { registry.addConverter(converter); } for (GenericConverter converter : getBeansOfType(GenericConverter.class)) { registry.addConverter(converter); } for (Formatter<?> formatter : getBeansOfType(Formatter.class)) { registry.addFormatter(formatter); } }Converter.class を追加すると、通常、インターフェースを通じて 2 つのジェネリックの特定の型を取得します。
public ResolvableType as(Class<?> type) { if (this == NONE) { return NONE; } Class<?> resolved = resolve(); if (resolved == null || resolved == type) { return this; } for (ResolvableType interfaceType : getInterfaces()) { ResolvableType interfaceAsType = interfaceType.as(type); if (interfaceAsType != NONE) { return interfaceAsType; } } return getSuperType().as(type); }ラムダ式のインターフェースは Converter であり、特定の型は取得できません。この場合の解決策は次のとおりです:
requestMappingHandlerAdapterbean が登録されるまで待ってから独自のコンバータを追加すると、
FormattingConversionService
@Bean @ConditionalOnBean(name = "requestMappingHandlerAdapter") public Converter<String, LocalDateTime> localDateTimeConverter() { return source -> LocalDateTime.parse(source, DateTimeUtils.DEFAULT_FORMATTER); }注: ここでは、Date 日付形式を照合するときに hutool が直接使用されます。これは、すでに作成した解析ツール クラスです。ここでは車輪の再発明はしません。次のメソッドでもこのツール クラスを使用します。必要に応じて、独自のプロジェクトでこのツール クラスを使用することも非常に簡単です。次のように、プロジェクトの pom ファイルに hutool の依存関係を導入するだけです:
@Component public class DateConverter implements Converter<String, Date> { @Override public Date convert(String value) { /** * 可对value进行正则匹配,支持日期、时间等多种类型转换 * 这里在匹配Date日期格式时直接使用了 hutool 为我们已经写好的解析工具类,这里就不重复造轮子了 * cn.hutool.core.date.DateUtil * @param value * @return */ return DateUtil.parse(value.trim()); } }Use Spring annotationsUse spring's annotations独自のアノテーション
@DateTimeFormat(pattern = "yyyy-MM-dd")、次のように:
<!--hu tool 工具类--> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.1.3</version> </dependency>カスタムパラメータコンバータが使用されている場合、Spring はこのメソッドを優先的に使用して処理します。つまり、Spring アノテーションは有効になりません。 Use ControllerAdvice with initBinder
@DateTimeFormat(pattern = "yyyy-MM-dd") private Date startDate;
post,content-type=application/json、バックグラウンドでは
@ が使用されます。 RequestBody 受信、デフォルトの受信および戻り値の形式は次のとおりです:
yyyy-MM-dd HH:mm:ss
spring:サポートjackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT 8
(content-type=application/json) リクエストの文字列形式は yyyy-MM-dd です
HH:mm:ss 、バックグラウンドで
@ を使用 RequestBody が受信され、戻り値の日付が
yyyy-MM-dd HH:mm:ss 形式の文字列に変換されます;
content-type=application/json ) リクエスト内の
yyyy-MM-dd およびその他のタイプの文字列は、
date;
java8date
api はサポートされていません;
@ControllerAdvice public class GlobalExceptionHandler { @InitBinder protected void initBinder(WebDataBinder binder) { binder.registerCustomEditor(LocalDate.class, new PropertyEditorSupport() { @Override public void setAsText(String text) throws IllegalArgumentException { setValue(LocalDate.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd"))); } }); binder.registerCustomEditor(LocalDateTime.class, new PropertyEditorSupport() { @Override public void setAsText(String text) throws IllegalArgumentException { setValue(LocalDateTime.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); } }); binder.registerCustomEditor(LocalTime.class, new PropertyEditorSupport() { @Override public void setAsText(String text) throws IllegalArgumentException { setValue(LocalTime.parse(text, DateTimeFormatter.ofPattern("HH:mm:ss"))); } }); } }
以上がSpring Boot の日付と時刻を処理する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。