Spring MVC 之 处理Date类型

在使用Spring MVC的项目中,我们经常需要遇到处理时间类型的字段。一般情况下大家可能都是通过String来接收这个对象,然后再把它转化成Date类型。如何能够优雅的处理这些时间类型的字段呢?下面我来分享一下我总结的一些方法。
一、Input

假如我们有一个User对象里面有一个birthday属性。一般情况下大家在使用Spring MVC的时候可能都是使用String字段来接收。然后再把它转换成Date类型插入到数据库中。但是今天要讲的是直接使用Date类型来接收前台传输过来的日期属性。

User.class

public class User {

    private Date birthday;

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

  

1.1 form data

首先以form data的形式传输一个birthday属性。我们写一个简单Controller来测试一下。

方法一:

@Controller
public class DateController {

    @InitBinder
    public void intDate(WebDataBinder dataBinder){
        dataBinder.addCustomFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss"));
    }

    @RequestMapping("test")
    @ResponseBody
    public User test( User date){
        System.out.println(date);
        return date;
    }

}

 

这里写图片描述

没有错,就是加了@InitBinder注解,为处理Date类型添加了处理类。而且请注意这个@InitBinder是这个类级别的,也就是说你其它Controller也可以使用这种方法添加Date处理类用于处理不同的pattern.

使用@InitBinder注解还可以指定哪些属性需要被处理。

    @InitBinder
    public void intDate(WebDataBinder dataBinder){
        dataBinder.addCustomFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss"), "birthday");
    }

   

其实@InitBinder注解还可以办其它很多的事情。大家可以慢慢挖掘。

方法二:

不使用@InitBinder注解,而在你需要绑定属性的注解上面添加@DateTimeFormat注解也同样能够达到你的目的。

这里写图片描述

方法三:

使用Spring MVC的扩展接口HandlerMethodArgumentResolver。它的使用是把HttpRequest里面的参数解析成Controller里面标注了@RequestMapping方法的方法参数。

1) Date.java – 指定该方法参数需要特殊处理  

  Date.java

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Date {

    String[] params () default "";

    String pattern() default "yyyy-MM-dd HH:mm:ss";

}

  

2) DateHandlerMethodArgumentResolver – 处理标注了@Date注解的方法参数

public class DateHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

    private String[] params;

    private String pattern;

    @Override
    public boolean supportsParameter(MethodParameter parameter) {

        boolean hasParameterAnnotation = parameter.hasParameterAnnotation(Date.class);
        if(!hasParameterAnnotation){
            return false;
        }
        Date parameterAnnotations = parameter.getParameterAnnotation(Date.class);
        String[] parameters = parameterAnnotations.params();
        if(StringUtils.isNoneBlank(parameters)){
            params = parameters;
            pattern = parameterAnnotations.pattern();
            return true;
        }
        return false;
    }

    @Override
    public Object resolveArgument(MethodParameter methodParam, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        Object object = BeanUtils.instantiateClass(methodParam.getParameterType());
        BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass());
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        for (String param : params) {
            String value = request.getParameter(param);
            if(StringUtils.isNoneBlank(value)){
                SimpleDateFormat sdf = new SimpleDateFormat(this.pattern);
                java.util.Date date = sdf.parse(value);
                PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
                for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
                    if(propertyDescriptor.getName().equals(param)){
                        Method writeMethod = propertyDescriptor.getWriteMethod();
                        if(!Modifier.isPublic(writeMethod.getModifiers())){
                            writeMethod.setAccessible(true);
                        }
                        writeMethod.invoke(object, date);
                    }
                }
            }
        }
        return object;
    }
}

   

3) MyMVCConfig – 配置Spring MVC扩展   

 MyMVCConfig.java

@Configuration
@EnableWebMvc
public class MyMVCConfig extends WebMvcConfigurerAdapter{

    ......

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new DateHandlerMethodArgumentResolver());
    }
}

 

4) DateController – 测试类

@Controller
public class DateController {

    @RequestMapping("test")
    @ResponseBody
    public User test(@Date(params = "birthday") User date){
        System.out.println(date);
        return date;
    }

}

 

User类不需要做任何改变。

这里写图片描述

可以看到,这样同样能够达到效果。
1.2 restful – json

上面的两种情况针对表格提交有效,但是对于Spring MVC里面的Restful语法就会无效。下面就来看看如何针对restful请求的日期对象。

对应的Controller就需要修改一下了。   

 DateController.java

@Controller
public class DateController {

    @RequestMapping("test")
    @ResponseBody
    public User test( @RequestBody User date){
        System.out.println(date);
        return date;
    }

}

 

Spring MVC restful是底层是使用Jackson来实现的。所以针对这种情况,我们就可以使用Jackson的注解@JsonDeserialize来实现。

修改点:  

  1 、User.java

public class User {

    @JsonDeserialize(using = DateJsonDeserialize.class)
    private Date birthday;

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

对应的添加一个JsonDeserialize反序列化类。
  

  2、DateJsonDeserialize.java

public class DateJsonDeserialize extends JsonDeserializer<Date> {

    @Override
    public Date deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
        String text = p.getText();
        if(StringUtils.isBlank(text)){
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date = sdf.parse(text);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
}

 

二、ouput

对于输出,我们就使用Spring MVC使用的@ResponseBody来返回json对象。但是如果我们不加处理返回的对象就是一个时间long的数据。

这里写图片描述

同样的Spring MVC的返回值也是使用的Jackson来实现返回json的,那么我们就使用Jackson的@JsonSerialize注解来序列化Date类型。

修改点:   

 1、User.java

public class User {

    @JsonDeserialize(using = DateJsonDeserialize.class)
    @JsonSerialize(using = DateJsonSerialize.class)
    private Date birthday;

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

  

同样的你也需要自定义一个日期的序列化的类。   

 2、DateJsonSerialize.java

public class DateJsonSerialize extends JsonSerializer {

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if(value != null){
            if(value.getClass().isAssignableFrom(Date.class)){
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String format = sdf.format((Date) value);
                gen.writeString(format);
            }
        }
    }

}

 

再次调用就能够达到自己想要的效果了。

这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值