Spring参数验证顺序问题
来源:互联网 发布:局域网共享文件软件 编辑:程序博客网 时间:2024/06/16 09:20
问题
今天遇到一个小问题,在进行表单提交之后,直接进入了400错误页面,这个比较诡异,我所做的无非就是进行了简单的参数验证,提取BindingResult中的信息放到Model中方便前台显示,如下:
12345678910
"/user/publish",method = RequestMethod.POST)(value =String publish(@Valid TopicForm topicForm,Model model,BindingResult result){if(result.hasErrors()){model.addAttribute("errors",result.allErrors)return "/user/publish"}Set<Tag> tagSet = tagService.constructeTags(topicForm.tags)topicService.publish(topicForm.build(tagSet))return "redirect:/"}
解决过程
12345678910111213
class TopicForm {"标题不能为空")(message =6, max = 125, message = "标题最少6个字符")(min =String title15, max = 20, message = "内容必须在20-2W个字符哟")(min =String content //故意改成20,产生验证错误}
直接打断点,发现根本没进入这段代码,因此猜测是验证的时候报了异常,因此将@Length
的max
改成20,产生错误结果,然后进入org.hibernate.validator.internal.constraintvalidators.hv.LengthValidator
,在isValid
方法上右键Add to watches,打个断点(友情提示,本人用的IDEA-16),一步一步跟踪调试发现进入了下面这段关键的代码段:
1234567891011121314151617181920212223242526
public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler {public final Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {String name = ModelFactory.getNameForParameter(parameter);Object attribute = (mavContainer.containsAttribute(name) ?mavContainer.getModel().get(name) : createAttribute(name, parameter, binderFactory, webRequest));WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);if (binder.getTarget() != null) {bindRequestParameters(binder, webRequest);validateIfApplicable(binder, parameter);if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {throw new BindException(binder.getBindingResult());}}// Add resolved attribute and BindingResult at the end of the modelMap<String, Object> bindingResultModel = binder.getBindingResult().getModel();mavContainer.removeAttributes(bindingResultModel);mavContainer.addAllAttributes(bindingResultModel);return binder.convertIfNecessary(binder.getTarget(), parameter.getParameterType(), parameter);}}
就是在这个地方抛出了一个BindException
的异常,然后Spring进行了其他一些处理进去了400页面,不重要,我们看看这个判断条件,hasErrors()是用来判断是否有参数验证错误,这里很明显为true,下面还有个关键方法,我们进去一探究竟:
123456
protected boolean isBindExceptionRequired(WebDataBinder binder, MethodParameter methodParam) {int i = methodParam.getParameterIndex();Class<?>[] paramTypes = methodParam.getMethod().getParameterTypes();boolean hasBindingResult = (paramTypes.length > (i + 1) && Errors.class.isAssignableFrom(paramTypes[i + 1]));return !hasBindingResult;}
这里一看就明晰了,getParameterIndex()获取的就是@Valid
标注的方法参数索引,然会去判断紧跟其后的参数是否为Errors
的子类,这时候我想到上面那个publish方法,我将Model作为其后续参数,而BindingResult为最后一个,因此肯定会返回true,导致抛出BindException异常。
总结
- 出了问题不要立马就去Google,先自己尝试去解决,打个断点进入源码调试下,进而分析问题可能产生的原因
- 平常注意看文档,对用到的东西要了若指掌
阅读全文
0 0
- Spring参数验证顺序问题
- printf问题--参数顺序
- spring 参数验证注解文档
- Spring boot 方法参数验证
- 参数入栈顺序问题
- spring log4j配置顺序问题
- spring中方法级验证参数
- spring mvc4 hibernate validator 方法参数验证
- Spring验证小结和问题
- 编译参数顺序导致奇怪问题
- printf打印参数的顺序问题
- spring参数传递的问题
- Spring 接收参数乱码问题
- spring注解bean加载顺序问题(一)
- SQL的保留字问题和参数定义顺序问题
- 用spring发邮件验证失败问题
- 用spring发邮件验证失败问题
- 关于UrlHttpConnection.setRequestProperty()的调用顺序问题的验证
- java EE开发之Struts2第四章:国际化和文件上传下载
- CentOS 7.2 下安装部署 LAMP 详解
- 做项目的研发模式,即怎么研发一个系统,一步一步怎么做:UP、RUP、迭代式、瀑布式、快速原型、敏捷开发,区别
- 对mui下拉刷新,上拉刷新样式自定义
- Kafka 0.11.0.2 安装备忘录
- Spring参数验证顺序问题
- jquery easyui实现树形(Tree)菜单点击,在content页生成Tab功能
- 1.Java核心API--集合
- tomcat内存设置
- 头注释格式
- Tensorflow实例:实现VGG
- stream_context_create()发送POST/GET请求
- scikit-learn 中文文档-朴素贝叶斯-监督学习|ApacheCN
- 循环嵌套判断字符串是否相等