A single state is represented by Model-View-Controller components, using
the following naming convention: <state>.jsp, <state>Servlet,
and <state>Model.
Goals:
The main consequence of using the MVC system is that there will be more files than if we didn't use MVC. For every state, there are at least three files that are involved. However, each file should be much simpler and easier to understand than if these things were in fewer files, so it seems to be an acceptable tradeoff.
/**
* Performs simple conditional logic to determine which state to
* transition to.
**/
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException {
if (wasCancelChosen(request)) {
discardClientQualInfoModel(request);
enterState("index.jsp", request, response);
} else { // next was chosen
updateClientQualInfoModel(request);
if (getClientQualInfoModel(request).isInvalid()) {
enterState("ClientQualInfo.jsp", request, response);
} else {
createClientQualConfirmModel(request);
enterState("ClientQualConfirm.jsp", request, response);
}
}
}
private void discardClientQualInfoModel(HttpServletRequest request) throws ServletException {
//
// Remove the model from the session to allow the garbage collector
// to reclaim memory.
//
HttpSession theSession = request.getSession();
theSession.removeAttribute("clientQualInfoModel");
}
private ClientQualInfoModel(HttpServletRequest request) throws ServletException {
HttpSession theSession = request.getSession();
return (ClientQualInfoModel) theSession.getAttribute("clientQualInfoModel");
}
private void createClientQualConfirmModel(HttpServletRequest request) throws ServletException {
ClientQualConfirmModel theModel = new ClientQualConfirmModel();
//
// Set model properties (not shown here), then add the model to the session
// so that it is available to the next view.
//
HttpSession theSession = request.getSession();
theSession.setAttribute("clientQualConfirmModel", theModel);
}
/**
* Set the model properties using information gleaned from the request.
* Typically this will be pulling info out of forms and setting properties
* on the model.
**/
private void updateClientQualInfoModel(HttpServletRequest request) throws ServletException {
ClientQualInfoModel theModel = getClientQualInfoModel(request);
theModel.getUser().setFirstName(request.getParameter("firstName"));
theModel.getUser().setLastName(request.getParameter("lastName"));
//
// etc.
//
}
/**
* Forwards the request and response to the given stateView, which
* is typically a jsp. Prior to calling this method, please ensure
* that all business objects that the stateView depends on are available
* in the request (either put them in the session or make them available
* as page scope beans).
**/
private void enterState(String stateView,
HttpServletRequest request,
HttpServletResponse response) throws ServletException {
RequestDispatcher theDispatcher = ServletContext.getRequestDispatcher(stateView);
theDispatcher.forward(request, response);
}
<%!
//
// Returns <FONT COLOR="red"> if the given fieldName in the given ClientQualInfoModel
// is invalid, otherwise returns <FONT COLOR="black">. Use it like this:
//
// <%= fontColorTagFor("firstName", clientQualInfoModel) %>
// <B> First Name </B>
// </FONT>
//
public String fontColorTagFor(String fieldName, ClientQualInfoModel model) {
if (model.isFieldValid(fieldName)) {
return "<FONT COLOR=\"black\">";
} else {
return "<FONT COLOR=\"red\">";
}
}
%>
<jsp:usebean id="clientQualInfoModel" class="ClientQualInfoModel" scope="page" />
<%
if (clientQualInfoModel.isInvalid()) {
//
// print out the fields that need to be changed
//
%>
<FONT COLOR="red">
Please review the indicated fields:<BR>
<jsp:getProperty name="clientQualInfoModel" property="validationErrorList" />
</FONT>
<%
}
%>
<FORM ACTION="ClientQualInfoServlet" METHOD="POST">
<%= fontColorTagFor("firstName", clientQualInfoModel) %>
<B>First Name</B>
</FONT>
<INPUT TYPE="TEXT" NAME="firstName" VALUE="<%= clientQualInfoModel.getFirstName() %>" SIZE="20" MAXLENGTH="40">
<%= fontColorTagFor("lastName", clientQualInfoModel) %>
<B>Last Name</B>
</FONT>
<INPUT TYPE="TEXT" NAME="lastName" VALUE="<%= clientQualInfoModel.getLastName() %>" SIZE="20" MAXLENGTH="40">
<!-- etc. -->
public class ClientQualInfoModel extends FormModel {
//
// FormModel would be an abstract class that provides
// functionality used in all form models, such as
// collecting validation problems.
//
private User user;
private Vector validationProblems = new Vector();
//
// Constructors
//
public ClientQualInfoModel(User user) {
this.user = user;
}
//
// Accessing
//
public String getFirstName() {
return this.user.getFirstName();
}
public String getLastName() {
return this.user.getLastName();
}
// etc.
public boolean isInvalid() {
try {
this.user.validate();
return false;
} catch (ValidationException e) {
collectValidationProblems(e);
return true;
}
}
}