spring-boot 接口请求之Date、LocalDate、LocalDateTime日期类型转换处理

 搭建完一个spring-boot的接口服务后,可以在前段通过ajax异步请求后台接口数据,一般ajax通过传递json对象给后台接口,后台接收数据转化为Bean对象,处理逻辑完成后,将返回的数据转为json回送给前台调用者;

1.前台ajax参数格式为:

var param1={
    id:1234,
    name:'名称',
    path:'路径',
    createdDate:'2017-01-05 12:45:32'
}


2.ajax 调用

$.get("http://***********/ajaxApi/getOfBean",param, function(result){
    console.info("result:"+JSON.stringify(result));
});


3.后台接收参数的Bean实体类

public class Ajax implements Serializable{
    private Long id;
    private String name;
    private String path;
    private Date createdDate;
    
}


4.后台spring-boot提供的接口:

@RestController
@RequestMapping(value="ajaxApi")
@Api(value = "/ajaxApi", description = "异步接口测试API",tags={"/ajaxApi"})
public class AjaxController {
  private static final Logger logger = LoggerFactory.getLogger(AjaxController.class);
  /***
   * 异步参数接收
   * @return
   */
    @RequestMapping(value = "/getOfBean")
    @ApiOperation("Bean实体参数")
    public Ajax getOfBean(Ajax ajax) throws Exception{
      logger.info("异步参数接收:{}",ajax.toString());//打印接收的对象
      return ajax;
    }
 }


接口接收参数为AjaxBean实体类,结束后返回该实体类给前台;启动项目,触发ajax请求,报错:

【org.springframework.validation.BindException】

<span style="font-size:18px;color:#ff0000;">Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'createdDate';
 nested exception is org.springframework.core.convert.ConversionFailedException: 
Failed to convert from type [java.lang.String] to type [java.util.Date] for value '2017-01-05 12:45:32'; 
nested exception is java.lang.IllegalArgumentException</span>

【报错原因】:
 ajax使用json字符串将日期字符串发送到后台接口,后台无法将字符串转为日期类型,缺少转换器;

【解决方法】:

 增加日期类型转换器,方式有四种:

第一种:在Bean实体字段或参数上增加@DateTimeFormat注解

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createdDate;


第二种:在接收参数的的Controller中增加@InitBinder转化方法

@InitBinder
protected void initBinder(WebDataBinder binder) {
   SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
   binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}


【*】此种方式只对当前controller起作用

第三种:配置全局的日期转换器

/**
 * 转换解析器
 * @author wangqingguo 2017/9/25
 */
@Configuration
public class MappingConverterAdapter {
    /***
     * 日期参数接收转换器,将json字符串转为日期类型
     * @return
     */
    @Bean
    public Converter<String, Date> DateConvert() {
        return new Converter<String, Date>() {
            @Override
            public Date convert(String source) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = null;
                try {
                    date = sdf.parse((String) source);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return date;
            }
        };
    }
}

【*】此处定义的dateConvert用来转换Date类型,如果是LocalDate、LocalDateTime类型,则将Date
类型换成相应的类型即可,注意java8的日期类型需要用Formatter格式化:

/**
 * 转换解析器
 * @author wangqingguo 2017/9/25
 */
