Announcement Announcement Module
Collapse
No announcement yet.
Validator not working Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Validator not working

    I am having issues with getting a validator to work. I appreciate any help in identifying the issue.

    I am using an MVC + Web Flow configuration.

    Here is web.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
      <display-name>project123</display-name>
      <listener>
        <listener-class>
        	org.springframework.web.context.ContextLoaderListener
        </listener-class>
      </listener>
      <servlet>
        <servlet-name>mvcwebflowDispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>
                    /WEB-INF/config/*servlet.xml
          </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>mvcwebflowDispatcher</servlet-name>
        <url-pattern>*.htm</url-pattern>
      </servlet-mapping>
      <welcome-file-list>
        <welcome-file>/WEB-INF/jsp/redirect.jsp</welcome-file>
      </welcome-file-list>
      <servlet>
        <description></description>
        <display-name>TestServlet</display-name>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>com.website.project123.servlet.TestServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/TestServlet</url-pattern>
      </servlet-mapping>
    </web-app>
    Here is my spring configuration:
    Code:
    <?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:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:context="http://www.springframework.org/schema/context"
    	   xmlns:webflow="http://www.springframework.org/schema/webflow-config"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    	   http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.3.xsd">
    
    	<context:component-scan base-package="com.website" />
    	
    	<mvc:annotation-driven/>
    
    	<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    		<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    		<property name="prefix" value="/WEB-INF/jsp/"/>
    		<property name="suffix" value=".jsp"/>
    	</bean>
    	
    	<!--##############################################################################################################################-->
    	<!--##############################################################################################################################-->
    	<!--##############################################################################################################################-->
    	<!-- WEBFLOW CONFIGURATIONS -->
    
    	<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
    		<webflow:flow-execution-repository max-executions="5" max-execution-snapshots="30" />
    	</webflow:flow-executor>
    
    	<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices" base-path="/WEB-INF/pageFlows">
    		<webflow:flow-location-pattern value="/**/*-flow.xml"/>	
    	</webflow:flow-registry>
    
    	<webflow:flow-builder-services id="flowBuilderServices" />
    
    	<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
        	<property name="flowExecutor" ref="flowExecutor" />
    	</bean>
    	
    	<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
        	<property name="flowRegistry" ref="flowRegistry"/>
        	<property name="order" value="-1"/>
    	</bean>
    
    	<!--##############################################################################################################################-->
    	<!--##############################################################################################################################-->
    	<!--##############################################################################################################################-->
    	
    
    </beans>
    My action beans are defined in this separate spring configuration:
    Code:
    <?xml version="1.0" encoding="windows-1252" ?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:webflow="http://www.springframework.org/schema/webflow-config"
           xsi:schemaLocation="
                           http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                           http://www.springframework.org/schema/webflow-config
                           http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.3.xsd">	
        
        <bean id="entity1SearchAction" class="com.website.flow.action.Entity1SearchAction" />
        
        <bean id="entity2SearchAction" class="com.website.flow.action.Entity2SearchAction" />
        
        <bean id="registrationAction" class="com.website.flow.action.RegistrationAction" />
        
    </beans>
    And my validation bean is in it's own separate spring configuration too:
    Code:
    <?xml version="1.0" encoding="windows-1252" ?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:webflow="http://www.springframework.org/schema/webflow-config"
           xsi:schemaLocation="
                           http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                           http://www.springframework.org/schema/webflow-config
                           http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.3.xsd">	
    
        <bean id="registrationValidator" class="com.website.flow.validator.RegistrationModelValidator" />
           
    </beans>
    Here is my validator class:
    Code:
    package com.website.flow.validator;
    
    import java.util.regex.Pattern;
    
    import com.website.config.Resources;
    import com.website.flow.model.RegistrationModel;
    
    import org.springframework.validation.Errors;
    import org.springframework.validation.Validator;
    
    import com.website.libraries.logging.LogManager;
    import com.website.libraries.util.WebUtil;
    
    public class RegistrationModelValidator implements Validator {
    	
    	public static final String SOURCE_NAME = "RegistrationModelValidator";
    	public static final String REGEX_FIELDNUMBER = "[0-9]{9}";
    
    	@Override
    	public boolean supports(Class<?> clazz) {
    		return RegistrationModel.class.isAssignableFrom(clazz);
    	}
    
    	@Override
    	public void validate(Object obj, Errors errors) {
    		LogManager.debug(Resources.LOG_DIRECTORY, SOURCE_NAME, "Entering RegistrationModelValidator.validate()...");
    		RegistrationModel model = (RegistrationModel) obj;
    		if (model.isReadyToRegister()) { // the user has verified the fieldNumber is not in the system and can now submit a registration application
    			
    		} else { // the user is attempting to begin registration and needs to verify the fieldNumber is not in the system
    			if (WebUtil.isEmptyString(model.getName())) {
    				errors.reject("error.name-required", "name is required");
    			}
    			if (WebUtil.isEmptyString(model.getfieldNumber())) {
    				errors.reject("error.fieldNumber-required", "fieldNumber is required");
    			} else if (!Pattern.matches(REGEX_FIELDNUMBER, model.getfieldNumber())) {
    				errors.reject("error.fieldNumber-invalid-format", "fieldNumber must be numbers only and 9 digits in length");
    			}
    		}
    		LogManager.debug(Resources.LOG_DIRECTORY, SOURCE_NAME, "Exiting RegistrationModelValidator.validate()...");
    	}
    
    }
    >>> POST WAS TOO LONG >> REPLYING WITH REMAINING CODE....

  • #2
    >>> I have referred to the reference documentation => http://static.springsource.org/sprin...alidation.html >>>

    Here is the RegistrationModel:
    Code:
    package com.website.flow.model;
    
    import java.io.Serializable;
    
    public class RegistrationModel implements Serializable {
    
    	private static final long serialVersionUID = 1L;
    
    	private boolean readyToRegister;
    	private boolean canHaveAnAccount;
    	
    	private String fieldNumber;
    	private String name;
    	private String address1;
    	private String address2;
    	private int state;
    	private int city;
    	private String zip;
    	private String fax;
    	private String contactName1;
    	private String contactPhone1;
    	private String contactName2;
    	private String contactPhone2;
    	private String username;
    	private String password;
    	private String reEnterPassword;
    	private String namePrefix;
    	private String firstName;
    	private String lastName;
    	private String mainPhone;
    	private String mainPhoneExtension;
    	private String altPhone;
    	private String altPhoneExtension;
    	private String mainEmail;
    	private String altEmail;
    	
    	public boolean isCanHaveAnAccount() {
    		return canHaveAnAccount;
    	}
    
    	public void setCanHaveAnAccount(boolean canHaveAnAccount) {
    		this.canHaveAnAccount = canHaveAnAccount;
    	}
    
    	public boolean isReadyToRegister() {
    		return readyToRegister;
    	}
    
    	public void setReadyToRegister(boolean readyToRegister) {
    		this.readyToRegister = readyToRegister;
    	}
    
    	public String getfieldNumber() {
    		return fieldNumber;
    	}
    
    	public void setfieldNumber(String fieldNumber) {
    		this.fieldNumber = fieldNumber;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public String getAddress1() {
    		return address1;
    	}
    
    	public void setAddress1(String address1) {
    		this.address1 = address1;
    	}
    
    	public String getAddress2() {
    		return address2;
    	}
    
    	public void setAddress2(String address2) {
    		this.address2 = address2;
    	}
    
    	public int getState() {
    		return state;
    	}
    
    	public void setState(int state) {
    		this.state = state;
    	}
    
    	public int getCity() {
    		return city;
    	}
    
    	public void setCity(int city) {
    		this.city = city;
    	}
    
    	public String getZip() {
    		return zip;
    	}
    
    	public void setZip(String zip) {
    		this.zip = zip;
    	}
    
    	public String getFax() {
    		return fax;
    	}
    
    	public void setFax(String fax) {
    		this.fax = fax;
    	}
    
    	public String getContactName1() {
    		return contactName1;
    	}
    
    	public void setContactName1(String contactName1) {
    		this.contactName1 = contactName1;
    	}
    
    	public String getContactPhone1() {
    		return contactPhone1;
    	}
    
    	public void setContactPhone1(String contactPhone1) {
    		this.contactPhone1 = contactPhone1;
    	}
    
    	public String getContactName2() {
    		return contactName2;
    	}
    
    	public void setContactName2(String contactName2) {
    		this.contactName2 = contactName2;
    	}
    
    	public String getContactPhone2() {
    		return contactPhone2;
    	}
    
    	public void setContactPhone2(String contactPhone2) {
    		this.contactPhone2 = contactPhone2;
    	}
    
    	public String getUsername() {
    		return username;
    	}
    
    	public void setUsername(String username) {
    		this.username = username;
    	}
    
    	public String getPassword() {
    		return password;
    	}
    
    	public void setPassword(String password) {
    		this.password = password;
    	}
    
    	public String getNamePrefix() {
    		return namePrefix;
    	}
    
    	public void setNamePrefix(String namePrefix) {
    		this.namePrefix = namePrefix;
    	}
    
    	public String getFirstName() {
    		return firstName;
    	}
    
    	public void setFirstName(String firstName) {
    		this.firstName = firstName;
    	}
    
    	public String getLastName() {
    		return lastName;
    	}
    
    	public void setLastName(String lastName) {
    		this.lastName = lastName;
    	}
    
    	public String getMainPhone() {
    		return mainPhone;
    	}
    
    	public void setMainPhone(String mainPhone) {
    		this.mainPhone = mainPhone;
    	}
    
    	public String getMainPhoneExtension() {
    		return mainPhoneExtension;
    	}
    
    	public void setMainPhoneExtension(String mainPhoneExtension) {
    		this.mainPhoneExtension = mainPhoneExtension;
    	}
    
    	public String getAltPhone() {
    		return altPhone;
    	}
    
    	public void setAltPhone(String altPhone) {
    		this.altPhone = altPhone;
    	}
    
    	public String getAltPhoneExtension() {
    		return altPhoneExtension;
    	}
    
    	public void setAltPhoneExtension(String altPhoneExtension) {
    		this.altPhoneExtension = altPhoneExtension;
    	}
    
    	public String getMainEmail() {
    		return mainEmail;
    	}
    
    	public void setMainEmail(String mainEmail) {
    		this.mainEmail = mainEmail;
    	}
    
    	public String getAltEmail() {
    		return altEmail;
    	}
    
    	public void setAltEmail(String altEmail) {
    		this.altEmail = altEmail;
    	}
    
    	public String getReEnterPassword() {
    		return reEnterPassword;
    	}
    
    	public void setReEnterPassword(String reEnterPassword) {
    		this.reEnterPassword = reEnterPassword;
    	}
    
    }
    Here is my registration-flow definition:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <flow xmlns="http://www.springframework.org/schema/webflow"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://www.springframework.org/schema/webflow
            http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
    
    	<var name="registerModel" class="com.website.flow.model.RegistrationModel" />
    	
    	<view-state id="start" view="../jsp/registration/registerForm.jsp" model="registerModel">
     		<on-entry>
     			<evaluate expression="registrationAction.start" />
     		</on-entry>	
     		<transition on="loadCities" to="loadCitiesAction" />
     		<transition on="beginRegistration" to="validateRegistration" />
     	</view-state>
     	
     	<action-state id="loadCitiesAction">
     		<evaluate expression="registrationAction.loadCities" />
     		<transition on="done" to="start" />
     	</action-state>
     	
     	<action-state id="validateRegistration">
     		<evaluate expression="registrationAction.beginRegistration" />
     		<transition on="done" to="start" />
     	</action-state>
        	
        <end-state id="end" />
    
    </flow>
    >>> AGAIN TOO LONG >> JSP CODE IN NEXT REPLY.....

    Comment


    • #3
      And finally here is my JSP:
      Code:
      <h2>Registration</h2>
      
      <div>Checker => ${checker}</div><br />
      <form:errors path="registerModel" cssClass="errors" element="div" />
      
      <form:form id="registrationForm" modelAttribute="registerModel">
      
      		
      	
      	
      	<h6>Field Number</h6>
      	<div class="contentDescription">Enter your Field Number to begin registration</div><br />
      	<table class="form" style="width:100%;">
      		
      		<tr>
      			<td class="label">Field Number:</td>
      			<td>
      				<form:input path="fieldNumber" />
      			</td>
      		</tr>
      	</table>
      
      <c:if test="${registerModel.readyToRegister}">
      	
      	<h6>Entity Information:</h6>
      	<table class="form" style="width:100%;">
      		<tr>
      			<td class="label">Name:</td>
      			<td>
      				<form:input path="name" />
      			</td>
      		</tr>
      		<tr>
      			<td class="label">Address 1:</td>
      			<td><form:input path="address1" /></td>
      		</tr>
      		<tr>
      			<td class="label">Address 2:</td>
      			<td><form:input path="address2" /></td>
      		</tr>
      		<tr>
      			<td class="label">State:</td>
      			<td>
      				<form:select path="state" id="selStates" onchange="changeState(this);">
      					<form:option value="-1">Select a state...</form:option>
      					<c:forEach items="${statesList}" var="state" varStatus="statesLooper">
      						<form:option value="${state.stateCode}">${state.stateName}</form:option>	
      					</c:forEach>
      				</form:select>
      			</td>
      		</tr>
      		<tr>
      			<td class="label">City:</td>
      			<td id="cityContainer">
      				<c:choose>
      					<c:when test="${fn:length(cityList)>0 }">
      						<form:select path="city" id="selCities">
      							<form:option value="-1">Select a city...</form:option>
      							<c:forEach items="${cityList}" var="city" varStatus="citiesLooper">
      								<form:option value="${city.cityCode}">${city.cityName}</form:option>	
      							</c:forEach>
      						</form:select>
      					</c:when>
      					<c:otherwise>
      						Select a state to load the list of cities
      					</c:otherwise>
      				</c:choose>
      			</td>
      		</tr>
      		<tr>
      			<td class="label">Zip:</td>
      			<td><form:input path="zip" /></td>
      		</tr>
      		<tr>
      			<td class="label">Fax:</td>
      			<td><form:input path="fax" /></td>
      		</tr>
      		<tr>
      			<td class="label">Contact Name 1:</td>
      			<td><form:input path="contactName1" /></td>
      		</tr>
      		<tr>
      			<td class="label">Contact Phone 1:</td>
      			<td><form:input path="contactPhone1" /></td>
      		</tr>
      		<tr>
      			<td class="label">Contact Name 2:</td>
      			<td><form:input path="contactName2" /></td>
      		</tr>
      		<tr>
      			<td class="label">Contact Phone 2:</td>	
      			<td><form:input path="contactPhone2" /></td>
      		</tr>
      	</table>
      	
      </c:if> <%-- /readyToRegister --%>	
      
      <c:if test="${registerModel.canHaveAnAccount}">
      	
      	<h6>Login Information</h6>
      	<table class="form" width="100%">
      		<tr>
      			<td class="label">Username:</td>
      			<td><form:input path="username" /></td>
      		</tr>
      		<tr>
      			<td class="label">Password:</td>
      			<td><form:password path="password"/></td>
      		</tr>
      		<tr>
      			<td class="label">Re-enter Password:</td>
      			<td><form:password path="reEnterPassword" /></td>
      		</tr>
      	</table>
      	
      	<h6>User Profile</h6>
      	<table class="form" style="width:100%;">
      		<tr>
      			<td class="label">Prefix</td>
      			<td>
      				<form:select path="namePrefix" id="selNamePrefix">
      					<form:option value="-1">Select one...</form:option>
      					<form:option value="Mr.">Mr.</form:option>
      					<form:option value="Ms.">Ms.</form:option>
      				</form:select>
      			</td>
      		</tr>
      		<tr>
      			<td class="label">First Name</td>
      			<td><form:input path="firstName" /></td>
      		</tr>
      		<tr>
      			<td class="label">Last Name:</td>
      			<td><form:input path="lastName" /></td>
      		</tr>
      		<tr>
      			<td class="label">Main Phone:</td>
      			<td><form:input path="mainPhone" /></td>
      		</tr>
      		<tr>
      			<td class="label">Main Phone Extension:</td>
      			<td><form:input path="mainPhoneExtension" /></td>
      		</tr>
      		<tr>
      			<td class="label">Alternate Phone:</td>
      			<td><form:input path="altPhone" /></td>
      		</tr>
      		<tr>
      			<td class="label">Alternate Phone Extension:</td>
      			<td><form:input path="altPhoneExtension" /></td>
      		</tr>
      		<tr>
      			<td class="label">Main Email:</td>
      			<td><form:input path="mainEmail" /></td>
      		</tr>
      		<tr>
      			<td class="label">Alternate Email:</td>
      			<td><form:input path="altEmail" /></td>
      		</tr>
      	</table>
      	
      </c:if>
      
      <br /><br />
      <c:choose>
      	<c:when test="${registerModel.readyToRegister}">
      		<input type="submit" name="_eventId_submitRegistration" value="Submit Registration" id="btnSubmitRegistration" />
      	</c:when>
      	<c:otherwise>
      		<input type="submit" name="_eventId_beginRegistration" value="Begin Registration" id="btnBeginRegistration" />
      	</c:otherwise>
      </c:choose>
      </form:form>

      Comment


      • #4
        And the problem is? Basically you tell us it doesn't work, here is my code fix it... A bit more context and problem description would be nice.

        One thing I notice is that your errors element is outside your form element, that isn't going to work, neither is there a path 'registerModel' that would be '*'.

        Comment


        • #5
          I open the page and without entering any form data, I submit the form. This should trigger the validator and errors should be returned. You may notice some debugging statements being sent to a logger at the beginning and end of the validate method of the validator. None of this code is being triggered. I've ran in debug mode to confirm.

          You statement regarding the errors element being outside the form doesn't seem to be accurate. I have another application that I used as a practice run for the application I am building now. In one of the test pages the errors form element is outside of the form and the path is set to equal the value of the "modelAttribute" of the form. That application works.

          I moved the errors element into the forms tag and adjusted the path to be equal to "*" (star). The validator still does not get triggered.

          Comment


          • #6
            I suggest a read of the validation chapter in spring web flow. According to the documentation your validator isn't following the (naming) conventions.

            Your model is named 'registerModel' and as such your validator should be named 'registerModelValidator'

            Comment


            • #7
              Thank you. That was it. My naming was all over the place. Once I streamlined the naming everything started working.

              Thank you for your guidance. It's much appreciated.

              Comment

              Working...
              X