mvc sample working

This commit is contained in:
Keith Donald
2007-10-29 13:55:10 +00:00
parent c813626744
commit 7ac647dc43
13 changed files with 235 additions and 525 deletions

View File

@@ -1,16 +1,14 @@
<?xml version="1.0"?>
<project name="swf-booking-jsf" default="dist">
<project name="swf-booking-MVC" default="dist">
<property file="build.properties" />
<property file="project.properties" />
<property file="${common.build.dir}/build.properties" />
<property file="${common.build.dir}/project.properties" />
<property file="${user.home}/build.properties" />
<property name="build.web" value="true" />
<import file="${common.build.dir}/common-targets.xml" />
<import file="${common.build.dir}/tomcat-targets.xml" />
</project>

View File

@@ -1,13 +1,15 @@
package org.springframework.webflow.samples.booking.flow.booking;
import java.util.Calendar;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.persistence.EntityManager;
import org.springframework.binding.message.Messages;
import org.springframework.binding.message.Severity;
import org.springframework.webflow.action.MultiAction;
import org.springframework.webflow.execution.Event;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.validation.DataBinder;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.springframework.webflow.action.FormAction;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.samples.booking.app.Booking;
import org.springframework.webflow.samples.booking.app.Hotel;
@@ -18,8 +20,20 @@ import org.springframework.webflow.samples.booking.app.User;
* definition at the appropriate points. Actions allow an externalized flow definition to delegate out to Java code to
* perform processing.
*/
public class BookingActions extends MultiAction {
public class BookingActions extends FormAction {
public BookingActions() {
setFormObjectName("booking");
setValidator(new BookingValidator());
}
@Override
protected void initBinder(RequestContext context, DataBinder binder) {
binder.setRequiredFields(new String[] { "checkinDate", "checkoutDate", "creditCard", "creditCardName" });
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}
@Override
/**
* Create a new booking object and register it with the flow-managed entity manager. The booking is not actually
* flushed to the database at this time; that only occurs when the booking flow reaches its "bookingAuthorized"
@@ -31,37 +45,23 @@ public class BookingActions extends MultiAction {
* @param context the current flow execution request context
* @return success if the booking was created successfully.
*/
public Event createBooking(RequestContext context) {
protected Object createFormObject(RequestContext context) throws Exception {
Hotel hotel = (Hotel) context.getFlowScope().get("hotel");
User user = (User) context.getConversationScope().get("user");
Booking booking = new Booking(hotel, user);
EntityManager em = (EntityManager) context.getFlowScope().get("entityManager");
em.persist(booking);
context.getFlowScope().put("booking", booking);
return success();
return booking;
}
/**
* Perform some custom server-side validation on the flow-scoped Booking object updated by the booking form.
*
* It is expected a future milestone of Spring Web Flow 2.0 will add a Messages abstraction that decouples SWF
* artifacts from environment-specific constructs like the FacesContext.
* @param context the current flow execution request context
* @return success if validation was successful, error if not
*/
public Event validateBooking(RequestContext context) {
Booking booking = (Booking) context.getFlowScope().get("booking");
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, -1);
if (booking.getCheckinDate().before(calendar.getTime())) {
context.getMessageContext().addMessage(
Messages.text("checkinDate", "Check in date must be a future date", Severity.ERROR));
return error();
} else if (!booking.getCheckinDate().before(booking.getCheckoutDate())) {
context.getMessageContext().addMessage(
Messages.text("checkoutDate", "Check out date must be later than check in date", Severity.ERROR));
return error();
public class BookingValidator implements Validator {
public boolean supports(Class clazz) {
return Booking.class.equals(clazz);
}
return success();
public void validate(Object object, Errors errors) {
}
}
}
}

View File

@@ -2,7 +2,8 @@ package org.springframework.webflow.samples.booking.flow.main;
import java.util.List;
import org.springframework.webflow.action.MultiAction;
import org.springframework.validation.DataBinder;
import org.springframework.webflow.action.FormAction;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.samples.booking.app.Booking;
@@ -15,7 +16,7 @@ import org.springframework.webflow.samples.booking.app.User;
* at the appropriate points. Actions allow an externalized flow definition to delegate out to Java code to perform
* processing.
*/
public class MainActions extends MultiAction {
public class MainActions extends FormAction {
private BookingService bookingService;
@@ -56,8 +57,10 @@ public class MainActions extends MultiAction {
* @param context the current flow execution request context
* @return success
*/
public Event findHotels(RequestContext context) {
public Event findHotels(RequestContext context) throws Exception {
SearchCriteria search = (SearchCriteria) context.getFlowScope().get("searchCriteria");
DataBinder binder = createBinder(context, search);
doBind(context, binder);
List<Hotel> hotels = bookingService
.findHotels(search.getSearchString(), search.getPageSize(), search.getPage());
context.getFlowScope().put("hotels", hotels);

View File

@@ -54,5 +54,4 @@ public class SearchCriteria implements Serializable {
public void setPage(int page) {
this.page = page;
}
}
}

View File

@@ -4,6 +4,10 @@
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<listener>
<listener-class>org.apache.tiles.web.startup.TilesListener</listener-class>
</listener>
<!-- The front controller of the Spring MVC Web application, responsible for handling all application requests -->
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>

View File

@@ -1,265 +0,0 @@
/* Setup defaults since variable in browsers
----------------------------------------------- */
body, div, dd, dt, dl, img, ul, ol, li, p, h1, h2, h3, h4, h5, form, hr, fieldset {
margin: 0;
padding: 0;
}
/* Element Defaults
----------------------------------------------- */
html {
height: 100%;
background-color: #9cac7c;
}
img {
border: 0;
}
body {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: small;
line-height: 1.25em;
color: #362F2D;
position: relative;
width: 760px;
height: 100%;
margin-left: auto;
margin-right: auto;
}
label {
font-weight: bold;
color: #5E5147;
}
input {
border: 1px solid #C3BBB6;
padding: 4px;
margin: 5px 0;
background: #fff url(../images/input.bg.gif) 0 0 repeat-x;
}
select {
border: 1px solid #C3BBB6;
padding: 4px;
margin: 5px 0;
background: #fff url(../images/input.bg.gif) 0 0 repeat-x;
}ol, ul {
margin: 10px 0px 10px 6px;
}
li {
margin: 10px 12px;
}
fieldset {
border: 0;
}
/* Layout
----------------------------------------------- */
#document {
padding: 0 1px;
background: #fff url(../images/bg.gif) 0 0 repeat-y;
float: left;
border-bottom: 1px solid #C3BBB6;
}
#header {
float: left;
width: 758px;
height:36px;
background-color: #414f23;
}
#container {
float: left;
width: 758px;
background: url(../images/header.jpg) 0 0 repeat-x;
}
#sidebar {
float: left;
width: 205px;
margin-left: 5px;
margin-top: 185px;
padding-top: 5px;
}
#content {
float: left;
width: 448px;
margin-top: 195px;
padding-top: 5px;
background: #fff url(../images/cnt.bg.gif) 0 0 repeat-x;
}
#footer {
clear: both;
margin-top: 40px;
float: left;
padding: 20px;
border-top: 1px solid #C3BBB6;
background-color: #fff;
width: 718px;
text-align: right;
}
/* General
----------------------------------------------- */
input[type="submit"], input[type="button"] {
font-weight: bold;
color: #fff;
border: 1px solid #5D1414;
height: 26px;
background: #fff url(../images/btn.bg.gif) 0 0 repeat-x;
border-style: none;
}
.center {
text-align: center;
}
.entry {
clear: both;
padding-top: 10px;
}
.entry .label {
float: left;
padding-top: 10px;
padding-right: 5px;
font-weight: bold;
width: 150px;
text-align: right;
}
.entry .output {
float: left;
width: 250px;
padding-top: 10px;
text-align: left;
}
.entry .input {
float: left;
width: 250px;
text-align: left;
}
/* Sidebar
----------------------------------------------- */
.notes {
text-align: center;
font-size: small;
}
.errors {
font-size: small;
font-weight: bold;
text-align: center;
color: #600;
}
.errors div {
text-align: left;
}
.errors input {
border: 1px solid #600;
}
.errors ul {
list-style: none;
}
.buttonBox {
text-align: center;
padding: 5px 0;
}
#sidebar p {
font-size: small;
color: #8B7869;
line-height: 150%;
padding-top: 10px;
padding-bottom: 10px;
padding-left: 5px;
padding-right: 5px;
}
#sidebar li {
font-size: small;
color: #8B7869;
}
#sidebar h1 {
line-height: normal;
font-weight: bold;
font-size: small;
}
/*
#sidebar p:hover {
color: #362F2D;
}
*/
/* Content
----------------------------------------------- */
#content .section {
float: left;
width: 518px;
padding: 15px 15px 0 10px;
}
#content .section h1 {
font-family: "Trebuchet MS", Arial, sans-serif;
line-height: normal;
font-weight: normal;
font-size: large;
}
#content .section p {
line-height: 150%;
padding: 10px 0;
font-size: small;
}
#content table {
width: 100%;
border: 1px solid #D2C9C4;
border-collapse: collapse;
}
#content table caption {
padding-bottom: 6px;
text-align: left;
font-weight: bold;
}
#content table thead th {
border-left: 1px solid #D2C9C4;
background: #fff url(../images/th.bg.gif) 0 100% repeat-x;
border-bottom: 1px solid #D2C9C4;
padding: 6px;
text-align: left;
font-size: small;
}
#content table tbody td {
border-left: 1px solid #E4DBD5;
padding: 4px;
border-bottom: 1px solid #D2C9C4;
font-size: 8pt;
}
#content dt {
font-weight: bold;
float: left;
width: 33%;
}
#content dd {
padding-left: 10px;
float: left;
width: 66%;
}
#radio table {
border: 0px;
}
#radio table tr td {
border: 0px;
border-left: 0px;
border-bottom: 0px;
}
#content .section .prev {
float: left;
width: 120px;
}
#content .section .next {
float: left;
}
/* Header
----------------------------------------------- */
#title {
float: left;
padding: 10px 0 6px 15px;
color: #e9efdb;
}
#status {
color: #e9efdb;
float: right;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-weight: bold;
font-size: x-small;
text-align: right;
padding-top: 14px;
padding-right: 15px;
}
#status a {
color: #e9efdb;
text-decoration: none;
}

