We often have scenes of front-end and back-end time conversion in projects, such as: creating time, update time, etc. Generally, the front and back ends use the timestamp or year, month and day format for transmission.
If the backend receives the front-end parameters and manually converts them into the desired format every time, it would be too troublesome for the backend to manually process the data into the desired format every time it passes the data to the front-end.
It needs to be configured in two scenarios (according to different Content-Type):
1.application/x-www-form-urlencoded and multipart/ form-data
This situation is recorded here as: not using @RequestBody
2.application/json
That is: using the interface of @RequestBody
This situation is recorded as: using @RequestBody
Remarks
Some people say that it can be configured like this:
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT 8
serialization:
write-dates-as-timestamps: false
This configuration is only applicable to Date, not LocalDateTime, etc.
Date serialization/deserialization uses this format: "2020-08-19T16:30:18.823 00:00".
Configuration class
package com.example.config; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.InitBinder; import java.beans.PropertyEditorSupport; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; @ControllerAdvice public class LocalDateTimeAdvice { @InitBinder protected void initBinder(WebDataBinder binder) { 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(LocalDate.class, new PropertyEditorSupport() { @Override public void setAsText(String text) throws IllegalArgumentException { setValue(LocalDate.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd"))); } }); binder.registerCustomEditor(LocalTime.class, new PropertyEditorSupport() { @Override public void setAsText(String text) throws IllegalArgumentException { setValue(LocalTime.parse(text, DateTimeFormatter.ofPattern("HH:mm:ss"))); } }); } }
Entity
package com.example.business.entity; import lombok.AllArgsConstructor; import lombok.Data; import java.time.LocalDateTime; @Data @AllArgsConstructor public class User { private Long id; private String userName; private LocalDateTime createTime; }
Controller
package com.example.business.controller; import com.example.business.entity.User; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("user") public class UserController { @PostMapping("save") public User save(User user) { System.out.println("保存用户:" + user); return user; } }
Test
postman visit: http://localhost:8080/user/save? userName=Tony&createTime=2021-09-16 21:13:21
postman result:
##Backend result: Option 2: Custom parameter converter (Converter) Implement org.springframework.core.convert.converter.Converter, a custom parameter converter.Configuration Class
package com.example.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.convert.converter.Converter; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @Configuration public class LocalDateTimeConfig { @Bean public Converter<String, LocalDateTime> localDateTimeConverter() { return new LocalDateTimeConverter(); } public static class LocalDateTimeConverter implements Converter<String, LocalDateTime> { @Override public LocalDateTime convert(String s) { return LocalDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); } } }
Entity
package com.example.business.entity; import lombok.AllArgsConstructor; import lombok.Data; import java.time.LocalDateTime; @Data @AllArgsConstructor public class User { private Long id; private String userName; private LocalDateTime createTime; }
Controller
package com.example.business.controller; import com.example.business.entity.User; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("user") public class UserController { @PostMapping("save") public User save(User user) { System.out.println("保存用户:" + user); return user; } }
Test
postman access: http://localhost:8080/user/save?userName=Tony&createTime=2021-09-16 21:13:21postman results: Backend results Using @RequestBodyOption 1: Configure ObjectMapperConfiguration Class
package com.knife.example.config; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.deser.std.DateDeserializers; import com.fasterxml.jackson.databind.ser.std.DateSerializer; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; import lombok.SneakyThrows; import org.springframework.boot.autoconfigure.jackson.JacksonProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.Date; @Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder, JacksonProperties jacksonProperties) { ObjectMapper objectMapper = builder.build(); // 把“忽略重复的模块注册”禁用,否则下面的注册不生效 objectMapper.disable(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS); objectMapper.registerModule(configTimeModule()); // 重新设置为生效,避免被其他地方覆盖 objectMapper.enable(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS); return objectMapper; } private JavaTimeModule configTimeModule() { JavaTimeModule javaTimeModule = new JavaTimeModule(); String localDateTimeFormat = "yyyy-MM-dd HH:mm:ss"; String localDateFormat = "yyyy-MM-dd"; String localTimeFormat = "HH:mm:ss"; String dateFormat = "yyyy-MM-dd HH:mm:ss"; // 序列化 javaTimeModule.addSerializer( LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(localDateTimeFormat))); javaTimeModule.addSerializer( LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(localDateFormat))); javaTimeModule.addSerializer( LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(localTimeFormat))); javaTimeModule.addSerializer( Date.class, new DateSerializer(false, new SimpleDateFormat(dateFormat))); // 反序列化 javaTimeModule.addDeserializer( LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(localDateTimeFormat))); javaTimeModule.addDeserializer( LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(localDateFormat))); javaTimeModule.addDeserializer( LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(localTimeFormat))); javaTimeModule.addDeserializer(Date.class, new DateDeserializers.DateDeserializer(){ @SneakyThrows @Override public Date deserialize(JsonParser jsonParser, DeserializationContext dc){ String text = jsonParser.getText().trim(); SimpleDateFormat sdf = new SimpleDateFormat(dateFormat); return sdf.parse(text); } }); return javaTimeModule; } }
Entity
package com.example.business.entity; import lombok.Data; import java.time.LocalDateTime; @Data public class User { private Long id; private String userName; private LocalDateTime createTime; }
Controller
package com.example.business.controller; import com.example.business.entity.User; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("user") public class UserController { @PostMapping("save") public User save(@RequestBody User user) { System.out.println("保存用户:" + user); return user; } }
Test
Backend resultsSave user: User(id=null, userName=Tony, createTime=2021- 09-16T21:13:21)Method 2: Configure class @JsonFormatThis method needs to configure ObjectMapper, and Entity also needs to add @JsonFormat.
Configuration Class
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; import org.springframework.boot.autoconfigure.jackson.JacksonProperties; import org.springframework.boot.jackson.JsonComponent; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; @Configuration public class JacksonConfig { @Bean public ObjectMapper serializingObjectMapper(Jackson2ObjectMapperBuilder builder, JacksonProperties jacksonProperties) { ObjectMapper objectMapper = builder.build(); // 把“忽略重复的模块注册”禁用,否则下面的注册不生效 objectMapper.disable(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS); // 自动扫描并注册相关模块 objectMapper.findAndRegisterModules(); // 手动注册相关模块 // objectMapper.registerModule(new ParameterNamesModule()); // objectMapper.registerModule(new Jdk8Module()); // objectMapper.registerModule(new JavaTimeModule()); // 重新设置为生效,避免被其他地方覆盖 objectMapper.enable(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS); return objectMapper; } }
Entity
package com.example.business.entity; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import java.time.LocalDateTime; @Data public class User { private Long id; private String userName; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime createTime; }
Controller
package com.example.business.controller; import com.example.business.entity.User; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("user") public class UserController { @PostMapping("save") public User save(@RequestBody User user) { System.out.println("保存用户:" + user); return user; } }
Test
Backend resultsSave user: User(id=null, userName=Tony, createTime=2021- 09-16T21:13:21)Option 2: Jackson2ObjectMapperBuilderCustomizer
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; @Configuration public class LocalDateTimeConfig { private final String localDateTimeFormat = "yyyy-MM-dd HH:mm:ss"; private final String localDateFormat = "yyyy-MM-dd"; private final String localTimeFormat = "HH:mm:ss"; @Bean public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { return builder -> { // 反序列化(接收数据) builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(localDateTimeFormat))); builder.deserializerByType(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(localDateFormat))); builder.deserializerByType(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(localTimeFormat))); // 序列化(返回数据) builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(localDateTimeFormat))); builder.serializerByType(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(localDateFormat))); builder.serializerByType(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(localTimeFormat))); }; } }
The above is the detailed content of What is the method for SpringBoot LocalDateTime format conversion?. For more information, please follow other related articles on the PHP Chinese website!