前后台时间类型传输

1. 请求处理

1.1 场景:

在开发javaweb项目是,往往需要传递时间,当前台传递的时字符串(如“2018-09-09”),后台却用时间类型接受会报错。

2018 六月 15 16:53:01.557 WARN  o.s.w.s.m.s.DefaultHandlerExceptionResolver - Failed to bind request element: org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.util.Date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.web.bind.annotation.RequestParam java.util.Date] for value '2018-09-09'; nested exception is java.lang.IllegalArgumentException 

大概意思就是String到Date类型不支持。

1.2. 分析:

在用SpringMVC 开发时,主要有两种接收方式,一种是普通的form表单提交,另一种是JSON格式提交。
1. form表单提交:不管是GET还是POST提交,都可以从request.getParameter中到参数,并且默认返回类型为String。@RequestParam就是拿取该数据并做类型转换映射到响应的参数上,因为Spring没有实现String到Date的转换导致报错。
2. JSON格式提交:这个时候用request.getParameter就得不到数据,因为数据被存到请求体中,可以用流的方式得到。Spring中可以用@RequestBody注解映射得到。
注:你可能疑惑,form表单提交的POST请求也不是放到请求体中,不也应该用流的形式取么?

1.3. 方案:

1.3.1 form表单提交

方法一

可以在参数前加@DateTimeFormat(pattern=”yyyyMMdd”)注解。

代码:

$("#saveBtn").click(function(e){
    $.ajax({
        url: '<%=basePath%>/date/date',
        type: 'post',
        dataType: 'json',
        data: {'date':$("#date").val()},
        success: function(data) {
            console.info(data);
        }
    });         
});

<form action="">
        时间:<input type = "text" name="date" id = "date"><br/>
        <input type="button" id = "saveBtn" value="提交">
</form>
/**
     * 测试有@DateTimeFormat
     * 前台传过来的时间为字符串
     */
    @RequestMapping("/date")
    public Date date(
            @DateTimeFormat(pattern="yyyy-MM-dd") Date date,
            HttpServletRequest request) throws IOException {
        System.out.println("\n");
        System.out.println("******测试有@DateTimeFormat,前台传过来的时间为字符串******");
        System.out.println(date);
        System.out.println(request.getParameter("date"));
        return date;
    }

输出:
******测试有@DateTimeFormat,前台传过来的时间为字符串******
Sun Sep 09 00:00:00 CST 2018
2018-09-09

方法二

前台传递时间格式的数据。

$("#saveBtn21").click(function(e){
    $.ajax({
        url: '<%=basePath%>/date/date21',
        type: 'post',
        dataType: 'json',
        data: {'date':new Date()},
        success: function(data) {
            console.info(data);
        }
    });
});
<form action="">
        时间21:<input type = "text" name="date" id = "date21"><br/>
        <input type="button" id = "saveBtn21" value="提交">
  </form>
/**
     * 测试没有@DateTimeFormat
     * 前台传过来的时间为时间
     */
    @RequestMapping("/date21")
    public Date date21(
            Date date,
            HttpServletRequest request) throws IOException {
        System.out.println("\n");
        System.out.println("******测试没有@DateTimeFormat,前台传过来的时间为时间******");
        System.out.println(date);
        System.out.println(request.getParameter("date"));
        return date;
    }

输出:
******测试没有@DateTimeFormat,前台传过来的时间为时间******
Sat Jun 16 10:30:36 CST 2018
Sat Jun 16 2018 10:30:36 GMT+0800 (中国标准时间)

1.3.2 JSON格式提交

方法一:

在JSON格式提交如果用@DateTimeFormat(pattern=”yyyyMMdd”)是不起作用的,
此时可以用json的@JsonDeserialize注解,将值反序列化。

经测试:JSON格式提交,如果前台传过来的时yyyy-MM-dd格式的字符串,后台不做处理可以正常接收。

代码:

public class DateEntity {
    @JsonDeserialize(using = DateJsonDeserialize.class)
    private Date date;
    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date = date;
    }
    @Override
    public String toString() {
        return "DateEntity [date=" + date + "]";
    }
}
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;
    }
}
$("#saveBtn3").click(function(e){
    var param = {'date':$("#date3").val()};
    $.ajax({
        url: '<%=basePath%>/date/date3',
        type: 'post',
        dataType: 'json',
        contentType: 'application/json',
        data: JSON.stringify(param),
        success: function(data) {
            console.info(data);
        }
    });
});
<form action="">
        时间3:<input type = "text" name="date" id = "date3"><br/>
        <input type="button" id = "saveBtn3" value="提交">
</form>
 /**
     * 测试有@RequestBody
     * 前台传过来的时间为字符串
     */
    @RequestMapping("/date3")
    public DateEntity date3(
            @RequestBody DateEntity dateEntity,
            HttpServletRequest request) throws IOException {
        System.out.println("\n");
        System.out.println("******测试有@RequestBody,前台传过来的时间为字符串******");
        System.out.println(dateEntity);
        return dateEntity;
    }

输出:
******测试有@RequestBody,前台传过来的时间为字符串******
DateEntity [date=Sun Sep 09 08:00:00 CST 2018]
null

方法二:
前台传递时间格式的数据。

2. 响应处理

2.1 场景

在Spring开发中,发现如果响应中含有时间格式的数据,会自动转换成long类型传递。

2.2 方案

以JSON提交为例,可以增加 @JsonSerialize注解,对响应参数的时间类型数据序列化

代码:

public class DateEntity {

    @JsonDeserialize(using = DateJsonDeserialize.class)// 请求时:将字符串类型的格式转换成时间类型
    @JsonSerialize(using=DateJsonSerialize.class)// 响应结果:将时间类型的格式化
    private Date date;
    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date = date;
    }
    @Override
    public String toString() {
        return "DateEntity [date=" + date + "]";
    }
}
public class DateJsonSerialize extends JsonSerializer<Object> {

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

}
$("#saveBtn3").click(function(e){
    var param = {'date':$("#date3").val()};
    $.ajax({
        url: '<%=basePath%>/date/date3',
        type: 'post',
        dataType: 'json',
        contentType: 'application/json',
        data: JSON.stringify(param),
        success: function(data) {
            console.info(data);
        }
    });
});
<form action="">
        时间3:<input type = "text" name="date" id = "date3"><br/>
        <input type="button" id = "saveBtn3" value="提交">
  </form>
 /**
     * 测试有@RequestBody
     * 前台传过来的时间为字符串
     */
    @RequestMapping("/date3")
    public DateEntity date3(
            @RequestBody DateEntity dateEntity,
            HttpServletRequest request) throws IOException {
        System.out.println("\n");
        System.out.println("******测试有@RequestBody,前台传过来的时间为字符串******");
        System.out.println(dateEntity);
        System.out.println(request.getParameter("date"));
        return dateEntity;
    }

响应结果:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/u010811939/article/details/80707336