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. SQL之 CAST 和 CONVERT

    原文来自于: http://bbs.csdn.net/topics/330251394 CAST 和 CONVERT将某种数据类型的表达式显式转换为另一种数据类型.CAST 和 CONVERT 提供相 ...

  2. Cron 表达式详解和案例

    1. cron表达式格式: {秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)} 2. cron表达式各占位符解释: {秒数} ==> 允许值范围: 0~59 ,不允许 ...

  3. 修复 Java 内存模型,第 2 部分——Brian Goetz

    转自Java并发大师Brain Goetz:http://www.ibm.com/developerworks/cn/java/j-jtp03304/ (中文地址) http://www.ibm.co ...

  4. 算法(三)粒子群算法PSO的介绍

    一.引言 在讲算法之前,先看两个例子: 例子一:背包问题,一个书包,一堆物品,每个物品都有自己的价值和体积,装满书包,使得装的物品价值最大. 例子二:投资问题,n个项目,第i个项目投资为ci 收益为p ...

  5. lucene入门

    一.lucene简介 Lucene是apache下的一个靠性能的.功能全面的用纯java开发的一个全文搜索引擎库.它几乎适合任何需要全文搜索应用程序,尤其是跨平台.lucene是开源的免费的工程.lu ...

  6. 数据结构--栈的应用(表达式求值 nyoj 35)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=35 题目: 表达式求值 时间限制:3000 ms | 内存限制:65535 KB描述 AC ...

  7. TCP/IP详解--TCP首部选项中时间戳选项

    一.简介 TCP时间戳选项会在TCP包头增加12个字节,以一种比重发超时更精确的方法来启用对RTT 的计算.   二.作用 ) TCP时间戳位于TCP选项中,kind=:lenth=:data由tim ...

  8. Storm 基础知识

    分布式的实时计算框架,storm对于实时计算的意义类似于hadoop对于批处理的意义. Storm的适用场景: 1.流数据处理:storm可以用来处理流式数据,处理之后将结果写到某个存入中去. 2.持 ...

  9. Reducejoin sample

    示例文件同sample join analysis 之前的示例是使用map端的join.这次使用reduce端的join. 根据源的类别写不同的mapper,处理不同的文件,输出的key都是stude ...

  10. selenium处理div生成弹框

    目前遇到的弹框有两种,一种是alert,一种是div,如果遇到div模拟的弹框,在用alert就不行了. 1. public static Alert getAlert(WebDriver dr) { ...