前后台时间类型传输

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. form表单提交
    1.1 后台RequestParam接收
    (方法一:前台传入字符串,后台用时间类型接收,方法二:前台传入时间格式,后台用时间类型接收)
    1.2 后台用实体类接收
    (方法一:前台传入字符串,后台用时间类型接收,方法二:前台传入时间格式,后台用时间类型接收)
  2. JSON格式提交

1.3.1 form表单提交

1.3.1.1 后台RequestParam接收
方法一

可以在参数前加@DateTimeFormat(pattern=“yyyyMMdd”)注解。
填写2018-09-09测试,前台传入字符串,后台用时间类型接收
在这里插入图片描述

代码:

$("#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

方法二

前台传递时间格式的数据。
填写Sat Jun 16 10:30:36 CST 2018测试,前台传入时间格式,后台用时间类型接收

在这里插入图片描述

$("#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,前台传过来的时间为时间******
Sun Jun 17 00:30:36 CST 2018
Sat Jun 16 10:30:36 CST 2018

1.3.2 后台用实体类接收

1.3.3 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;
    }

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

3总结:

1. form表单提交
	后台RequestParam接收;后台用实体类接收一样,
	前台传入字符串,后台用时间类型接收,后台正确拿到数据必须交@DataTimeFormat
	前台传入时间格式,后台用时间类型接收,后台不用做处理,自动转换
2. JSON格式提交
   需要反序列化
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值