zoukankan      html  css  js  c++  java
  • SpringMvc Json LocalDateTime 互转,form urlencoded @ModelAttribute 转换

    JDK8 的LocalDate 系列日期API ,比Date 或者 Calendar 都好用很多,但是在SpringMvc 自动装配会有点小问题

    会导致抛出类似异常

    default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDateTime' for property 'createDate';
    nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type ... for value '2017-11-03';
    nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value

    解决方法 1  注意 @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") form 或者url 传过来的 日期必须严格根据此 格式,实在没有的,需要在前端补全格式,否则依然会抛出以上异常

        @JsonDeserialize(using = LocalDateTimeDeserializer.class)  //application/json
        @JsonSerialize(using = LocalDateTimeSerializer.class) //application/json
      //LocalDateTime @DateTimeFormat(pattern
    = "yyyy-MM-dd HH:mm:ss")    //application/x-www-form-urlencoded private LocalDateTime createDate;
      //LocalDate
        @DateTimeFormat(pattern = "yyyy-MM-dd")    //application/x-www-form-urlencoded
        private LocalDate createDate;

    解决方法 2 此方法只处理json  不能处理 application/x-www-form-urlencoded 也就是说 @ModelAttribute 的时候还是需要  @DateTimeFormat 注解

    继承 WebMvcConfigurerAdapter

      private static class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
    
            private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
            @Override
            public void serialize(LocalDateTime value, JsonGenerator jgen, SerializerProvider provider)
                    throws IOException {
                jgen.writeString(dateTimeFormatter.format(value));
            }
    
        }
    
        private static class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
    
            @Override
            public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
                String result = StringDeserializer.instance.deserialize(jsonParser, deserializationContext);
                return LocalDateTimeUtil.UDateToLocalDateTime(DateUtil.parseDate(DateUtil.C_TIME_PATTON_DEFAULT,result));
            }
        }
       @Override
        public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
            for (HttpMessageConverter converter : converters) {
                if (converter instanceof MappingJackson2HttpMessageConverter) {
                    ObjectMapper objectMapper = ((MappingJackson2HttpMessageConverter) converter).getObjectMapper();
                    SimpleModule module = new SimpleModule();
                    module.addSerializer(LocalDateTime.class,new LocalDateTimeSerializer());
                    module.addDeserializer(LocalDateTime.class,new LocalDateTimeDeserializer());
                    objectMapper.registerModule(module);
                }
            }
        }

     2018年3月12日 15:09:28 对 解决方法 2 的补充 在继承WebMvcConfigurerAdapter的配置类中注册转换器 可以支持application/x-www-form-urlencoded 的自动装配

     @Override
        public void addFormatters(FormatterRegistry registry) {
            registry.addConverter(new DateConverter());
            registry.addConverter(new LocalDateConverter());
            registry.addConverter(new LocalDateTimeConverter());
        }
    
        public static class DateConverter implements Converter<String, Date> {
            @Override
            public Date convert(String source) {
                if (!NumberUtils.isDigits(source))
                    return null;
                Long milli = NumberUtils.createLong(source);
                return new Date(milli);
            }
        }
    
        public static class LocalDateTimeConverter implements Converter<String, LocalDateTime> {
            @Override
            public LocalDateTime convert(String source) {
                if (!NumberUtils.isDigits(source))
                    return null;
                Long milli = NumberUtils.createLong(source);
                return LocalDateTime.ofEpochSecond(milli, 0, ZoneOffset.UTC);
            }
        }
    
        public static class LocalDateConverter implements Converter<String, LocalDate> {
            @Override
            public LocalDate convert(String source) {
                if (!NumberUtils.isDigits(source))
                    return null;
                Long milli = NumberUtils.createLong(source);
                return LocalDateTime.ofEpochSecond(milli, 0, ZoneOffset.UTC).toLocalDate();
            }
        }
  • 相关阅读:
    JS 、JQ 获取宽高总结 & JS中getBoundingClientRect的作用及兼容方案
    JS与JQ 获取页面元素值的方法和差异对比
    ES6
    移动端:active伪类无效的解决方法
    JavaScript中valueOf函数与toString方法
    Reverse Words in a String -- LeetCode
    Count Primes -- LeetCodes (primality test)
    Maximum Size Subarray Sum Equals k -- LeetCode
    Subsets II -- LeetCode
    Maximum Product of Word Lengths -- LeetCode
  • 原文地址:https://www.cnblogs.com/sweetchildomine/p/7807868.html
Copyright © 2011-2022 走看看