@Configuration
public class MappingConverterAdapter {
    /***
     * 日期参数接收转换器,将json字符串转为日期类型
     * @return
     */
   @Bean
    public Converter<String, LocalDateTime> LocalDateTimeConvert() {
        return new Converter<String, LocalDateTime>() {
            @Override
            public LocalDateTime convert(String source) {
 
                DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                LocalDateTime date = null;
                try {
                    date = LocalDateTime.parse((String) source,df);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return date;
            }
        };
    }
}

第四种:配置Formatter日期转换器

/**
 * 日期转换器
 * @author LiMeng 2017/11/7
 */
@Configuration
public class DateConfig {
    /***
     * Date日期类型转换器
     * @return
     */
    @Bean
    public Formatter<Date> dateFormatter() {
        return new Formatter<Date>() {
 
            @Override
            public Date parse(String text, Locale locale) throws ParseException {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = null;
                try {
                    date = sdf.parse(text);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return date;
            }
 
            @Override
            public String print(Date object, Locale locale) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                return sdf.format(object);
            }
        };
    }
}

【*】如果是LocalDate、LocalDateTime类型,则将Date类型换成相应的类型即可,
注意java8的日期类型需要用Formatter格式化:

/**
 * 日期转换器
 * @author LiMeng 2017/11/7
 */
@Configuration
public class DateConfig {
    /***
     * Date日期类型转换器
     * @return
     */
    @Bean
    public Formatter<Date> dateFormatter() {
        return new Formatter<Date>() {
 
            @Override
            public Date parse(String text, Locale locale) throws ParseException {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = null;
                try {
                    date = sdf.parse(text);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return date;
            }
 
            @Override
            public String print(Date object, Locale locale) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                return sdf.format(object);
            }
        };
    }
    @Bean
    public Formatter<LocalDate> localDateFormatter() {
        return new Formatter<LocalDate>() {
            @Override
            public LocalDate parse(String text, Locale locale) throws ParseException {
                return LocalDate.parse(text, DateTimeFormatter.ISO_LOCAL_DATE);
            }
 
            @Override
            public String print(LocalDate object, Locale locale) {
                return DateTimeFormatter.ISO_LOCAL_DATE.format(object);
            }
        };
    }
 
    @Bean
    public Formatter<LocalDateTime> localDateTimeFormatter() {
        return new Formatter<LocalDateTime>() {
            @Override
            public String print(LocalDateTime localDateTime, Locale locale) {
                DateTimeFormatter formatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                return formatter.format(localDateTime);
            }
 
            @Override
            public LocalDateTime parse(String text, Locale locale) throws ParseException {
                DateTimeFormatter formatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                return LocalDateTime.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }
        };
    }
}

OK,启动系统,可以正常访问,但这时发现后台返回前台的数据为:
{"id":1234,"name":"名称","path":"路径","createdDate":1483545600000}

发现后台可以正常接收日期类型,但返回后前台接收的日期成了时间戳;理想情况下前台接收到时间的格式化字符串数据;
之所以出现这个问题,是因为项目没有对返回的JSON进行处理解析;

【报错原因】:
 java中的日期类型,在转为JSON字符串时没有进行日期格式化;

【解决方法】:
解决方式有以下几种

第一种:在Bean实体属性增加 @JsonFormat注解

   @JsonFormat( pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    private Date createdDate;
    @JsonFormat( pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createdTime;

【*】注:Date类型的使用注解 会出现事件相差8小时的情况,需要设定timezone属性指定时区;LocalDateTime类型没有发现此问题,所以没有加此属性;
另外LocalDateTime只加此注解,还是无法解析,需要增加jackson-datatype-jsr310jar包才管用

compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.9.3'
第二种:增加MappingJackson2HttpMessageConverterAdapter 转换器,对日期类型进行格式化转换:

/**
 * JSON解析器
 * @author wangqingguo 2017/9/25
 */
@Configuration
public class MappingJackson2HttpMessageConverterAdapter {
 
    /***
     * 配置JSON解析器内容
     * @return
     */
    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter a= new MappingJackson2HttpMessageConverter();
        /***
         * 头格式
         */
        List<MediaType> supportedMediaTypes=new ArrayList<>();
        supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        supportedMediaTypes.add(MediaType.TEXT_HTML);
        supportedMediaTypes.add(MediaType.TEXT_PLAIN);
        a.setSupportedMediaTypes(supportedMediaTypes);
 
        /***
         * 日期格式化,解决返回的日期类型格式化
         */
        ObjectMapper objectMapper = a.getObjectMapper();
        DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        objectMapper.setDateFormat(dateFormat);
        a.setObjectMapper(objectMapper);
 
 
        return a;
    }
}


【*】注:此种方式只对Date类型起作用,Java8的LocalDateTime类型不起作用,LocalDateTime类型还是需要用@JsonFormat注解的形式;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值