zoukankan      html  css  js  c++  java
  • Spring验证的错误返回------BindingResult

    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> //如果是英文浏览器, “邮箱格式不正确!”就会使英文版本的。

    好的, 就先写到这里了。

  • 相关阅读:
    Linux 用户和组管理
    Bash 基础特性
    Linux 中常用的基础命令二
    Linux 中常用的基础命令一
    Linux 获取帮助
    Linux 基础入门二
    Linux 基础入门一
    计算机基础
    python 操作元组 列表===python中三大宝刀(字典已经再上一遍 说过)
    mysql 创建数据存储过程的申明
  • 原文地址:https://www.cnblogs.com/developer-ios/p/5915727.html
Copyright © 2011-2022 走看看