Situasi ini harus dilayan secara berbeza daripada masa digunakan sebagai rentetan Json, kerana json hujung depan ke pojo hujung belakang menggunakan Json alat Jackson bersiri (HttpMessgeConverter
); apabila rentetan masa dihantar sebagai parameter permintaan biasa, Converter
digunakan untuk penukaran Terdapat perbezaan dalam kaedah pemprosesan antara keduanya.
untuk melaksanakan org.springframework.core.convert.converter.Converter
, penukar parameter tersuai, seperti berikut:
@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")); } }; } }
Ulasan: Dua biji di atas akan disuntik ke Penghurai parameter spring mvc (nampaknya dipanggil ParameterConversionService
), apabila rentetan masuk hendak ditukar ke dalam kelas LocalDateTime, spring akan memanggil Penukar untuk menukar parameter input.
Nota: Berkenaan penukar parameter tersuai, terdapat perangkap Jika kelas dalaman tanpa nama di atas dipermudahkan menjadi ungkapan lambda:
@Bean @ConditionalOnBean(name = "requestMappingHandlerAdapter") public Converter<String, LocalDate> localDateConverter() { return source -> LocalDate.parse(source, DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)); }
Apabila projek dimulakan semula Pengecualian akan berlaku. :
Disebabkan oleh: java.lang.IllegalArgumentException: Tidak dapat menentukan jenis sumber
dan jenis sasaranuntuk Penukar anda [com.example.demo126.config Lambda$522/817994751]; adakah kelas membuat parameter jenis tersebut?
adalah kerana:
Projek web akan dimulakan apabila ia mula mendaftar requestMappingHandlerAdapter
WebBindingInitializer
adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer());
dan ConfigurableWebBindingInitializer
memerlukan FormattingConversionService,
dan FormattingConversionService
akan menambah semua Converter
s Apabila menambah, anda perlu mendapatkan maklumat generik:
@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); } }
Add Converter.class biasanya melalui The. antara muka memperoleh jenis khusus dua jenis generik
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); }
Antara muka ungkapan Lambda ialah Penukar, dan jenis khusus tidak boleh diperolehi dalam kes ini, penyelesaiannya ialah:
Kaedah paling mudah adalah dengan tidak menggunakan ungkapan Lambda dan menggunakan kelas dalaman tanpa nama, supaya masalah di atas tidak akan wujud
Tunggu sahaja sehingga pendaftaran requestMappingHandlerAdapterbean
selesai sebelum menambah anda sendiri penukar. Ia tidak akan didaftarkan dalam FormattingConversionService
@Bean @ConditionalOnBean(name = "requestMappingHandlerAdapter") public Converter<String, LocalDateTime> localDateTimeConverter() { return source -> LocalDateTime.parse(source, DateTimeUtils.DEFAULT_FORMATTER); }
juga boleh melakukan pemadanan biasa pada rentetan yang dilalui oleh hujung hadapan, seperti yyyy-MM-dd HH:mm:ss , yyyy-MM-dd, HH:mm:ss, dsb., untuk dipadankan. untuk menyesuaikan diri dengan pelbagai senario.
@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()); } }
Nota: hutool digunakan secara langsung apabila memadankan format tarikh Tarikh Ia adalah kelas alat penghuraian Kami tidak akan mencipta semula roda di sini jika anda mahu Ia juga sangat mudah untuk menggunakan kelas alat ini dalam projek anda sendiri Hanya memperkenalkan kebergantungan hutool dalam fail pom projek, seperti berikut:
<!--hu tool 工具类--> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.1.3</version> </dependency>
Gunakan anotasi spring sendiri. @DateTimeFormat(pattern = "yyyy-MM-dd")
, seperti berikut:
@DateTimeFormat(pattern = "yyyy-MM-dd") private Date startDate;
Jika penukar parameter tersuai digunakan, Spring lebih suka menggunakan kaedah ini untuk pemprosesan, iaitu anotasi Spring tidak akan berkuat kuasa.
@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"))); } }); } }
Seperti yang anda boleh lihat daripada namanya, ini ialah potongan gelung dalam pengawal (penangkapan pengecualian global juga boleh dilakukan di sini), dan parameter ditukar sebelum memasuki pengendali; penukaran Untuk objek yang sepadan.
Jenis permintaan ialah: post,content-type=application/json
, dan latar belakang menggunakan @RequestBody
untuk menerimanya Format penerimaan lalai dan nilai pulangan ialah: yyyy-MM-dd HH:mm:ss
Tambah kandungan berikut dalam fail application.propertiities:
spring:
jackson:
format tarikh: yyyy-MM- dd HH:mm:ss
zon waktu: GMT+8
menyokong rentetan dalam format yyyy-MM-dd (content-type=application/json)
dalam HH:mm:ss
meminta dan menggunakan @RequestBody
di latar belakang Tarikh nilai terima dan pemulangan ditukar kepada yyyy-MM-dd HH:mm:ss
rentetan format
tidak disokong (content-type=application/json
) dan rentetan yyyy-MM-dd
dan jenis lain; dalam permintaan ditukar kepada date
; java8
Tarikh
Atas ialah kandungan terperinci Cara mengendalikan tarikh dan masa Spring Boot. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!