Spring驗證的錯誤返回------BindingResult

Spring驗證的錯誤返回------BindingResult 

 參考資料:http://www.mkyong.com/spring-mvc/spring-mvc-form-errors-tag-example/css

<%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/>");
}


}

}
%>html

 

 

 

 

 

 

最近作的一個項目使用了 Spring MVC3, 其中驗證也是使用Spring的 validate 框架, 但不是所有。java

咱們 只是使用了org.springframework.validation.Errors, org.springframework.validation.BindingResult 來將驗證錯誤信息返回到JSP頁面。由於Spring提供了<form:errors>標籤來顯示BindingResult對象裏的錯誤信 息, 而且這個驗證框架還支持國際化, errorCode對應的語言文字放到工程的message資源文件就行了。spring

下面是一個簡單的註冊帳戶的例子:包括三個文件:JSP, AccountValidator和AccountValidator。數據庫

 

1. 首先是JSP頁面:addAccount,jsp的表單api

<form:form modelAttribute="accountVo" action="${actionUrl}" method="post"> 
            <form:hidden path="id"  readonly=「readonly」/>瀏覽器

           <form:input path="email" size="30" onblur="checkEmail();"/> //path的值必須和accountVo這個對象的屬性一致spring-mvc

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

                   //這裏省略了表單的其餘元素, 直接來提交按鈕   mvc

           <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> //若是是英文瀏覽器, 「郵箱格式不正確!」就會使英文版本的。

好的, 就先寫到這裏了。

相關文章
相關標籤/搜索