2015-04-18 60 views
4

嗨StackOverflow的春JSR-303 Bean驗證不工作,空bindingresult

我試圖beanvalidation添加到我的小web應用。直到現在它不起作用,因爲我的bindingresult保持空白。我也做了以下內容:

  • 添加所有的依賴關係(同學,Javax.el,JBoss的記錄,驗證-API)
  • 添加註釋
  • 與@Valid和BindingResult
  • 更新更新控制器我jsp頁面
  • Maked確保我在調度員servlet.xml中有<mvc:annotation-driven/>

我已經看過類似的問題^ h在stackoverflow上,但我一直無法找到我需要的答案。我正在使用Apache Tomcat。

我的控制器:

@RequestMapping(value = {"/cardForm"}, method = POST, params = {"dispatcher=createCard"}) 
    public String addCard(@Valid @ModelAttribute("card") Card card, BindingResult result) { 
     System.out.println(result.getErrorCount()); 
     if (result.hasErrors()) { 
      return "cardForm"; 
     } else { 
      try { 
       service.addCard(card); 
      } catch (MapperException ex) { 
       Logger.getLogger(CardController.class.getName()).log(Level.SEVERE, null, ex); 
      } 
      return "redirect:/"; 
     } 
    } 

我的班級進行驗證:

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package domain; 
import javax.persistence.Entity; 
import javax.validation.constraints.Min; 
import javax.validation.constraints.NotNull; 
/** 
* 
* @author niels 
*/ 
@Entity 
public class Card extends DomainObjectBase { 
    @NotNull(message="{error.name.null}") 
    private String name; 
    @NotNull(message="{error.type.null}") 
    private String type; 
    @NotNull(message="{error.text.null}") 
    private String text; 
    @NotNull(message="{error.playerClass.null}") 
    private String playerClass; 
    @Min(value=0,message="{error.attack.min}") 
    private int attack; 
    @Min(value=0,message="{error.health.min}") 
    private int health; 
    @Min(value=0,message="{error.cost.min}") 
    private int cost; 

    public Card() {} 

    public Card(String name, String type, String text, String playerClass, int attack, int health, int cost) throws DomainException { 
     setName(name); 
     setType(type); 
     setText(text); 
     setPlayerClass(playerClass); 
     setAttack(attack); 
     setHealth(health); 
     setCost(cost); 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getType() { 
     return type; 
    } 

    public void setType(String type) { 
     this.type = type; 
    } 

    public String getText() { 
     return text; 
    } 

    public void setText(String text) { 
     this.text = text; 
    } 

    public String getPlayerClass() { 
     return playerClass; 
    } 

    public void setPlayerClass(String playerClass) { 
     this.playerClass = playerClass; 
    } 

    public int getAttack() { 
     return attack; 
    } 

    public void setAttack(int attack) throws DomainException { 
     this.attack = attack; 
    } 

    public int getHealth() { 
     return health; 
    } 

    public void setHealth(int health) throws DomainException { 
     this.health = health; 
    } 

    public int getCost() { 
     return cost; 
    } 

    public void setCost(int cost) throws DomainException { 
     this.cost = cost; 
    } 

} 

我的調度員servlet.xml中:

<?xml version='1.0' encoding='UTF-8' ?> 
<!-- was: <?xml version="1.0" encoding="UTF-8"?> --> 
<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:p="http://www.springframework.org/schema/p" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:mvc="http://www.springframework.org/schema/mvc" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
     http://www.springframework.org/schema/context 
     http://www.springframework.org/schema/context/spring-context-4.0.xsd 
     http://www.springframework.org/schema/mvc 
     http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> 


    <mvc:annotation-driven/> 
    <context:component-scan base-package="controller"/> 
    <!-- 
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 
     <property name="basename" value="classpath:messages"></property> 
    </bean> 
    --> 
    <mvc:interceptors>  
     <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang" /> 
    </mvc:interceptors> 

    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"> 
     <property name="defaultLocale" value="en_GB"/> 
    </bean> 

    <bean id="viewResolver" 
      class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
      p:prefix="/WEB-INF/jsp/" 
      p:suffix=".jsp" /> 

    <bean class="org.springframework.context.support.ResourceBundleMessageSource" 
     id="messageSource"> 
     <property name="basename" value="messages" /> 
    </bean> 


</beans> 

我cardForm.jsp:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> 
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> 
<!DOCTYPE html> 
<html lang="en"> 

    <head> 

     <title> 
      Hearthstone | 
      <spring:message code="title.addCard"> 
      </spring:message> 
     </title> 
     <jsp:include page="title.jsp" /> 


    </head> 

    <body> 

