3. JSP Example

All '/resources' URLs are resolved by Spring JavaScript's the ResourceServlet configured in the web.xml.

Excerpt from /WEB-INF/templates/main.jsp
                
<link type="text/css" rel="stylesheet" href="<c:url value="/resources/dijit/themes/tundra/tundra.css" />" />
<script type="text/javascript" src="<c:url value="/resources/dojo/dojo.js" />"></script>
<script type="text/javascript" src="<c:url value="/resources/spring/Spring.js" />"></script>
<script type="text/javascript" src="<c:url value="/resources/spring/Spring-Dojo.js" />"></script>
                
            

The create link goes to '/person.html' which is mapped to the person flow. The search link still goes through the PersonController. Both the create and search links are secured so when the login and logout pages are rendered, these links aren't displayed until the user logs in.

/WEB-INF/templates/menu.jsp
                
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>

<div id="side-bar">
    <a href="<c:url value="/"/>">Home</a>
    
    <sec:authorize ifAllGranted="ROLE_USER">
        <p><fmt:message key="person.form.title"/></p>
            <a href="<c:url value="/person.html"/>"><fmt:message key="button.create"/></a> 
            <a href="<c:url value="/person/search.html"/>"><fmt:message key="button.search"/></a>
    </sec:authorize>
</div>
                
            

The edit link goes to the person flow (ex: '/person.html?id=1'). The flow will look up the person record based on the id request parameter.

/WEB-INF/jsp/person/search.jsp
                
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>

<h1><fmt:message key="person.search.title"/></h1>

<table class="search">
    <tr>
        <th><fmt:message key="person.form.firstName"/></th>
        <th><fmt:message key="person.form.lastName"/></th>
    </tr>
<c:forEach var="person" items="${persons}" varStatus="status">
    <tr>
        <c:set var="personFormId" value="person${status.index}"/>

        <c:url var="editUrl" value="/person.html">
            <c:param name="id" value="${person.id}" />
        </c:url>
        
        <sec:authorize ifAllGranted="ROLE_ADMIN">
            <c:url var="deleteUrl" value="/person/delete.html"/>
            <form id="${personFormId}" action="${deleteUrl}" method="POST">
                <input id="id" name="id" type="hidden" value="${person.id}"/>
            </form>
        </sec:authorize>

        <td>${person.firstName}</td>
        <td>${person.lastName}</td> 
        <td>
            <a href='<c:out value="${editUrl}"/>'><fmt:message key="button.edit"/></a>
            <sec:authorize ifAllGranted="ROLE_ADMIN">
                <a href="javascript:document.forms['${personFormId}'].submit();"><fmt:message key="button.delete"/></a> 
            </sec:authorize>
        </td>
    </tr>
</c:forEach>
</table>
                
            

The form:form element just needs to have it's modelAttribute set to correspond to where the flow put the Person instance. The save and cancel buttons specify which event id they are associated with for this step in the flow. This value should match the flow's transition element's on attribute.

Messages are displayed at the top if there are any status or error messages available. Basic validation is performed by the PersonValidator. Which just checks that something has been filled in for the first and last name.

/WEB-INF/jsp/person/form.jsp
                
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>

<h1><fmt:message key="person.form.title"/></h1>

<div id="messages">
    <c:if test="${not empty statusMessageKey}">
       <p><fmt:message key="${statusMessageKey}"/></p>
    </c:if>

    <spring:hasBindErrors name="person">
        <h2>Errors</h2>
        <div class="formerror">
            <ul>
            <c:forEach var="error" items="${errors.allErrors}">
                <li>${error.defaultMessage}</li>
            </c:forEach>
            </ul>
        </div>
    </spring:hasBindErrors>
</div>

<form:form modelAttribute="person">
    <form:hidden path="id" />

    <fieldset>
        <div class="form-row">
            <label for="firstName"><fmt:message key="person.form.firstName"/>:</label>
            <span class="input"><form:input path="firstName" /></span>
        </div>       
        <div class="form-row">
            <label for="lastName"><fmt:message key="person.form.lastName"/>:</label>
            <span class="input"><form:input path="lastName" /></span>
        </div>
        <div class="form-buttons">
            <div class="button">
                <input type="submit" id="save" name="_eventId_save" value="<fmt:message key="button.save"/>"/>&#160;
                <input type="submit" name="_eventId_cancel" value="<fmt:message key="button.cancel"/>"/>&#160;    
            </div>    
        </div>
    </fieldset>
</form:form>