当前页面: 开发资料首页 → Java 专题 → JSF实例学习--比萨(pizza)订购系统。
摘要: JSF实例学习--比萨(pizza)订购系统。
JavaServer Face为Java应用程序的开发提速。
JavaServer Faces(JSF)是一项使用Java技术来快速构建Web应用程序的新技术。JSF通过提供以下特性来加速开发进程:
标准和可扩展的用户界面组件;极易配置的页面导航;用于输入验证的组件;自动化的Bean管理;事件处理;轻松的错误处理,
以及内置的对国际化的支持。
本文介绍如何使用JSF来构建在线比萨(pizza)订购系统。
项目描述
该应用程序被称之为PizzaRia,是一个在线商店,允许用户选择比萨饼并递交选定的比萨饼。PizzaRia与其他在线商店类似,
用户可以浏览菜单,向购物车中添加所选产品并进行结账。
该应用程序的用户界面由5个JSP文件组成,它们是index.jsp, details.jsp, shoppingCart.jsp, checkOut.jsp以及order.jsp 。
每个用户界面的页面包括3个其它页面:header.jsp, menu.jsp和 footer.jsp
用户购物流程:进入商店、查看商品详细信息、购物(放入购物车)、 结账、付款。
<table width="100%" align=center>
<tr> <td align=middle></td> </tr> </table><table width="100%" align=center>
<tr> <td align=middle></td> </tr> </table><table width="100%" align=center>
<tr> <td align=middle></td> </tr> </table> <table width="100%" align=center> <tr> <td height="453" align=middle></td> </tr> </table>
数据库
该程序的数据存储在3张表中:products(产品)、orders(定单)和OrderDetails(订单详细项目)。Products表存储产品信息,
具有4列:ProductId(产品标识), Name(名称), Description(说明)和 Price(价格)。
Orders表中的每一行存储一个单独的订单,其中的信息包括联系人姓名、送货地址以及信用卡细目。Orders表有6列:
OrderId(定单标识), ContactName(联系人姓名), DeliveryAddress(送货地址), CCName(信用卡所属人姓名),
CCNumber(信用卡号码)和 CCExpiryDate(信用卡有效期限)。
每个订单的详细项目被存储在OrderDetails表中。OrderDetails表有4列:OrderId(定单标识), ProductId(产品标识),
Quantity(数量)和 Price(价格)。Orders与OrderDetails表通过OrderID列有一对多的对应关系。请注意,OrderDetails表
在用户下订单的时候就保存相关的价格信息。该价格可能与当前产品价格不同,后者存储在Products表的Price列中。
用于在一个Oracle数据库中创建所需的表的脚本文件pizzaria-oracle.sql存放在pizzaria.zip文件中。
业务对象
以下是在该应用程序中使用的业务对象:
ProductBean用于封装一个产品信息。它具有如下属性:id(标识)、name(名称)、description(说明)和price(价格)。
每次details.jsp页被访问的时候,JSF实现(implementation)就会自动创建一个ProductBean实例。该JSF实现调用ProductBean
的无参数构造器,从数据库中获取相关的数据,并且将其填入相应的字列中。
ProductSummary。ProductSummary(产品概要)用于表示产品的概要。该类包含2个属性:id(标识)和name(名称)。
ShoppingItemBean。ShoppingItemBean用于表示购物项目。该类包含4个属性:productId(产品标识), productName
(产品名称), price(价格)以及 quantity(数量)。
ShoppingCartBean。ShoppingCartBean用于表示一个存储在对话(session)对象中的购物车。该类允许用户添加购物项目(使用addShopping方法),获取包含所有购物项目的列表(使用getShoppingItems方法),获得所购货物的总价值(使用getTotal方法)。
OrderBean。OrderBean表示一个订单。该类具有如下5个属性:contactName, deliveryAddress, creditCardName,
creditCardNumber以及 creditCardExpiryDate。
MenuBean。MenuBean使用getMenu方法显示可供产品的目录。该方法返回一个包含到产品细节的链接的HTML表。
package pizzaria;
import java.util.ArrayList;
import java.util.Iterator;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
public class MenuBean {
String browsePage = "details.jsp";
public String getBrowsePage() {
return browsePage;
}
public void setBrowsePage(String page) {
browsePage = page;
}
public String getMenu() {
// get DatabaseUtil instance
FacesContext facesContext = FacesContext.getCurrentInstance();
ServletContext servletContext = (ServletContext) facesContext.getExternalContext().getContext();
DatabaseUtil dbUtil = (DatabaseUtil) servletContext.getAttribute("DATABASE_UTIL");
StringBuffer buffer = new StringBuffer(512);
buffer.append("<table>\n");
ArrayList summaries = dbUtil.getProductSummaries();
Iterator iterator = summaries.iterator();
while (iterator.hasNext()) {
ProductSummary summary = (ProductSummary) iterator.next();
buffer.append("<tr><td>");
buffer.append("" +
summary.getName() + "");
buffer.append("</td></tr>\n");
}
buffer.append("</table>\n");
return buffer.toString();
}
}
DatabaseUtil。DatabaseUtil提供了以下3种方法以便访问和操作数据:
应用程序上下文监听器
应用程序上下文监听器(AppContextListener类)从web.xml文件读出用于访问数据库的初始参数,然后将其写入
ServletContext对象。用到的初始参数如下:jdbcDriver, dbUrl, dbUserName和 dbPassword。在你的web.xml文件中编辑这些值,
以便反应你数据库的真实值。
package pizzaria; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class AppContextListener implements ServletContextListener { //从web.xml文件中读取Servlet上下文初始化参数,构造一个DatabaseUtil对象 public void contextInitialized(ServletContextEvent event) { DatabaseUtil dbUtil = new DatabaseUtil(); ServletContext servletContext = event.getServletContext(); String jdbcDriver = servletContext.getInitParameter("jdbcDriver"); String dbUrl = servletContext.getInitParameter("dbUrl"); String dbUserName = servletContext.getInitParameter("dbUserName"); String dbPassword = servletContext.getInitParameter("dbPassword"); dbUtil.setJdbcDriver(jdbcDriver); dbUtil.setDbUrl(dbUrl); dbUtil.setDbUserName(dbUserName); dbUtil.setDbPassword(dbPassword); servletContext.setAttribute("DATABASE_UTIL", dbUtil); } public void contextDestroyed(ServletContextEvent event) { ServletContext servletContext = event.getServletContext(); servletContext.removeAttribute("DATABASE_UTIL"); } }JSF应用程序配置
JSF允许编程人员仅仅通过应用程序配置文件就可以轻松配置应用程序。该文件如果存在的话,则它应该被命名为faces-config.xml, 并且应该位于你应用程序下的WEB-INF 目录。
可以在faces-config.xml文件中对该应用程序的多个方面进行配置,包括bean管理、页面导航、定制UI(用户界面)组件、
定制验证程序和消息资源。在 PizzaRia 应用程序中,我将该faces-config.xml用于bean管理和页面导航的配置。
<?xml version="1.0"?>
faces-config PUBLIC
"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
"http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
事件处理
package pizzaria; import java.util.Map; import javax.faces.FactoryFinder; import javax.faces.application.Application; import javax.faces.application.ApplicationFactory; import javax.faces.component.UICommand; import javax.faces.context.FacesContext; import javax.faces.el.ValueBinding; import javax.faces.event.ActionEvent; import javax.faces.event.ActionListener; import javax.servlet.ServletContext; public class AppActionListener implements ActionListener { public void processAction(ActionEvent event) { FacesContext facesContext = FacesContext.getCurrentInstance(); String localValue = (String) ((UICommand) event.getComponent()).getValue(); if ("Buy".equals(localValue)) { String productId = (String) facesContext.getExternalContext().getRequestParameterMap().get("myForm:productId"); Map sessionMap = facesContext.getExternalContext().getSessionMap(); ShoppingCartBean cart = (ShoppingCartBean) sessionMap.get("shoppingCartBean"); if (cart==null) { cart = new ShoppingCartBean();//创建购物车 sessionMap.put("shoppingCartBean", cart); } ProductBean product = getDatabaseUtil().getProductDetails(productId); ShoppingItemBean shoppingItem = new ShoppingItemBean(product.getId(), product.getName(), product.getPrice(), 1); cart.addShoppingItem(shoppingItem); } else if ("Pay".equals(localValue)) { // insert a record into the database OrderBean order = (OrderBean) getValueBinding("#{orderBean}").getValue(facesContext); ShoppingCartBean cart = (ShoppingCartBean) getValueBinding("#{shoppingCartBean}").getValue(facesContext); if (cart!=null && order!=null) { getDatabaseUtil().insertOrder(order, cart); // empty shopping cart cart.removeShoppingItems(); } } } private ValueBinding getValueBinding(String valueRef) { ApplicationFactory factory = (ApplicationFactory)FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY); Application application = factory.getApplication(); return application.createValueBinding(valueRef); } private DatabaseUtil getDatabaseUtil() { FacesContext facesContext = FacesContext.getCurrentInstance(); ServletContext servletContext = (ServletContext) facesContext.getExternalContext().getContext(); return (DatabaseUtil) servletContext.getAttribute("DATABASE_UTIL"); } }
AppActionListener类使用两个非常有用的方法:getValueBinding 和getDatabaseUtil。getValueBinding接受指定对象名的
字符串,并返回一个可以向下转换类型为对象类型的ValueBinding对象。比如说,为获得用户的在应用程序配置文件中被注册成shoppingCartBean 的ShoppingCartBean实例,开发人员需要通过传递"shoppingCartBean"来调用getValueBinding。
ShoppingCartBean cart = (ShoppingCartBean) getValueBinding("#{shoppingCartBean}").getValue(facesContext);
getDatabaseUtil方法返回一个对ServletContext中的DatabaseUtil实例的引用:
private DatabaseUtil getDatabaseUtil() { FacesContext facesContext = FacesContext.getCurrentInstance(); ServletContext servletContext = (ServletContext)facesContext.getExternalContext().getContext(); return (DatabaseUtil) servletContext.getAttribute("DATABASE_UTIL"); } 运行程序: http://127.0.0.1:8080/pizza/faces/index.jsp</td> </tr> <tr>
该PizzaRia JSF应用程序原作者使用JavaServer Faces[JSF] 1.0。为了学习方便,站长将其改用了jsf1.1+Access,并改写了
所有jsp文件。请下载源码分析。
↑返回目录
前一篇: JSF中的columnClasses和rowClasses样式类
后一篇: JSF实例学习--JCatalog