【修真院小课堂】 SpringMVC下的参数校验
大家好,我是IT修真院北京分院第32期学员,一枚正直善良的java程序员。
今天给大家分享一下,修真院官网java任务五中可能会使用到的知识点:
SpringMVC下的参数校验
一、背景介绍
1.基于前后端分离的思想,后端的参数校验是必不可少的:
(1)防止有人绕过前端直接对后端接口注入数据
(2)测试的时候有效发现前端错误并反馈
2.几种检验方式:
(1)直接将拿到的参数在controller层里面用if判断
优点:在接口较少的情况下相比其他方法这样做还算省事儿
缺点:大量代码嵌入到controller,违背了代码的复用性原则
改进方法:封装if判断,针对不同的参数在controller里面调用不同的封装类
(2)实现spring提供的Validator接口
优点:不使用配置文件,不使用注解,代码耦合性低
缺点:耦合性降低自然在实现的接口类中代码量就增加了,而且aop做起来挺难的
(3)使用基于JSR303的注解方式并使用spring生成validator实例
优点:不用自己实现接口,aop的使用使得大量验证变得方便
缺点:至少我使用的时候@valid注解是不支持分组、次序、级联验证的
改进方法:spring提供了我们一个@validated接口,使用该注解可以完成上述特殊验证
上面三种方法只是我接触参数验证的冰山一角,还有很多验证方法我还没学会,但是原理都是基于javax validation,hibernate validate都是使用的javax validation而没有暴露自己的接口,减少了代码的侵入性,今天就结合自己写的代码讲一下后两种方法。
二、知识剖析
1.关于JSR303、349和380
(1)注解类型
可以注解在javabean的field和properties上,也可以注解在map、list上,注解很灵活,甚至可以直接注解在controller的接口上,大部分情况下正则表达式可以满足我们的需要。
(2)错误信息的提取
如果是原生写法信息可以从constraintViolations中提取,其是一个set集合,通过迭代器调用getMessage方法即可拿到
2.关于validator接口
(1)需要实现的两种方法
我们在实现接口的同时要实现它的两个方法,分别声明了要校验的类和校验标准。
(2)在控制器中的注册
使用WebDataBinder绑定我们的接口实现类,要校验的参数后面要紧跟bindingresult。
(3)错误信息的提取
bindingResult.getAllErrors可以获取需要的错误信息然后进行处理,也可以使用form:form的error标签展示我们返回的错误
3.关于spring整合
(1)国际化配置和错误信息文件
需要注入一个工厂产生validator实例,通过EL表达式提取配置文件中的错误信息.
(2)分组和次序校验需要实现的接口
只声明一个接口即可,不需要写其他任何东西
三、编码实战
四、常见问题
(1)判断用户输入的基本类型是否合法
eg:我们得接受int类型的接口传过来一个非int类型的数据
处理办法:全局异常捕获
问题所在:我自己写的时候本来想写正则但是不支持基本类型,只能给string这种类型
(2)遇到json数据如何处理
eg:前端发过来一个复杂的json数据但是其中数据是和表单对应的
处理办法:这个时候不应该再对controller进行aop切面处理,选择拦截器或许是个合适的选择
问题所在:拦截器的代码我写了一下,但是没有合适的json对象做测试,核心思想还是拿到数据之后遍历放入map做检验
(3)发过来的数据没办法直接转换成model怎么办
eg:登陆的时候发送的用户名和验证码是和user这个model对应,但是没有和验证码对应的字段
处理办法:不对此接口做aop处理,我目前是又加了个if判断,挺多余的
问题所在:处理了也是一直报错,一开始没有认识到检验实际上必须对应model模型,也就是我们数据库中的数据
(4)做这么多参数检验是否会影响我们接口处理速度
if语句没试过,但是aop对速度是没什么大的影响
五、参考文献
https://blog.csdn.net/csyuyaoxiadn/article/details/56016359
https://blog.csdn.net/u012881904/article/details/77197015
http://beanvalidation.org/2.0/spec/2.0.0.cr2/#_evaluation_license
六、更多讨论
鸣谢
本次小课堂更多是结合自己的代码进行讲解,肯定有很多错误和局限性
感谢观看,如有出错,恳请指正