校验器
@InitBinder亲测有效,网上很多资料都说了一半,或者没有说明白,
我先简单的说下这个InitBinder是用来干嘛的,为什么要使用他,以及他出现的场景;
通常来说前后台在做交互的时候,有一个form转换的过程就是把表单数据转换成我们的DTO,专门用来接收前台数据;
这个时候就会有很多很东西值得我们去思考,也是通过自己摸索才发现出来的;
直接上图,postMan;注意下面截图的地方,如果跟前台的交互是通过
application/x-www-form-urlencoded,表单进行交互的,这个时候SpringMVC是不能帮你进行从string转换成Date的,更别说你的特殊形式的date,比如yyyy-MM-dd HH24-mm-ss等
这个时候直接转就会出错!!如果没有InitBinder注解进行转换的话;
脱离代码谈技术就是耍流氓!!!直接上代码
这个controller中我写了两个方法,用来做校验
package com.cloudwalk.shark.controller; import com.cloudwalk.shark.common.utils.ResponseData; import com.cloudwalk.shark.dto.validate.AdvertQueryForm; import com.cloudwalk.shark.editor.SharkDateEditor; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.*; import java.text.SimpleDateFormat; import java.util.Date; @Controller @RequestMapping(value = "/validate", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE}) public class SharkValidationController {
@InitBinder public void initBinder(WebDataBinder binder) { binder.setFieldDefaultPrefix("advert."); binder.registerCustomEditor(Date.class,"startDate",new SharkDateEditor()); } @PostMapping("/bean") @ResponseBody public ResponseData checkBeanIsValid(@Validated @RequestBody AdvertQueryForm advertQueryForm){ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMM-dd"); System.out.println(simpleDateFormat.format(advertQueryForm.getStartDate())); return new ResponseData(true,"2","3",advertQueryForm); } @PostMapping("/beanForm") @ResponseBody public ResponseData checkBeanIsValidFormUrlEncoded(AdvertQueryForm advertQueryForm){ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMM-dd"); System.out.println(simpleDateFormat.format(advertQueryForm.getStartDate())); return new ResponseData(true,"2","3",advertQueryForm); } }
我们的startDate是Date类型的,希望SpringMVC直接帮我们从String转换成Date,
而不是我们自己在进行转换
package com.cloudwalk.shark.dto.validate; import java.util.Date; public class AdvertQueryForm { private String merchantName; private String merchantCode; private String clientCode; private String id; private Date startDate; public String getMerchantName() { return merchantName; } public void setMerchantName(String merchantName) { this.merchantName = merchantName; } public String getMerchantCode() { return merchantCode; } public void setMerchantCode(String merchantCode) { this.merchantCode = merchantCode; } public String getClientCode() { return clientCode; } public void setClientCode(String clientCode) { this.clientCode = clientCode; } public String getId() { return id; } public void setId(String id) { this.id = id; } public Date getStartDate() { return startDate; } public void setStartDate(Date startDate) { this.startDate = startDate; } }
同时initBinder还可以帮我们简化类型转换,比如我们的参数里面包含advert这种父名(前台代码在写的时候很容易有这种层次)
我们也想通过SpringMvc自动帮我们进行参数接收
binder.setFieldDefaultPrefix("advert.");
这行代码就能省去我们很多事情;直接上图
![](https://img2018.cnblogs.com/blog/1387024/201905/1387024-20190527164704645-558444400.png)
通过这种方式我们也能获取前台的参数;
而通过[{"key":"Content-Type","name":"Content-Type","value":"application/json","description":"","type":"text"}]
![](https://img2018.cnblogs.com/blog/1387024/201905/1387024-20190527164903679-532810459.png)
这种方式你的initBinder是不会生效的,这个在Form里面你可以写各种各样的注解去验证,jsonField等,不需要通过InitBinder去实现;
而且这种方式SpringMVC 就直接能帮你把关键的key转换成相应的Date!!
给大家看下我们自定义的Editor
package com.cloudwalk.shark.editor; import java.beans.PropertyEditorSupport; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class SharkDateEditor extends PropertyEditorSupport { @Override public String getAsText() { //获取属性值 Date date = (Date) getValue(); DateFormat dateFormat = new SimpleDateFormat("yyyyMM--dd"); String str = dateFormat.format(date); String mydate = str.substring(0, 4) + str.substring(4, 6) + "--" + str.substring(8, 10); System.out.println(mydate); return mydate; } @Override public void setAsText(String text) throws IllegalArgumentException { DateFormat dateFormat = new SimpleDateFormat("yyyyMM--dd"); try { System.out.println(dateFormat.parse(text)); //设置属性值 setValue(dateFormat.parse(text)); } catch (ParseException e) { System.out.println("ParseException...................."); } } }
比如我们可以自定义解析前台传来的特殊格式的日期!
没有什么比每天有成长进步更高兴的事情