     <div id="wrapper"> 
      <jsp:include page="menu.jsp" /> 
      <!-- Page Content --> 
      <div id="page-content-wrapper"> 
       <div class="container-fluid"> 
        <div class="row"> 
         <div class="col-lg-6 col-lg-offset-3"> 


          <form:form action="${pageContext.request.contextPath}/cardForm.htm" method="post" modelAttribute="card"> 
           <form:errors path="*" cssClass="errorblock" element="div" /> 
           <c:choose> 
            <c:when test="${card.id > 0}"> 
             <h3><spring:message code="card.update"> 
             </spring:message></h3> 
             <form:hidden path="id" value="${card.id}"/> 
             <input type="hidden" name="dispatcher" value="updateCard"/> 
            </c:when> 
            <c:otherwise> 
             <h3><spring:message code="card.add"> 
             </spring:message></h3> 
             <input type="hidden" name="dispatcher" value="createCard"/> 
            </c:otherwise> 
           </c:choose> 


           <div class="form-group"> 
            <form:label path="name"><spring:message code="card.name"> 
             </spring:message>: </form:label> 
            <form:input path="name" class="form-control"></form:input> 
            </div> 
            <div class="form-group"> 
            <form:label path="type">Type: </form:label> 

            <form:select class="form-control" path="type"> 
             <form:option value="Minion">Minion</form:option> 
             <form:option value="Spell">Spell</form:option> 
             <form:option value="Weapon">Weapon</form:option> 
            </form:select> 
           </div> 
           <div class="form-group"> 
            <form:label path="text"><spring:message code="card.text"> 
             </spring:message>: </form:label> 
            <form:input path="text" class="form-control"></form:input> 
            </div> 
            <div class="form-group"> 
            <form:label path="playerClass"><spring:message code="card.playerClass"> 
             </spring:message>: </form:label> 
            <form:select class="form-control" path="playerClass"> 
             <form:option value="All classes">All classes</form:option> 
             <form:option value="Priest">Priest</form:option> 
             <form:option value="Shaman">Shaman</form:option> 
             <form:option value="Mage">Mage</form:option> 
             <form:option value="Warrior">Warrior</form:option> 
             <form:option value="Warlock">Warlock</form:option> 
             <form:option value="Paladin">Paladin</form:option> 
             <form:option value="Rogue">Rogue</form:option> 
             <form:option value="Druid">Druid</form:option> 
             <form:option value="Hunter">Hunter</form:option> 
            </form:select> 
           </div> 

           <div class="form-group"> 
            <form:label path="attack"><spring:message code="card.attack"> 
             </spring:message>: </form:label> 
            <form:input path="attack" class="form-control"></form:input> 
            </div> 
            <div class="form-group"> 
            <form:label path="health"><spring:message code="card.health"> 
             </spring:message>: </form:label> 
            <form:input path="health" class="form-control"></form:input> 
            </div> 
            <div class="form-group"> 
            <form:label path="cost"><spring:message code="card.cost"> 
             </spring:message>: </form:label> 
            <form:input path="cost" class="form-control"></form:input> 
            </div> 
            <div class="form-group"><form:button type="submit" class="btn btn-primary"><spring:message code="form.send"> 
             </spring:message></form:button></div> 
          </form:form> 
         </div> 

        </div> 
       </div> 

      </div> 
      <!-- /#page-content-wrapper --> 

     </div> 
     <!-- /#wrapper --> 

     <!-- Bootstrap Core JavaScript --> 
     <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> 

     <!-- Menu Toggle Script --> 
     <script> 
      $("#menu-toggle").click(function (e) { 
       e.preventDefault(); 
       $("#wrapper").toggleClass("toggled"); 
      }); 
     </script> 

    </body> 

</html> 
+0

你可以在Github上發佈你的代碼嗎? –

+0

當然!我在Bitbucket的版本控制下:https://bitbucket.org/encapsulator/hs/src –

+0

很酷,今天晚些時候我會研究它:) –

回答

4

好吧,我明白了想通了,你和我必須說,一切的工作,但使用的是錯誤的javax.validation註解:)

您使用@ NotNull,但事實是controller.CardController#addCard(domain.Card,org.springframework.validation.BindingResult)接收到的Card實例中的字段不會爲空,它們將設置爲空字符串 - 這就是爲什麼您不查看BindingResult中的任何驗證錯誤。

只需添加(org.hibernate.validator.constraints。)@NotEmpty註釋而不是當前的@NotNull註釋,您將看到在BindingResult中報告的驗證錯誤。

+0

就是這樣!你先生,是英雄:D –

+0

爲此搜索了整整一天,哇,謝謝! –

+0

不客氣。只需整理一下你的項目。那裏現在有很多混亂;) –