开发者

SpringBoot LocalDateTime格式转换方案详解(前端入参)

目录
  • 简介
    • 说明
    • 相关网址
    • 方案简介
  • 不使用@RequestBody
    • 方案1:@ControllerAdvice+@InitBinwww.devze.comder
    • 方案2:自定义参数转换器(Converter)
  • 使用@RequestBody
    • 方案1:配置ObjectMapper
      • 法1:只用配置类
      • 法2:配置类+@jsonFormat
    • 方案2:Jackson2ObjectMapperBuilderCustomizer

    简介

    说明

            项目我们经常会有前后端时间转换的场景,比如:创建时间、更新时间等。一般情况下,前后端使用时间戳或者年月日的格式进行传递。

            如果后端收到了前端的参数每次都手动转化为想要的格式,后端每次将数据传给前端时都手动处理为想要的格式实在是太麻烦了。

            基于如上原因,本文用示例介绍SpringBoot全局格式配置,将前端传过来的时间自动转化为LocalDateTime。(本文只介绍年月日格式的转化方法,例如:2021-09-16 21:13:21 => LocalDateTime。时间戳转化为LocalDateTime的方法类似)。

    相关网址

    https://www.jb51.net/article/281341.htm

    方案简介

    要分两种情景进行配置(根据Content-Type的不同):

    1.application/x-www-form-urlencoded 和 multipart/form-data

    • 本处将此种情况记为:不使用@RequestBody

    2.application/json

    • 即:使用@RequestBody的接口
    • 本处将此种情况记为:使用@RequestBody

    备注

    有人说,可以这样配置:

    spring:

      jackson:

        date-format: yyyy-MM-dd HH:mm:ss

        time-zone: GMT+8

        serialization:

          write-dates-as-timestamps: false

    这种配置只适用于Date这种,不适用于LocalDateTime等。

    DaOLHRWGte序列化/反序列化时都是用的这种格式:"2020-08-19T16:30:18.823+00:00"。

    不使用@RequestBody

    方案1:@ControllerAdvice+@InitBinder

    配置类

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

    测试

    postman访问:http://localhost:8080/user/save?userName=Tony&createTime=2021-09-16 21:13:21

    postman结果:

    SpringBoot LocalDateTime格式转换方案详解(前端入参)

    后端结果:

    SpringBoot LocalDateTime格式转换方案详解(前端入参)

    方案2:自定义参数转换器(Converter)

    实现 org.springframework.core.convert.converter.Converter,自定义参数转换器。

    配置类

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

    测试

    postman访问:http://localhost:8080/user/save?userName=Tony&createTime=2021-09-16 21:13:21

    postman结果:

    SpringBoot LocalDateTime格式转换方案详解(前端入参)

    后端结果

    SpringBoot LocalDateTime格式转换方案详解(前端入参)

    使用@RequestBody

    方案1:配置ObjectMapper

    法1:只用配置类

    本方法只配置ObjectMapper即可,Entity不需要加@JsonFormat。

    配置类

    package com.knife.example.config;
     
    import com.fasterXML.jackson.core.JsonParser;
    imporjavascriptt com.fasterxml.jackson.databind.DeserializationContext;
    import com.fasterxml.jackson.databind.MapperFe编程客栈ature;
    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;
        }
    }

    测试

    SpringBoot LocalDateTime格式转换方案详解(前端入参)

    后端结果

    保存用户:User(id=null, userName=Tony, createTime=2021-09-16T21:13:21)

    法2:配置类+@JsonFormat

    本方法需要配置ObjectMapper,Entity也需要加@JsonFormat。

    配置类

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

    测试

    SpringBoot LocalDateTime格式转换方案详解(前端入参)

    后端结果

    保存用户:User(id=null, userName=Tony, createTime=2021-09-16T21:13:21)

    方案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"开发者_Js入门;
     
        @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.deserializepythonrByType(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)));
            };
        }
    }
    

    到此这篇关于SpringBoot LocalDateTime格式转换(前端入参)的文章就介绍到这了,更多相关SpringBoot LocalDateTime格式转换内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