View File

@@ -2,7 +2,7 @@
<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-1.0.xsd">
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<attribute name="description" value="The flow that handles the process of booking a hotel for a user"/>
@@ -27,18 +27,16 @@
<method-result name="hotel" scope="flow" />
</bean-action>
</render-actions>
<transition on="book" to="createBooking" />
<transition on="book" to="enterBookingDetails" />
<transition on="cancel" to="cancel" />
</view-state>
<action-state id="createBooking">
<action method="createBooking" bean="bookingActions"/>
<transition on="success" to="enterBookingDetails" />
</action-state>
<view-state id="enterBookingDetails" view="bookingForm.jsp">
<render-actions>
<action method="setupForm" bean="bookingActions"/>
</render-actions>
<transition on="proceed" to="confirmBooking">
<action method="validateBooking" bean="bookingActions" />
<action method="bindAndValidate" bean="bookingActions" />
</transition>
<transition on="cancel" to="cancel" />
</view-state>

View File

@@ -1,4 +1,7 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<tiles:insertTemplate template="/template.jsp">
<tiles:putAttribute name="content">
@@ -8,146 +11,124 @@
</div>
<div class="section">
<h:form id="booking">
<h:messages errorClass="errors" />
<form:form id="booking" modelAttribute="booking">
<form:errors path="*" cssClass="errors" />
<fieldset>
<div class="entry">
<div class="field">
<div class="label">Name:</div>
<div class="output">#{hotel.name}</div>
<div class="output">${hotel.name}</div>
</div>
<div class="entry">
<div class="field">
<div class="label">Address:</div>
<div class="output">#{hotel.address}</div>
<div class="output">${hotel.address}</div>
</div>
<div class="entry">
<div class="field">
<div class="label">City, State:</div>
<div class="output">#{hotel.city}, #{hotel.state}</div>
<div class="output">${hotel.city}, ${hotel.state}</div>
</div>
<div class="entry">
<div class="field">
<div class="label">Zip:</div>
<div class="output">#{hotel.zip}</div>
<div class="output">${hotel.zip}</div>
</div>
<div class="entry">
<div class="field">
<div class="label">Country:</div>
<div class="output">#{hotel.country}</div>
<div class="output">${hotel.country}</div>
</div>
<div class="entry">
<div class="field">
<div class="label">Nightly rate:</div>
<div class="output">
<h:outputText value="#{hotel.price}">
<f:convertNumber type="currency" currencySymbol="$"/>
</h:outputText>
<spring:bind path="hotel.price">${status.value}</spring:bind>
</div>
</div>
<div class="entry">
<div class="field">
<div class="label">
<h:outputLabel for="checkinDate">Check In Date:</h:outputLabel>
<label for="checkinDate">Check In Date:</label>
</div>
<div class="input">
<sf:clientDateValidator allowBlank="false" msgDisplay="block" msgClass="errors">
<h:inputText id="checkinDate" value="#{booking.checkinDate}" required="true">
<f:convertDateTime pattern="MM/dd/yy" timeZone="EST"/>
</h:inputText>
</sf:clientDateValidator>
<form:errors path="checkinDate" cssClass="errors"/>
<form:input id="checkinDate" path="checkinDate"/>
</div>
</div>
<div class="entry">
<div class="field">
<div class="label">
<h:outputLabel for="checkoutDate">Check Out Date:</h:outputLabel>
<label for="checkoutDate">Check Out Date:</label>
</div>
<div class="input">
<sf:clientDateValidator allowBlank="false" msgDisplay="block" msgClass="errors">
<h:inputText id="checkoutDate" value="#{booking.checkoutDate}" required="true">
<f:convertDateTime pattern="MM/dd/yy" timeZone="EST"/>
</h:inputText>
</sf:clientDateValidator>
<form:errors path="checkoutDate" cssClass="errors"/>
<form:input id="checkoutDate" path="checkoutDate"/>
</div>
</div>
<div class="entry">
<div class="field">
<div class="label">
<h:outputLabel for="beds">Room Preference:</h:outputLabel>
<label for="beds">Room Preference:</label>
</div>
<div class="input">
<h:selectOneMenu id="beds" value="#{booking.beds}">
<f:selectItem itemLabel="One king-size bed" itemValue="1"/>
<f:selectItem itemLabel="Two double beds" itemValue="2"/>
<f:selectItem itemLabel="Three beds" itemValue="3"/>
</h:selectOneMenu>
<form:select id="beds" path="beds">
<form:option label="One king-size bed" value="1"/>
<form:option label="Two double beds" value="2"/>
<form:option label="Three beds" value="3"/>
</form:select>
</div>
</div>
<div class="entry">
<div class="field">
<div class="label">
<h:outputLabel for="smoking">Smoking Preference:</h:outputLabel>
<label for="smoking">Smoking Preference:</label>
</div>
<div id="radio" class="input">
<h:selectOneRadio id="smoking" value="#{booking.smoking}" layout="pageDirection">
<f:selectItem itemLabel="Smoking" itemValue="true"/>
<f:selectItem itemLabel="Non Smoking" itemValue="false"/>
</h:selectOneRadio>
<form:radiobutton id="smoking" path="smoking" label="Smoking" value="true"/>
<form:radiobutton path="smoking" label="Non Smoking" value="false"/>
</div>
</div>
<div class="entry">
<div class="field">
<div class="label">
<h:outputLabel for="creditCard">Credit Card #:</h:outputLabel>
<label for="creditCard">Credit Card #:</label>
</div>
<div class="input">
<sf:clientNumberValidator allowBlank="false" allowNegative="false" allowDecimals="false" minLength="16" maxLength="16" msgDisplay="block" msgClass="errors">
<h:inputText id="creditCard" value="#{booking.creditCard}" required="true"/>
</sf:clientNumberValidator>
<form:errors path="creditCard" cssClass="errors"/>
<form:input id="creditCard" path="creditCard"/>
</div>
</div>
<div class="entry">
<div class="field">
<div class="label">
<h:outputLabel for="creditCardName">Credit Card Name:</h:outputLabel>
<label for="creditCardName">Credit Card Name:</label>
</div>
<div class="input">
<sf:clientTextValidator allowBlank="false" msgDisplay="block" msgClass="errors">
<h:inputText id="creditCardName" value="#{booking.creditCardName}" required="true"/>
</sf:clientTextValidator>
<form:errors path="creditCardName" cssClass="errors"/>
<form:input id="creditCardName" path="creditCardName"/>
</div>
</div>
<div class="entry">
<div class="field">
<div class="label">
<h:outputLabel for="creditCardExpiryMonth">Credit Card Expiry:</h:outputLabel>
<label for="creditCardExpiryMonth">Credit Card Expirty:</label>
</div>
<div class="input">
<h:selectOneMenu id="creditCardExpiryMonth" value="#{booking.creditCardExpiryMonth}">
<f:selectItem itemLabel="Jan" itemValue="1"/>
<f:selectItem itemLabel="Feb" itemValue="2"/>
<f:selectItem itemLabel="Mar" itemValue="3"/>
<f:selectItem itemLabel="Apr" itemValue="4"/>
<f:selectItem itemLabel="May" itemValue="5"/>
<f:selectItem itemLabel="Jun" itemValue="6"/>
<f:selectItem itemLabel="Jul" itemValue="7"/>
<f:selectItem itemLabel="Aug" itemValue="8"/>
<f:selectItem itemLabel="Sep" itemValue="9"/>
<f:selectItem itemLabel="Oct" itemValue="10"/>
<f:selectItem itemLabel="Nov" itemValue="11"/>
<f:selectItem itemLabel="Dec" itemValue="12"/>
</h:selectOneMenu>
<h:selectOneMenu id="creditCardExpiryYear" value="#{booking.creditCardExpiryYear}">
<f:selectItem itemLabel="2005" itemValue="2005"/>
<f:selectItem itemLabel="2006" itemValue="2006"/>
<f:selectItem itemLabel="2007" itemValue="2007"/>
<f:selectItem itemLabel="2008" itemValue="2008"/>
<f:selectItem itemLabel="2009" itemValue="2009"/>
</h:selectOneMenu>
<form:select id="creditCardExpiryMonth" path="creditCardExpiryMonth">
<form:option label="Jan" value="1"/>
<form:option label="Feb" value="2"/>
<form:option label="Mar" value="3"/>
<form:option label="Apr" value="4"/>
<form:option label="May" value="5"/>
<form:option label="Jun" value="6"/>
<form:option label="Jul" value="7"/>
<form:option label="Aug" value="8"/>
<form:option label="Sep" value="9"/>
<form:option label="Oct" value="10"/>
<form:option label="Nov" value="11"/>
<form:option label="Dec" value="12"/>
</form:select>
<form:select path="creditCardExpiryYear">
<form:option label="2007" value="1"/>
<form:option label="2008" value="2"/>
<form:option label="2009" value="3"/>
</form:select>
</div>
</div>
<div class="entry errors">
<h:messages globalOnly="true"/>
</div>
<div class="entry">
<div class="label">&#160;</div>
<div class="input">
<sf:validateAllOnClick>
<h:commandButton id="proceed" action="proceed" value="Proceed"/>
</sf:validateAllOnClick>&#160;
<h:commandButton id="cancel" immediate="true" value="Cancel" action="cancel"/>
</div>
<div class="buttonGroup">
<input type="submit" name="_eventId_proceed" value="Proceed"/>&#160;
<input type="submit" name="_eventId_cancel" value="Cancel"/>&#160;
</div>
</fieldset>
</h:form>
</form:form>
</div>
</tiles:putAttribute>

