用Struts框架构建netstore
Struts构建netstore项目
一.数据库的连接 : 1.在server.xml(Host中)中的配置: (tomcat5.5)
<Context path="/netstorelm" docBase="C:\tomcat\webapps\shop\netstorelm\WebRoot" debug="0" reloadable="true">
<Resource name="jdbc/netstorelm" auth="Container" type="javax.sql.DataSource" maxActive="5" maxIdle="5" maxWait="10000" username="root" password="root" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/netstore?autoReconnect=true" /> </Context>
2.在DBUtil.java中获得数据库的连接:
public final class DBUtil { public static Connection getConnection() throws SQLException { return getConnection(true); } //无参数的连接
public static Connection getConnection(boolean isAutoCommit) throws SQLException { Connection conn = null; try { Context initContext =
new InitialContext();
DataSource ds=(DataSource)initContext.lookup("java:/comp/env/jdbc/netstorelm");
conn = ds.getConnection(); conn.setAutoCommit(isAutoCommit);
} catch (NamingException e) { e.printStackTrace();
throw new SQLException(e.getMessage()); } return conn; }
public static void commit(Connection conn) {
try { if (conn != null && !conn.isClosed()) { conn.commit(); }
} catch (SQLException e) { e.printStackTrace(); } }
public static void rollback(Connection conn) {
try { if (conn != null && !conn.isClosed()) { conn.rollback(); }
} catch (SQLException e) { e.printStackTrace(); } }
public static void release(Connection conn) { if (conn != null) {
try { conn.close();} catch (SQLException e){ e.printStackTrace();}} }
二.关于异常的处理: public class DataAccessException extends RuntimeException {
public DataAccessException() { super(); }
public DataAccessException(String arg0, Throwable arg1) {super(arg0, arg1);}
public DataAccessException(String arg0) {super(arg0); }
public DataAccessException(Throwable arg0) {super(arg0); } }
三.将程序中的常量单独存放用于提高Action的独立性:
public final class Constants {
public static final String SESSION_CONTAINER_KEY = "SessionContainer";
public static final String SIGNON_KEY = "Login";
public static final String SUCCESS_KEY = "Success";
public static final String FAILURE_KEY = "Failure";
public static final String IMAGE_RESOURCE_KEY = "IMAGE_RESOURCE_KEY"; }
四.用户注册和登陆模块:
1.模型层(Model):
public class Customer { private Long id; private String name;
private String password; private String email;
getter( )/setter( ); }
2.DAO持久化层:(Data Access Object):提供该层所有访问数据库的接口
a.dao接口: public interface CustomerDao {
public Customer getCustomer(Long id);
public List<Customer> getAllCustomers();
public Customer getCustomer(String email, String password);
public int addCustomer(Customer customer);
public int updateCustomer(Customer customer);
public int deleteCustomer(Long id); }
3.daoImpl实现: public class CustomerDaoImpl implements CustomerDao {
public Customer getCustomer(String email, String password) {//实现登陆
Connection conn = null; PreparedStatement pstmt = null;
ResultSet rs = null; try { conn = DBUtil.getConnection();
String sql = "select * from CUSTOMERS where email=? and password=?";
pstmt = conn.prepareStatement(sql); pstmt.setString(1, email);
pstmt.setString(2, password); rs = pstmt.executeQuery();
return assembleCustomer(rs); } catch (SQLException e) {
throw new DataAccessException(e);
} finally { DBUtil.release(rs, pstmt, conn); } }
private Customer assembleCustomer(ResultSet rs) throws SQLException {
Customer customer = null;
if (rs != null && rs.next()) { customer = new Customer();
customer.setId(rs.getLong(1)); customer.setName(rs.getString(2));
customer.setPassword(rs.getString(3));customer.setEmail(rs.getString(4));}
return customer; } //实现注册
public int addCustomer(Customer customer) {//从Action中传递过来,ActionForm结束
Connection conn = null; PreparedStatement pstmt = null;
try { conn = DBUtil.getConnection();
pstmt = conn.prepareStatement(INSERT_SQL);
pstmt.setString(1, customer.getName());
pstmt.setString(2, customer.getPassword());
pstmt.setString(3, customer.getEmail());
return pstmt.executeUpdate();
} catch(SQLException e) { return -1;
} finally { DBUtil.release(pstmt, conn); } }
public List<Customer> getAllCustomers() { //实现用户管理功能
pstmt = conn.prepareStatement(SELECT_SQL);
rs = pstmt.executeQuery(); return assembleCustomers(rs);....}
private List<Customer> assembleCustomers(ResultSet rs) throws SQLException {
List<Customer> records = new ArrayList<Customer>();
while (rs != null && rs.next()) { Customer customer = new Customer();
customer.setId(rs.getLong(1)); customer.setName(rs.getString(2));
customer.setPassword(rs.getString(3));customer.setEmail(rs.getString(4));
records.add(customer); } return records; }} //返回集合供传递
4.通过Dao工厂提供所有DAO层方法的接口: public final class NetstoreDaoFactory {
public static CustomerDao getCustomerDao( ) {return new CustomerDaoImpl();}
public static ItemDao getItemDao() { return new ItemDaoImpl(); }
public static LineItemDao getLineItemDao() {return new LineItemDaoImpl();}
public static OrderDao getOrderDao() { return new OrderDaoImpl(); } }
5.通过业务代理接口让业务对象和客户层分离,有利于隐藏业务逻辑的实现
a.接口: public interface NetstoreService {
public List<Item> getItems();
public Customer login(String email, String password);
public Item getItemById(Long id); public void deleteItemById(Long id);
public int addCustomer(Customer customer);
public Customer getCustomerById(Long id); public void saveOrder(Order order);
public List<Customer> getAllCustomers(); public int deleteCustomer(Long id);
public List<Order> getOrders(); public Order getOrder(Long id); }
b.业务代理的实现public class NetstoreServiceImpl implements NetstoreService {
private static final CustomerDao customerDao=NetstoreDaoFactory.getCustomerDao();
private static final ItemDao itemDao = NetstoreDaoFactory.getItemDao();
private static final OrderDao orderDao = NetstoreDaoFactory.getOrderDao();
private static final LineItemDao lineItemDao=NetstoreDaoFactory.getLineItemDao();
public List<Item> getItems() { return itemDao.getAllItems(); }
public Customer login(String email, String password) {
return customerDao.getCustomer(email, password); }
public int addCustomer(Customer customer) {
return customerDao.addCustomer(customer); } }
6.登陆过程:a.页面<logic:notPresent name="SessionContainer" property="customer"
scope="session"> //属性值须与ActionForm绑定或相同
<html:form action="signin.do" method="post">
<table border=0>
登陆email: <html:text property=" loginForm.email" size="12"/>
登陆密码 <html:password property=" loginForm.password"/>
<html:submit>登陆</html:submit> </table> </html:form> </logic:notPresent>
b.ActionForm的在config中的实例化:
<form-bean name="loginForm"
type="org.apache.struts.validator.DynaValidatorForm"> //采取动态验证表单
<form-property name="email" type="java.lang.String"></form-property>
<form-property name="password" type="java.lang.String" /> </form-bean>
c.配置文件:<action path="/signin"
type="netstore.security.LoginAction"
name="loginForm" scope="request" input="/index.jsp">
<forward name="Success" path="/welcome.jsp"></forward>
<forward name="Failure" path="/security/reg.jsp"></forward>
</action>
d.Action中的处理:public class LoginAction extends NetstoreBaseAction {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)throws Exception {
DynaValidatorForm loginForm = (DynaValidatorForm) form;
String email = (String) loginForm.get("email");
String password = (String) loginForm.get("password");
NetstoreService service = getNetstoreService();
Customer customer = service.login(email, password);
if (customer==null) { ActionMessages errors = new ActionMessages();
errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("notmatch"));
saveErrors(request, errors);return mapping.findForward(Constants.FAILURE_KEY);}
else{ SessionContainer sessionContainer = getSessionContainer(request);
sessionContainer.setCustomer(customer);
return mapping.findForward(Constants.SUCCESS_KEY); }} }
Action的实现方式还得考虑保存实体(用户和购物车)的存在
e. NetstoreService service = getNetstoreService();方法的由来:
public abstract class NetstoreBaseAction extends Action { //所有Action的基类
protected NetstoreService getNetstoreService(){return new NetstoreServiceImpl()}
protected Object getSessionObject(HttpServletRequest req, String attrName) {
Object sessionObj = null;
HttpSession session = req.getSession(false);//不产生一个新的session
if (session != null) { sessionObj = session.getAttribute(attrName); }
return sessionObj; }
protected SessionContainer getSessionContainer(HttpServletRequest request) {
SessionContainer sessionContainer = (SessionContainer) getSessionObject(
request, Constants.SESSION_CONTAINER_KEY);
if (sessionContainer == null) {sessionContainer = new SessionContainer();
HttpSession session = request.getSession(true);
session.setAttribute(Constants.SESSION_CONTAINER_KEY,sessionContainer);
} return sessionContainer; }
protected boolean isLoggedIn(HttpServletRequest request) {
SessionContainer container = getSessionContainer(request);
if (container.getCustomer()!=null&&container.getCustomer().getId() != null) {
return true; } else { return false; } }}
f.SessionContainer用于保存Customer和ShoppingCart信息
public class SessionContainer {
private Customer customer;
private ShoppingCart cart = new ShoppingCart();。。。。。setter()/getter()。。。
public void cleanUp() { setCart(null); setCustomer(null); }}
7.注册功能的实现过程:a.页面:
<logic:notPresent name="SessionContainer" property="customer" scope="session">
<html:form action="/reg.do" >
姓名:<html:text property="name" /> email: <html:text property="email" />
密码: <html:password property="password"/>
<html:submit>注册</html:submit> </html:form> </logic:notPresent>
b.配置文件:<form-bean name="regForm" type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="password" type="java.lang.String" />
<form-property name="email" type="java.lang.String" />
<form-property name="name" type="java.lang.String" /> </form-bean>
<action path="/reg" name="regForm"
type="netstore.security.RegAction" scope="request" input="/welcome.jsp">
<forward name="Success" path="/welcome.jsp"></forward>
<forward name="Failure" path="/security/reg.jsp"></forward> </action>
c.Aciton: public class RegAction extends NetstoreBaseAction {
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)throws Exception{
DynaValidatorForm regForm = (DynaValidatorForm) form;
NetstoreService service = getNetstoreService();
Customer customer=new Customer();
customer.setEmail((String) regForm.get("email"));
customer.setPassword((String) regForm.get("password"));
customer.setName((String) regForm.get("name"));
int rs=service.addCustomer(customer);
if (rs ==0) {ActionMessages errors = new ActionMessages();
errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage("notmatch"));
saveErrors(request, errors);return mapping.findForward(KEY);
}else{return mapping.findForward(Constants.SUCCESS_KEY);}} }
d.代理接口:
public interface NetstoreService{public int addCustomer(Customer customer);}
e.代理的实现:public class NetstoreServiceImpl implements NetstoreService {
private static final CustomerDao customerDao=NetstoreDaoFactory.getCustomerDao()
public int addCustomer(Customer customer){//通过代理得到工厂的方法接口
return customerDao.addCustomer(customer); }}
f:工厂方法的集合:public final class NetstoreDaoFactory {
public static CustomerDao getCustomerDao() {return new CustomerDaoImpl();}}
g:DAO层与关系数据库的访问:
public interface CustomerDao { public int addCustomer(Customer customer);}
h.DAO实现层:public int addCustomer(Customer customer) {//与模型层进行交互
Connection conn = null; PreparedStatement pstmt = null;
try {conn = DBUtil.getConnection();pstmt=conn.prepareStatement(INSERT_SQL);
pstmt.setString(1, customer.getName()); 。。。return pstmt.executeUpdate(); }
五.购物车模块:
1.显示出所有商品:a.欢迎页面: <logic:forward name="welcome"/>//可实现自动跳转
b.配置全局变量:<forward name="welcome" path="/home.do" redirect="true" />
<action path="/home" type="netstore.item.FeaturedPageAction"
scope="request"> <forward name="Success" path="/index.jsp" /> </action>
c. public class FeaturedPageAction extends NetstoreBaseAction {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)throws Exception {
NetstoreService service = getNetstoreService();
List<Item> featuredItems = service.getItems();
request.setAttribute("FeaturedItemsKey", featuredItems);
return mapping.findForward(Constants.SUCCESS_KEY); }}
d.DAO层实现: public List<Item> getAllItems() {
Connection conn = null; PreparedStatement pstmt = null;
ResultSet rs = null; try { conn = DBUtil.getConnection();
pstmt = conn.prepareStatement(SELECT_SQL);
rs = pstmt.executeQuery(); return assembleItems(rs); }
e.页面显示: <logic:iterate id="item" name="FeaturedItemsKey">
<html:link page="/viewitemdetail.do" paramName="item" paramProperty="id">
<img border="0" src="<bean:write name="item" property="smallImageURL"/>"/>
</html:link> //通过连接显示图片 <bean:write name="item" property="name"/>
<bean:write name="item" format="#,##0.00" property="basePrice"/></b><br>
<bean:write name="item" property="description"/> </logic:iterate>
2.显示商品的详细信息:a.配置信息: <form-bean name="itemDetailForm" type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="view" type="netstore.model.Item" /> </form-bean>
<action path="/viewitemdetail" type="netstore.item.GetItemDetailAction"
name="itemDetailForm" scope="request" input="/index.jsp">
<forward name="Success" path="/catalog/itemdetail.jsp"></forward> </action>
b.Action: public class GetItemDetailAction extends NetstoreBaseAction {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)throws Exception {
Long itemId = new Long(request.getParameter("id"));
NetstoreService service = getNetstoreService();
Item item = service.getItemById(itemId);
((DynaValidatorForm) form).set("view", item);//对动态表单对象赋值
return mapping.findForward(Constants.SUCCESS_KEY); }}
c.页面显示: <img border="0" src="<bean:write name="itemDetailForm" property="view.largeImageURL"/>"/> //显示一个表单的对象的属性值
<bean:write name="itemDetailForm" property="view.name"/>
<bean:write name="itemDetailForm" property="view.modelNumber"/>
<html:link page="/cart.do?method=addItem" paramId="id"paramName="itemDetailForm"
paramProperty="view.id" paramScope="request">添加到购物车 </html:link>
3.购物车: a.配置信息(需要继承DispatchAction)<action path="/cart" type="netstore.order.ShoppingCartAction" parameter="method">
<forward name="Success" path="/order/shoppingcart.jsp"/> </action>
b.Action: public class ShoppingCartAction extends NetstoreDispatchAction {
public ActionForward addItem(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws Exception {
SessionContainer sessionContainer = getSessionContainer(request);
Long itemId = new Long(request.getParameter("id"));
String qtyParameter = request.getParameter("qty");
int quantity = 1; if (qtyParameter != null) {
quantity = Integer.parseInt(qtyParameter); }
NetstoreService service = getNetstoreService();
Item item = service.getItemById(itemId);
sessionContainer.getCart().addItem(new ShoppingCartItem(item, quantity));
return mapping.findForward(Constants.SUCCESS_KEY); }
4.检测是否登陆: public class CheckoutAction extends NetstoreBaseAction {
public ActionForward execute( ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response )throws Exception {
if(!isLoggedIn(request)){return mapping.findForward(Constants.SIGNON_KEY);
} return mapping.findForward( Constants.SUCCESS_KEY ); }}
5.产生随机定单号
new Double(Math.random()* System.currentTimeMillis()).toString().substring(3, 8)
6.注销功能: public class LogoutAction extends NetstoreBaseAction {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)throws Exception {
HttpSession session = request.getSession(false);
if (session != null) {
SessionContainer sessionContainer = getSessionContainer(request);
if (sessionContainer != null) { sessionContainer.cleanUp(); } session.invalidate(); }
return mapping.findForward(Constants.SUCCESS_KEY); }}
7.Action得到动态表单对象:
a.<form-bean name="updateCusForm" type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="updateCus" type="netstore.model.Customer" />
</form-bean>
b.Action:DynaValidatorForm updateCus = (DynaValidatorForm) form;
Customer cus=(Customer)updateCus.get("updateCus");
8.将表单设置为只读: <html:text property="updateCus.name" value="${SessionContainer.customer.name}" readonly="true"/>