完美处理日期类型的参数

目录

前言

一、GET方法时参数传入日期类型

举例

二、POST方法时参数传入日期类型

三、PUT方法时参数传入日期类型

Response中日期格式该如何处理


前言

RESTful开发时经常会遇到参数传入日期类型及返回的日期类型值,日期和时间戳如果没有适当和一致地处理,就会给人带来头痛的问题,我这里建议大家使用统一格式化的时间字符串yyyy-MM-dd HH:mm:ss


一、GET方法时参数传入日期类型

举例

localhost:8202/test/get_time?time=2023-5-17 12:23:25

import java.util.Date;

@RequestMapping(value = "/get_time", method = RequestMethod.GET)
@ResponseBody
public R<Date> time_get(Date time) {
    logger.info("time:{}", time);
    return service.createResponse(time);
}

在这种情况下日期参数是无法成功的传入到controller方法里,会报出如下的异常:

org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type java.util.Date for value '2018-07-09 10:38:57'; nested exception is java.lang.IllegalArgumentException    
at org.springframework.core.convert.support.ObjectToObjectConverter.convert(ObjectToObjectConverter.java:81) ~\[spring-core-4.0.0.RELEASE.jar:4.0.0.RELEASE\]    
 at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:35) ~\[spring-core-4.0.0.RELEASE.jar:4.0.0.RELEASE\]    
 at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:178) ~\[spring-core-4.0.0.RELEASE.jar:4.0.0.RELEASE\]    
 at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:161) ~\[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE\]    
 at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:93) ~\[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE\]    
 at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:64) ~\[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE\]    
 ... 43 common frames omitted    
Caused by: java.lang.IllegalArgumentException: null    
 at java.util.Date.parse(Date.java:615) ~\[na:1.7.0_45\]    
 at java.util.Date.<init>(Date.java:272) ~\[na:1.7.0_45\]    
 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~\[na:1.7.0_45\]    
 at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) ~\[na:1.7.0_45\]    
 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~\[na:1.7.0_45\]    
 at java.lang.reflect.Constructor.newInstance(Constructor.java:526) ~\[na:1.7.0_45\]    
 at org.springframework.core.convert.support.ObjectToObjectConverter.convert(ObjectToObjectConverter.java:76) ~\[spring-core-4.0.0.RELEASE.jar:4.0.0.RELEASE\]    
 ... 48 common frames omitted    

解决上面的问题,使用@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")加到日期参数之前

import java.util.Date;
 
@RequestMapping(value = "/time_get", method = RequestMethod.GET)
@ResponseBody
public Response<Date> time_get(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date time) {
    logger.info("time:{}", time);
    return Response.createResponse(time);
}

提示:年月日:pattern=”yyyy-MM-dd”,年月日时分秒:pattern=”yyyy-MM-dd HH:mm:ss”

二、POST方法时参数传入日期类型

当使用@RequestBody接受一个VO对象时@DateTimeFormat就会失效,因为我们走的是Json序列化与反序列化,@DateTimeFormat只会生效与object序列化、反序列化。如果使用的Spring可以自定义messageConvert或者增强MappingJackson2HttpMessageConverter中的ObjectMapper

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
    @Override
    protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
        addDefaultHttpMessageConverters(messageConverters);
        for (int i = 0; i < messageConverters.size(); i++) {
            HttpMessageConverter<?> mc = messageConverters.get(i);
            if (mc instanceof MappingJackson2HttpMessageConverter) {
                ObjectMapper objectMapper = new ObjectMapper();
                //当json中属性在反序列化时,javabean中没有找到属性就忽略,如果FAIL_ON_UNKNOWN_PROPERTIES=true找不到属性会报错
                objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                //设置序列化、反序列化时日期类型的格式
                objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
                ((MappingJackson2HttpMessageConverter) mc).setObjectMapper(objectMapper);
            }
            converters.add(mc);
        }
    }
}

注意:使用Jackson进行json序列化反序列化,默认可以处理yyyy-MM-dd这个格式,但是反序列化后的时间会差8小时

通过上面对json序列化反序列化的配置后日期参数处理就变的简单了

@RequestMapping(value = "/time_post", method = RequestMethod.POST)
@ResponseBody
public Response<Date> time_post(@RequestBody TestVo vo) {
    logger.info("time:{}", vo.getTime());
    return Response.createResponse(vo.getTime());
}
public class TestVo implements Serializable {
    private static final long serialVersionUID = 7435595656553442126L;
    private Date time;
    public Date getTime() {
        return time;
    }
    public void setTime(Date time) {
        this.time = time;
    }
}

三、PUT方法时参数传入日期类型

如果put传参方式与get一样在方法上直接传参(url?time=2023-5-17 12:23:25),那参考get请求参数处理方式即可

如果put传参方式与post一样使用@RequestBody传入json格式数据,那么参考post请求参数处理方式即可


Response中日期格式该如何处理

SpringMVC使用@ResponseBody时,日期格式默认显示为时间戳,不管方法直接返回Date类型、或者VO类型时,时间格式都一样返回时间戳。

如果我们要以字符串格式返回呢,那该如何处理?

  • 方法一 增加统一的messageConvert处理:

如果使用的spring可以自定义messageConvert或者增强MappingJackson2HttpMessageConverter中的ObjectMapper

代码在 POST方法时参数传入日期类型该如何处理

  • 方法二 通过@JsonFormat注解处理:

请在VO对象的date字段上加上@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8"),例如下面代码:

public class TestVo implements Serializable {
    private static final long serialVersionUID = 7435595656552442126L;
 
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date time;
    public Date getTime() {
        return time;
    }
    public void setTime(Date time) {
        this.time = time;
    }
}

注意@JsonFormat(pattern=”yyyy-MM-dd HH:mm:ss”,timezone = “GMT+8”) ,即可将json返回的对象为指定的类型。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值