View File

@@ -1,4 +1,7 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<tiles:insertTemplate template="/template.jsp">
<tiles:putAttribute name="content">
@@ -8,60 +11,54 @@
</div>
<div class="section">
<h:form id="confirm">
<form:form id="confirm" modelAttribute="booking">
<fieldset>
<div class="entry">
<div class="field">
<div class="label">Name:</div>
<div class="output">#{hotel.name}</div>
<div class="output">${hotel.name}</div>
</div>
<div class="entry">
<div class="field">
<div class="label">Address:</div>
<div class="output">#{hotel.address}</div>
<div class="output">${hotel.address}</div>
</div>
<div class="entry">
<div class="field">
<div class="label">City, State:</div>
<div class="output">#{hotel.city}, #{hotel.state}</div>
<div class="output">${hotel.city}, ${hotel.state}</div>
</div>
<div class="entry">
<div class="field">
<div class="label">Zip:</div>
<div class="output">#{hotel.zip}</div>
<div class="output">${hotel.zip}</div>
</div>
<div class="entry">
<div class="field">
<div class="label">Country:</div>
<div class="output">#{hotel.country}</div>
<div class="output">${hotel.country}</div>
</div>
<div class="entry">
<div class="field">
<div class="label">Total payment:</div>
<div class="output">
<h:outputText value="#{booking.total}">
<f:convertNumber type="currency"
currencySymbol="$"/>
</h:outputText>
<div class="output">
<spring:bind path="total">${status.value}</spring:bind>
</div>
</div>
<div class="entry">
<div class="field">
<div class="label">Check In Date:</div>
<div class="output"><h:outputText value="#{booking.checkinDate}"/></div>
<div class="output"><spring:bind path="checkinDate">${status.value}</spring:bind></div>
</div>
<div class="entry">
<div class="field">
<div class="label">Check Out Date:</div>
<div class="output"><h:outputText value="#{booking.checkoutDate}"/></div>
<div class="output"><spring:bind path="checkoutDate">${status.value}</spring:bind></div>
</div>
<div class="entry">
<div class="field">
<div class="label">Credit Card #:</div>
<div class="output">#{booking.creditCard}</div>
<div class="output">${booking.creditCard}</div>
</div>
<div class="entry">
<div class="label">&#160;</div>
<div class="input">
<h:commandButton id="confirm" value="Confirm" action="confirm"/>&#160;
<h:commandButton id="revise" value="Revise" action="revise"/>&#160;
<h:commandButton id="cancel" value="Cancel" action="cancel"/>
</div>
<div class="buttonGroup">
<input type="submit" name="_eventId_confirm" value="Confim"/>&#160;
<input type="submit" name="_eventId_revise" value="Revise"/>&#160;
<input type="submit" name="_eventId_cancel" value="Cancel"/>&#160;
</div>
</fieldset>
</h:form>
</form:form>
</div>
</tiles:putAttribute>
</tiles:insertTemplate>
</tiles:insertTemplate>

