爆破专栏丨SpringBoot2

接下来我会结合CustomDateEditor与InitBinder,给大家讲解如何对前端传递过来的日期类型参数进行格式化校验。我们先来看看CustomDateEditor类的结构关系,如下图所示:

图片

4. 示例代码

这里我先放一段校验前端日期类型参数格式的示例代码,后面我们会利用这段代码实现对前端传入的日期参数校验的目的。

@InitBinder
public void InitBinder(WebDataBinder binder) {
    //前端传入的时间格式必须是"yyyy-MM-dd"效果!
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    CustomDateEditor dateEditor = new CustomDateEditor(df, true);
    binder.registerCustomEditor(Date.class, dateEditor);
}

二. @InitBinder详解

在开始今天的内容之前,我先给大家介绍一个@InitBinder注解。

1. @InitBinder注解简介

@InitBinder注解可以作用在@Controller的方法上,表示为当前控制器注册一个属性编辑器,对WebDataBinder进行初始化,且只对当前的Controller有效。

2. @InitBinder执行时机

@InitBinder注解被解析的时机,是在其所位于的方法被请求执行之前。同时@InitBinder标注的方法是可以多次执行的,也就是说来一次请求就会执行一次@InitBinder解析。

3. @InitBinder执行原理

当某个Controller上的第一次请求,由SpringMVC前端控制器匹配到该Controller之后,根据Controller的 class类型来查找所有标注了@InitBinder注解的方法,并且存入Request Mapping Handler Adapter里的 initBinderCache 缓存中。等下一次请求执行对应业务方法之前,会先走initBinderCache缓存,而不用再去解析@InitBinder。

三. @InitBinder实现过程

接下来我们编写一个案例,实现对前端传递过来的日期参数进行格式化校验。

首先我们来创建一个Web程序,创建过程请参考之前的案例,此处略!

1. 创建Controller测试接口

在创建的Web项目中,我创建一个Controller接口,接口方法中可以接受Date类型的参数。

package com.yyg.boot.web;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.WebBindingInitializer;
import org.springframework.web.context.request.WebRequest;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description Description
 * @Author 一一哥Sun
 * @Date Created in 2020/3/23
 */
@Slf4j
@RestController
public class BindController {

    @GetMapping(value = "/bind")
    public Map<String, Object> getFormatData(Date date) throws ParseException {
        log.warn("date={}", date);
        Map<String, Object> map = new HashMap<>();
        map.put("name", "一一哥");
        map.put("age", 30);
        map.put("date", date);
        return map;
    }

}

项目入口类的创建这里我也直接略过了,大家自行创建即可。

2. 启动程序进行测试

启动项目后,此时我们可以在Postman中输入如下地址进行测试:http://localhost:8080/bind?date=2020-09-09

Postman中的效果如下所示:

图片

经过测试,发现此时产生400状态码,我们知道产生400状态码的原因是前后端参数不一致,具体就是无法将前端传递过来的String类型的时间字符串转换为Date类型!因为前端是没有Date类型的,前端传递的日期参数只能被理解为String类型,默认情况下是不能把这个String类型的日期数据直接转换为Date类型的。

图片

那怎么解决这个问题呢?

3. 添加@InitBinder代码

接下来我们在上面创建的Controller里面,添加一段新的代码,如下:

/**
     * @InitBinder标注的方法,只针对当前Controller有效!
     * 如果没有该方法,则会产生400状态码!
     * MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.util.Date!
     */
    @InitBinder
    public void InitBinder(WebDataBinder binder) {
        //前端传入的时间格式必须是"yyyy-MM-dd"效果!
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        CustomDateEditor dateEditor = new CustomDateEditor(df, true);
        binder.registerCustomEditor(Date.class, dateEditor);
    }

此时完整的Controller类如下图所示:

图片

4. 重启项目进行测试

添加完代码之后,我们把项目重启,然后我们在Postman中重新输入如下地址:http://localhost:8080/bind?date=2020-09-09

Postman的测试效果如下:

图片

可以发现此时前端传递的时间字符串被成功的传递到后端,并且被成功的转换成了Date类型!以上就是@InitBinder的原理及用法!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值