Spring验证的错误返回------BindingResult

参考资料:http://www.mkyong.com/spring-mvc/spring-mvc-form-errors-tag-example/

<%Enumeration<String> enums=request.getAttributeNames();
while(enums.hasMoreElements()){

String key=enums.nextElement();
if(key.equals("org.springframework.validation.BindingResult.改为自己spring表单名")){
BeanPropertyBindingResult valuess=(BeanPropertyBindingResult)request.getAttribute(key);

out.print("=========######===========<br/>");
for(FieldError or:valuess.getFieldErrors()){

out.print(or.getCode()+"<br/>");
out.print("------------------------<br/>");
//out.print(or.getDefaultMessage()+"<br/>");
for(String codes:or.getCodes()){
out.print(codes+"<br/>");
}

// out.print(or.getArguments()+"<br/>");
out.print(or.getField()+"<br/>");
out.print(or.getRejectedValue()+"<br/>");

out.print("====================<br/>");
}

out.print("====================<br/>");
}

}

}
%>

最近做的一个项目使用了 Spring MVC3, 其中验证也是使用Spring的 validate 框架, 但不是全部。

我们 只是使用了org.springframework.validation.Errors, org.springframework.validation.BindingResult 来将验证错误信息返回到JSP页面。因为Spring提供了<form:errors>标签来显示BindingResult对象里的错误信 息, 并且这个验证框架还支持国际化, errorCode对应的语言文字放到工程的message资源文件就好了。

下面是一个简单的注册账户的例子:包括三个文件:JSP, AccountValidator和AccountValidator。

1. 首先是JSP页面:addAccount,jsp的表单

<form:form modelAttribute="accountVo" action="${actionUrl}" method="post"> 
            <form:hidden path="id"  readonly=“readonly”/>

<form:input path="email" size="30" onblur="checkEmail();"/> //path的值必须和accountVo这个对象的属性一致

<form:errors path="email" cssClass="errorMsg"></form:errors>

//这里省略了表单的其他元素, 直接来提交按钮

<input type=" button"  id="saveAccount"  value='<fmt:message key="button.next" />' onclick="submitAccount ('accountVo')"/>

//这里完全可以使用type=“submit”, 这里使用button可以截获提交事件, 并在提交之前先做JS层面的验证

</form:form>

Note: 使用上面这些标签, 必须引入Spring 的 form标签库:<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

大家还看到我们使用了JSTL的fmt标签库(国际化), 这个也要引入<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>, 其实我们也完全可以用<form message>标签来做国际化的。这里我还想说一个东西:readonly这个属性根本起不到只读的作用, 完全可以被修改,但是使用disable属性后,这个表单元素就无法放到accountVo这个对象并提交了, 纠结!

2. 这里是个不完整的验证类AccountValidator, 注意,我们没有实现Validator接口

public class AccountValidator { 
    public void validate(AccountVo accountVo, Errors errors) { 
        String email = accountVo.getEmail(); 
        if (!StringUtils.hasLength(email)) { 
             errors.rejectValue("email", "validate.email.empty", "邮箱不能为空");//这个函数有好几个重载的变体 
        } 
   } 
}

Note: Errors这个接口有好几个rejectValue()函数, 它们是可以支持国际化的。 比如, 上面这个例子表示, 错误的字段(filed)是“email”, errorCode是“validate.email.empty”, 与资源文件对应, 第三个是defaultMessage。很多国际化当中会带有参数, rejectValue其中的一个重载函数就是 rejectValueString field, String errorCode, Object[] errorArgs, String defaultMessage)。

3. 最后是AccountController