View File

@@ -1,4 +1,7 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<tiles:insertTemplate template="/template.jsp">
<tiles:putAttribute name="content">
@@ -8,48 +11,45 @@
</div>
<div class="section">
<div class="entry">
<div class="label">Name:</div>
<div class="output">#{hotel.name}</div>
</div>
<div class="entry">
<div class="label">Address:</div>
<div class="output">#{hotel.address}</div>
</div>
<div class="entry">
<div class="label">City:</div>
<div class="output">#{hotel.city}</div>
</div>
<div class="entry">
<div class="label">State:</div>
<div class="output">#{hotel.state}</div>
</div>
<div class="entry">
<div class="label">Zip:</div>
<div class="output">#{hotel.zip}</div>
</div>
<div class="entry">
<div class="label">Country:</div>
<div class="output">#{hotel.country}</div>
</div>
<div class="entry">
<div class="label">Nightly rate:</div>
<div class="output">
<h:outputText value="#{hotel.price}">
<f:convertNumber type="currency" currencySymbol="$"/>
</h:outputText>
</div>
</div>
</div>
<div class="section">
<h:form id="hotel">
<fieldset class="buttonBox">
<h:commandButton id="book" action="book" value="Book Hotel"/>&#160;
<h:commandButton id="cancel" action="cancel" value="Back to Search"/>
<form:form id="hotel" modelAttribute="hotel">
<fieldset>
<div class="field">
<div class="label">Name:</div>
<div class="output">${hotel.name}</div>
</div>
<div class="field">
<div class="label">Address:</div>
<div class="output">${hotel.address}</div>
</div>
<div class="field">
<div class="label">City:</div>
<div class="output">${hotel.city}</div>
</div>
<div class="field">
<div class="label">State:</div>
<div class="output">${hotel.state}</div>
</div>
<div class="field">
<div class="label">Zip:</div>
<div class="output">${hotel.zip}</div>
</div>
<div class="field">
<div class="label">Country:</div>
<div class="output">${hotel.country}</div>
</div>
<div class="field">
<div class="label">Nightly rate:</div>
<div class="output">
<spring:bind path="price">${status.value}</spring:bind>
</div>
</div>
<div class="buttonGroup">
<input type="submit" name="_eventId_book" value="Book Hotel"/>&#160;
<input type="submit" name="_eventId_cancel" value="Back to Search"/>&#160;
</div>
</fieldset>
</h:form>
</form:form>
</div>
</titles:putAttribute>
</tiles:putAttribute>
</tiles:insertTemplate>

