I am using Spring Web Flow(SWF) for my conversation type page navigation. In that project, there is main flow called candidatemain-flow.xml and have subflow called candidate-flow.xml and matriculation-flow.xml. When I running my project, the main flow start and it transaction to the subflow called candidate-flow.xml and the registration page is rendered. But I fill some data in registration form and submit back to the subflow, it can't travel the second subflow called matriculation-flow.xml(I think) and show the registration form again and this flow step "execution=e1s1" show again.
This is my flow main definition:
<?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.xsd">
<var name="candidate" class="com.wcg.lms.models.CandidateDTOFull"/>
<subflow-state id="candidateRegistrationFir" subflow="candidate">
<input name="candidate" value="candidate" type="com.wcg.lms.models.CandidateDTOFull"/>
<output name="candidate" value="candidate" type="com.wcg.lms.models.CandidateDTOFull"/>
<transition on="candidateReady" to="candidateRegistrationSec" />
</subflow-state>
<subflow-state id="candidateRegistrationSec" subflow="matriculation">
<input name="candidate" value="candidate" type="com.wcg.lms.models.CandidateDTOFull"/>
<transition on="matriculationReady" to="candidateRegistrationThir" />
</subflow-state>
<subflow-state id="candidateRegistrationThir" subflow="academic">
<input name="candidate" value="candidate"/>
<transition on="academicReady" to="candidateRegistrationFourth" />
</subflow-state>
<subflow-state id="candidateRegistrationFourth" subflow="other">
<input name="candidate" value="candidate"/>
<transition on="otherReady" to="candidateRegistrationFifth" />
</subflow-state>
<subflow-state id="candidateRegistrationFifth" subflow="sourceoffinance">
<input name="candidate" value="candidate"/>
<transition on="sourceOfFinanceReady" to="candidateRegistrationSixth" />
</subflow-state>
<subflow-state id="candidateRegistrationSixth" subflow="parentdetails">
<input name="candidate" value="candidate"/>
<transition on="parentDetailsReady" to="addNewCandidate" />
</subflow-state>
<action-state id="addNewCandidate">
<evaluate result="flowScope.candidate" expression="candidateDelegate.addNewCandidateDetails(candidate)"></evaluate>
<transition to="thankCandidate"/>
</action-state>
<view-state id="thankCandidate" model="flowScope.candidate">
<on-entry>
<set name="flowScope.candidate" value="candidate" type="com.wcg.lms.models.CandidateDTOFull"/>
</on-entry>
<transition to="endState"/>
</view-state>
<end-state id="endState"/>
<global-transitions>
<transition on="cancel" to="endState"/>
</global-transitions>
</flow>
This is candidate-flow.xml:
<?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.xsd">
<input name="candidate" type="com.wcg.lms.models.CandidateDTOFull" required="true" />
<view-state id="candidateRegistrationViewFir" model="candidate">
<on-entry>
<evaluate result="viewScope.idTypeList" expression="idTypeDelegate.findAllIdType()"/>
<evaluate result="viewScope.genderList" expression="T(com.wcg.yude.lms.components.common.Gender).values()"/>
<evaluate result="viewScope.maritalStatusList" expression="T(com.wcg.yude.lms.components.common.MaritalStatus).values()"/>
<set name="candidate.name" value="new com.wcg.yude.lms.components.student.Name()"/>
<set name="candidate.address" value="new com.wcg.yude.lms.components.registrar.Address()" />
<set name="candidate.contactInfo" value="new com.wcg.yude.lms.components.registrar.ContactInfo()" />
<set name="candidate.photoAttachment" value="new com.wcg.lms.models.AttachmentHolderDTO()" />
</on-entry>
<transition on="submit" to="candidateReady"/>
</view-state>
<end-state id="cancel" />
<end-state id="candidateReady">
<output name="candidate" type="com.wcg.lms.models.CandidateDTOFull" />
</end-state>
<global-transitions>
<transition on="cancel" to="cancel" />
</global-transitions>
</flow>
This is matriculation-flow.xml:
<?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.xsd">
<var name="matriculationDetails" class="com.wcg.lms.models.CandidateMatriculationStandardDetailsDTO"/>
<input name="candidate" type="com.wcg.lms.models.CandidateDTOFull" required="true" />
<view-state id="candidateRegistrationViewSec" model="candidate">
<on-entry>
<set name="viewScope.photoAttachment" value="new com.wcg.lms.models.AttachmentHolderDTO()" />
</on-entry>
<transition on="submit" to="matriculationReady">
<evaluate expression="candidate.setMatriculationStandardDetails(matriculationDetails)"></evaluate>
</transition>
</view-state>
<end-state id="cancel" />
<end-state id="matriculationReady" />
<global-transitions>
<transition on="cancel" to="cancel" />
</global-transitions>
</flow>
This is candidateRegistrationViewFir.jsp for registration:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>YUDE_Spring_Test</title>
<link href="<c:url value="/resources/css/bootstrap.min.css"/>" rel="stylesheet">
<link href="<c:url value="/resources/css/bootstrap.css"/>" rel="stylesheet">
<link href="<c:url value="/resources/css/thuStyle.css"/>" rel="stylesheet">
</head>
<body>
<div class="container-fluid">
<div class="row">
<img class="img-rounded" alt="" src="<c:url value="/resources/img/YUDE-Banner3.jpg"/>" style="width: 100%; height: 300px;">
</div>
<br/>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="well">
<sf:form cssClass="form-horizontal" commandName="candidate">
<input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}"/>
<label>flowExecutionKey: ${flowExecutionKey}</label>
<div class="form-group">
<label for="firstName" class="col-md-3 control-label">First Name :</label>
<div class="col-md-3">
<sf:input path="name.firstName" cssClass="form-control" size="15" id="firstName" placeholder="Full Name" />
</div>
<label for="street1" class="col-md-3 control-label">Street-1 :</label>
<div class="col-md-3">
<sf:input path="address.street1" cssClass="form-control" size="50" id="street1" placeholder="Street-1" />
</div>
</div>
<div class="form-group">
<label for="middleName" class="col-md-3 control-label">Middle Name :</label>
<div class="col-md-3">
<sf:input path="name.middleName" cssClass="form-control" size="15" id="middleName" placeholder="Middle Name" />
</div>
<label for="street2" class="col-md-3 control-label">Street-2 :</label>
<div class="col-md-3">
<sf:input path="address.street2" cssClass="form-control" size="50" id="street2" placeholder="Street-2" />
</div>
</div>
<div class="form-group">
<label for="lastName" class="col-md-3 control-label">Last Name :</label>
<div class="col-md-3">
<sf:input path="name.lastName" cssClass="form-control" size="15" id="lastName" placeholder="Last Name" />
</div>
<label for="city" class="col-md-3 control-label">City :</label>
<div class="col-md-3">
<sf:input path="address.city" cssClass="form-control" size="15" id="city" placeholder="City" />
</div>
</div>
<div class="form-group">
<label for="dob" class="col-md-3 control-label">Date Of Birth :</label>
<div class="col-md-3">
<sf:input path="dob" cssClass="form-control" size="15" id="dob" placeholder="Date Of Birth" />
</div>
<label for="state" class="col-md-3 control-label">State :</label>
<div class="col-md-3">
<sf:input path="address.state" cssClass="form-control" size="15" id="state" placeholder="State" />
</div>
</div>
<div class="form-group">
<label for="nationality" class="col-md-3 control-label">Nationality :</label>
<div class="col-md-3">
<sf:input path="nationality" cssClass="form-control" size="15" id="nationality" placeholder="Nationality" />
</div>
<label for="country" class="col-md-3 control-label">Country :</label>
<div class="col-md-3">
<sf:input path="address.country" cssClass="form-control" size="15" id="country" placeholder="Country" />
</div>
</div>
<div class="form-group">
<label for="race" class="col-md-3 control-label">Race</label>
<div class="col-md-3">
<sf:input path="race" cssClass="form-control" size="15" id="race" placeholder="Race" />
</div>
<label for="phone1" class="col-md-3 control-label">Phone-1 :</label>
<div class="col-md-3">
<sf:input path="contactInfo.phone1" cssClass="form-control" size="15" id="phone1" placeholder="Phone1" />
</div>
</div>
<div class="form-group">
<label for="idType" class="col-md-3 control-label">IdType :</label>
<div class="col-md-3">
<sf:select path="idType" cssClass="form-control" id="idType">
<c:forEach var="idType" items="${idTypeList}">
<sf:option value="${idType}">${idType.name}</sf:option>
</c:forEach>
</sf:select>
</div>
<label for="phone2" class="col-md-3 control-label">Phone-2 :</label>
<div class="col-md-3">
<sf:input path="contactInfo.phone2" cssClass="form-control" size="15" id="phone2" placeholder="Phone2" />
</div>
</div>
<div class="form-group">
<label for="idNo" class="col-md-3 control-label">Id No :</label>
<div class="col-md-3">
<sf:input path="idNo" cssClass="form-control" size="15" id="idNo" placeholder="IdNo" />
</div>
<label for="phone3" class="col-md-3 control-label">Phone-3 :</label>
<div class="col-md-3">
<sf:input path="contactInfo.phone3" cssClass="form-control" size="15" id="phone3" placeholder="Phone3" />
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">MALE</label>
<div class="col-md-1">
<sf:radiobutton path="gender" cssClass="form-control" value="${gender.MALE}" />
</div>
<label class="col-md-2 control-label">FEMALE</label>
<div class="col-md-1">
<sf:radiobutton path="gender" cssClass="form-control" value="${gender.FEMALE}" />
</div>
<label for="email1" class="col-md-3 control-label">Email-1 :</label>
<div class="col-md-3">
<sf:input path="contactInfo.email1" cssClass="form-control" size="15" id="email1" placeholder="Email-1" />
</div>
</div>
<div class="form-group">
<label for="maritalStatus" class="col-md-3 control-label">MaritalStatus :</label>
<div class="col-md-3">
<sf:select path="maritalStatus" cssClass="form-control" id="maritalStatus">
<c:forEach var="maritalStatus" items="${maritalStatusList}">
<sf:option value="${maritalStatus}">${maritalStatus}</sf:option>
</c:forEach>
</sf:select>
</div>
<label for="email2" class="col-md-3 control-label">Email-2 :</label>
<div class="col-md-3">
<sf:input path="contactInfo.email2" cssClass="form-control" size="15" id="email2" placeholder="Email-2" />
</div>
</div>
<div class="form-group">
<label for="occupation" class="col-md-3 control-label">Occupation :</label>
<div class="col-md-3">
<sf:input path="occupation" cssClass="form-control" size="15" id="occupation" placeholder="Occupation" />
</div>
<div class="form-group">
<label for="photoAttachment" class="col-md-3 control-label">File input</label>
<div class="col-md-3">
<sf:input path="photoFile" type="file" id="photoAttachment" />
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-3 pull-left">
<button type="submit" class="btn btn-primary" name="_eventId_cancel" disabled="disabled">← Older</button>
</div>
<div class="col-md-3 pull-right">
<input type="submit" class="btn btn-primary" name="_eventId_submit" value="Newer →"/>
</div>
</div>
</sf:form>
</div>
</div>
</div>
</div>
</body>
</html>
This is the candidateRegistrationViewSec.jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>YUDE_Spring_Test</title>
<link href="<c:url value="/resources/css/bootstrap.min.css"/>" rel="stylesheet">
<link href="<c:url value="/resources/css/bootstrap.css"/>" rel="stylesheet">
<link href="<c:url value="/resources/css/thuStyle.css"/>" rel="stylesheet">
</head>
<body>
<blockquote>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
<footer>Someone famous in <cite title="Source Title">Source Title</cite></footer>
</blockquote>
</body>
Your comment is partially right but not validator but it need converter or formatter. Although I directly fill data by call ref-type dot its value type variable, "IdTypeDTO" object and "Gender" enum are binding as String to its model class's property's property(means "candidateModelBean.candidate.idType" property is reference type and I bind that property as String).
So I simply add custom formatter for that type of property like this :
public class GenderFormatter implements Formatter<Gender>{
@Override
public String print(Gender gender, Locale local) {
return gender.getLabel();
}
@Override
public Gender parse(String value, Locale local) throws ParseException {
if(Gender.valueOf(value) == Gender.MALE) {
return Gender.MALE;
} else {
return Gender.FEMALE;
}
}
}
and registered in formatter registray and config in web flow config file and every things go well and transition to page 2(candidateRegistrationViewSec.jsp). However because of your comment, I check again and realize the solution. Thank for answering Prasad :)