@Controller//基于注解, 声明这是一个controller 
@RequestMapping(value="/account") //表示总的路径 
@SessionAttributes("account") //表示account对象将会存入session当中, //默认情况下model.addAttribute(account)将会把account对象放入request当中, 并且属性名为“account” 
public class AccountFormController {

@RequestMapping(value = "/add", method = RequestMethod.POST) 
    public String addAccount( @ModelAttribute("accountVo") AccountVo accountVo
             BindingResult result, //这里面,BindResult result必须紧跟着前面的@ModelAttribute, 否则会出错

HttpServletResponse response, 
            HttpSession session, Model model) { 
        log.debug(accountVo.toString()); 
         
        if(isExist(accountVo)){ 
            log.debug("Opps, 这个email已经注册过了!"); 
             result.rejectValue("email", "misFormat", "这个email已经注册过了!"); 
            return "account/addAccount"; 
        }else{ 
            new AccountValidator().validate(accountVo, result); 
            if( result.hasErrors()){ 
                log.debug("表单数据有误, 重新填写"+accountVo); 
                model.addAttribute("accountVo",accountVo);//把accountVo对象返回到页面, 这样不至于表单被清空了 
                return "account/addAccount";//返回到注册页面,同时,这里会自动将验证错误信息返回到JSP页面, 怎么返回呢?看后面! 
            } 
            //这里会做很多数据库的操作, 省略 
       }

} //end of login()

}//end of controller

Note: 这里需要特别注意几个问题:1.函 数形参 BindResult result 必须紧跟着前面的@ModelAttribute, 否则会出异常; 2. @ModelAttribute("accountVo") AccountVo accountVo, 这个参数与JSP页面的<form:form modelAttribute="accountVo" action="${actionUrl}" method="post">对应

4. 进阶一下, 看看验证错误信息对象是怎么传递到页面的

这 一切看起来都很完美, 但是有时候出于设计的原因, 我们不得不使用redirect, 对, 就是重定向! 就是这个东西让我对Spring MVC有了一点不好的印象, 特别是结合了sitemesh之后。这个先打住, 咱们还是说验证错误怎么传给重定向之后的JSP页面吧。

其实也简单, 咱们可以先把错误对象放入session当中, 然后在另一个Controller里把它取出来, 然后再返回到相应的JSP页面就行了!

对!但是,这里要注意了, BindingResult这个对象是自动传入JSP的, 我们不知道应该把它放在request里面呢还是session里面, 或者其他的地方, 以及属性名叫什么。这个就是我昨天晚上纠结的问题, 最后看了一下Spring 的源代码, 终于稍微清楚了一点儿。下面直接上代码,然后解释。

if(session.getAttribute("BindingResult.accountVo") != null){ 
            //放到session和request里面, 不论attr name设置成什么都不行 
            //只有这样才能把bindingresult的错误信息传到JSP页面 
            String errorAttrName = " org.springframework.validation.BindingResult.accountenterpriseVo"; 
             model.addAttribute(errorAttrName, session.getAttribute("BindingResult.accountVo")); 
            session.removeAttribute("BindingResult.enterpriseVo");

}

首先, 验证错误对象 BindingResult 必须放入 org.springframework.ui. Model 当中返回给JSP页面。放到request和session当中都没用。

第二,这个属性名是 BindingResult.getClass().getName + “.” + targetName, 也就是上面那一长串, 其中targerName对应着JSP页面的表单的modelAttribute, 即<form:form modelAttribute="accountVo" action="${actionUrl}" method="post">中的accountVo。 对了, 顺便说一下, accountVo同时还是表单的id, 大家可以用firefox的firebug查看页面元素。<form:error>标签也会被翻译成

<span class="errorMsg" id="email.errors">邮箱格式不正确!</span> //如果是英文浏览器, “邮箱格式不正确!”就会使英文版本的。

好的, 就先写到这里了。