View File

@@ -8,7 +8,7 @@
<form:form modelAttribute="searchCriteria">
<div class="section">
<span class="errors">
<form:errors/>
<form:errors path="*"/>
</span>
<h1>Search Hotels</h1>
<fieldset>
@@ -19,15 +19,11 @@
<form:option label="10" value="10"/>
<form:option label="20" value="20"/>
</form:select>
<input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}" />
<input type="submit" class="button" name="_eventId_findHotels" value="Find Hotels" style="width: 165px; height: 15px;" />
<input type="submit" class="button" name="_eventId_findHotels" value="Find Hotels" />
</fieldset>
</div>
<div class="section">
<c:if test="#{hotels.empty == 0}">
No Hotels Found
</c:if>
<table>
<thead>
<tr>
@@ -38,18 +34,14 @@
</tr>
</thead>
<tbody>
<c:forEach var="hotel" items="#{hotels}">
<c:forEach var="hotel" items="${hotels}">
<tr>
<td>#{hotel.name}</td>
<td>#{hotel.address}</td>
<td>#{hotel.city}, #{hotel.state}, #{hotel.country}</td>
<td>#{hotel.zip}</td>
<td>${hotel.name}</td>
<td>${hotel.address}</td>
<td>${hotel.city}, ${hotel.state}, ${hotel.country}</td>
<td>${hotel.zip}</td>
<td>
<c:url var="viewHotelLink">
<c:param name="hotelId" value="#{hotel.id}"/>
<c:param name="_flowExecutionKey" value="#{flowExecutionKey}" />
</c:url>
<a href="#{viewHotelLink}">View Hotel</a>
<a href="${flowExecutionUrl}?_eventId=selectHotel&hotelId=${hotel.id}">View Hotel</a>
</td>
</tr>
</c:forEach>
@@ -62,10 +54,6 @@
</div>
<div class="section">
<c:if test="#{bookings.empty}">
No Bookings Found
</c:if>
<table>
<thead>
<tr>
@@ -79,20 +67,16 @@
</tr>
</thead>
<tbody>
<c:forEach var="booking" items="#{bookings}">
<c:forEach var="booking" items="${bookings}">
<tr>
<td>#{booking.hotel.name}</td>
<td>#{booking.hotel.address}</td>
<td>#{booking.hotel.city}, #{booking.hotel.state}</td>
<td>#{booking.checkinDate}</td>
<td>#{booking.checkoutDate}</td>
<td>#{booking.id}</td>
<td>${booking.hotel.name}</td>
<td>${booking.hotel.address}</td>
<td>${booking.hotel.city}, ${booking.hotel.state}</td>
<td>${booking.checkinDate}</td>
<td>${booking.checkoutDate}</td>
<td>${booking.id}</td>
<td>
<c:url var="cancelBookingLink">
<c:param name="bookingId" value="#{booking.id}"/>
<c:param name="_flowExecutionKey" value="#{flowExecutionKey}" />
</c:url>
<a href="#{cancelBookingLink}">Cancel</a>
<a href="${flowExecutionUrl}?_eventId=cancelBooking&bookingId=${booking.id}">Cancel</a>
</td>
</tr>
</c:forEach>

View File

@@ -2,7 +2,7 @@
<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-1.0.xsd">
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<attribute name="description" value="The main flow of the application that handles searching for hotels to book"/>

View File

@@ -5,25 +5,35 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Spring Faces: Hotel Booking Sample Application</title>
<link href="/swf-booking-jsf/css/screen.css" rel="stylesheet" type="text/css" />
<tiles:insertAttribute name="headIncludes" />
<style type="text/css" media="screen">
@import url("/swf-booking-mvc/spring/resources/css-framework/css/tools.css");
@import url("/swf-booking-mvc/spring/resources/css-framework/css/typo.css");
@import url("/swf-booking-mvc/spring/resources/css-framework/css/forms.css");
@import url("/swf-booking-mvc/spring/resources/css-framework/css/layout-navtop-localleft.css");
@import url("/swf-booking-mvc/spring/resources/css-framework/css/layout.css");
@import url("/swf-booking-mvc/spring/resources/css/booking.css");
</style>
</head>
<body>
<div id="document">
<div id="header">
<div id="title">Spring Faces: Hotel Booking Sample Application</div>
<div id="status">
Welcome #{user.name}
<body class="tundra spring">
<div id="page">
<div id="header" class="clearfix spring">
<div id="welcome">
<div class="left">Spring Web Flow + Spring MVC: Hotel Booking Sample Application</div>
<div class="right">
Welcome, ${user.name}
</div>
</div>
<div id="branding" class="spring">
<img src="/swf-booking-mvc/spring/resources/images/header.jpg" />
</div>
</div>
<div id="container">
<div id="sidebar">
<div id="content" class="clearfix spring">
<div id="local" class="spring">
<a href="http://www.thespringexperience.com">
<c:url value="/images/diplomat.jpg" />
<img src="/swf-booking-mvc/spring/resources/images/diplomat.jpg"/>
</a>
<a href="http://www.thespringexperience.com">
<c:url value="/images/tse.gif" />
<img src="/swf-booking-mvc/spring/resources/images/tse.gif"/>
</a>
<p>
The features illustrated in this sample are just the beginning.
@@ -32,14 +42,15 @@
December 12 - 15, 2007 at the Westin Diplomat in Hollywood, Florida.
</p>
</div>
<div id="content">
<div id="main">
<tiles:insertAttribute name="content" />
</div>
<div id="footer">
<a href="http://www.springframework.org"><img src="/swf-booking-jsf/images/powered-by-spring.png" /></a>
</div>
</div>
<div id="footer" class="clearfix spring">
<a href="http://www.springframework.org">
<img src="/swf-booking-mvc/spring/resources/images/powered-by-spring.png"/>
</a>
</div>
</div>
</body>
</html>