Spring验证的错误返回------BindingResult的更多相关文章

  1. Spring Boot API 统一返回格式封装

    今天给大家带来的是Spring Boot API 统一返回格式封装,我们在做项目的时候API 接口返回是需要统一格式的,只有这样前端的同学才可对接口返回的数据做统一处理,也可以使前后端分离 模式的开发 ...

  2. spring boot 解决后台返回 json 到前台中文乱码之后出现返回json数据报错 500:no convertter for return value of type

    问题描述 spring Boot 中文返回给浏览器乱码 解析成问号?? fastJson jackJson spring boot 新增配置解决后台返回 json 到前台中文乱码之后,出现返回json ...

  3. egg框架实现表单验证及获取验证的错误信息

    最近再看egg框架 是阿里今年开源的一款基于nodejs的mvc架构的web框架 感兴趣的同学可以看看 因为之前一直做php的关系 在tp,yii,laravel这些框架中对于前台发送的数据,模型里都 ...

  4. 自定义 serializers.ValidationError 的错误返回

    在使用DRF进行反序列过程中,总是需要校验字段,然后返回错误结果.可以使用默认的自定义校验项,也可以自定义校验项.而默认的自定义校验项总是差强人意. 版本 Django 2.2.3 Python 3. ...

  5. TCP connect的错误返回值

    如果是TCP套接字,调用connect函数将激发TCP三次握手过程,而且仅在连接建立成功或出错时返回,其中错误返回可能有下面几种情况: (1)若TCP客户没有收到SYN分节的响应,则返回ETIMEDO ...

  6. [原创]java WEB学习笔记71:Struts2 学习之路-- struts2常见的内建验证程序及注意点,短路验证,非字段验证,错误消息的重用

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  7. Spring MVC 3.0 返回JSON数据的方法

    Spring MVC 3.0 返回JSON数据的方法1. 直接 PrintWriter 输出2. 使用 JSP 视图3. 使用Spring内置的支持// Spring MVC 配置<bean c ...

  8. jQuery ajax请求错误返回status 0和错误error的问题

    上周发现一个jQuery ajax请求错误返回status 0和错误error的问题,responseText是"error",状态码是0而不是200: $.ajax({ type ...

  9. spring全局异常处理 自定义返回数据结构

    在写api接口中,正常返回和异常错误返回我们都希望很清楚的将这些信息清楚的返回给用户,出现异常情况下需要清楚的知道是参数异常还是未知异常,而不是返回一个不正确的数据结构. 所以此处只针对写api接口时 ...

随机推荐

  1. 多选按钮(CheckBox)

    今天我们介绍的是Checkbox多选框: 1.Activity //复选框,[基础控件]---状态切换控件CompoundButton及其子类CheckBox.RadioButton.ToggleBu ...

  2. WPF Caliburn.Micro ListView 批量删除,有其他方法的大家一起交流一下

    做这种批量删除的时候我的想法是获取每行的ID,然后更具ID删除,看过一些博客,大部分都是直接写在.CS文件里面,将ListView和CheckBox关联起来,最后用checkbox ck=sender ...

  3. iOS 视频选择压缩

    //原理,还是调用UIImagePickerController控制器,设置Type为视频 #import "ViewController.h" #import <AVFou ...

  4. Mac显示隐藏文件的终端命令

    显示:defaults write com.apple.finder AppleShowAllFiles -bool true隐藏:defaults write com.apple.finder Ap ...

  5. 小波说雨燕 第三季 构建 swift UI 之 UI组件集-视图集(二)ActionSheet视图 学习笔记

    action动作 sheet表 其实就是一种菜单 参数:1代理:谁去代理它2取消按钮标题3这个按钮标题会自动变成红色4添加设置其他按钮(不想加,设置为nil)   然后我们为这些按钮添加点击事件:   ...

  6. java网络---基本web概念

    首先需要搞清楚web中的3个关键概念. 一.HTTP,HTML,URL. HTML 全称是Hypertext Markup Language,是用来描述一个网页的语言.或者说,该语言是用来描述网页的“ ...

  7. Jmeter之Http Cookie Manager

    一.Http Cookie Manager的作用: 1.自动管理cookie:象浏览器一样的存储和发送Cookie,如果发送一个http请求他的响应中包含Cookie,那么Cookie Manager ...

  8. 读书笔记——数据库的ADO开发总结

    基本上是对 ADO+开发指南.pdf 的摘抄和总结,以及个人心得. 文章末尾有<ADO+开发指南.pdf>的资源下载,附带个人批注. --------------------------- ...

  9. Windows环境下JDK安装与环境变量配置详细的图文教程

    原文作者:souvc博文出处:http://www.cnblogs.com/liuhongfeng/p/4177568.html 本节内容:JDK安装与环境变量配置 以下是详细步骤 一.准备工具: 1 ...

  10. 两台SQL Server数据同步解决方案

    复制的概念 复制是将一组数据从一个数据源拷贝到多个数据源的技术,是将一份数据发布到多个存储站点上的有效方式.使用复制技术,用户可以将一份数据发布到多台服务器上,从而使不同的服务器用户都可以在权限的许可 ...