本文共 10207 字,大约阅读时间需要 34 分钟。
前言
为了巩固之前所学Java Web基础,特做一个还算是比较完整的小项目——在线网上书店。
成果图
在线网上书店这个项目包含了两个部分,前台和后台。前台用于向用户显示商品(这里是书籍)信息,如下图所示。
后台由管理员进行管理,后台分为分类管理模块、图书管理模块、订单管理模块以及数据库管理模块等4个模块,如下图所示。搭建开发环境
导入开发包和创建包结构
在Eclipse中新创建一个mybookstore的项目,导入项目所需要的开发包(jar包),创建项目所需要的包,在Java Web开发中,架构的层次是以包的形式体现出来的。
以上就是根据此项目的实际情况创建的包,可能还需要创建其他的包,这个得根据项目的需求来定了。后台分帧页面
在WebRoot根目录下新建一个manager.jsp页面,这个页面代表后台首页,而且该页面是一个分帧页面,分帧的代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>在线网上书店后台管理页面
我们还要在WebRoot根目录下新建一个manager目录,用于保存后台相关的一系列jsp页面。由于后台首页包含有head.jsp和left.jsp这两个页面,所以,还要在manager目录中新建出这两个页面。
-
head.jsp页面的内容如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
在线网上书店后台管理页面的页头部分 在线网上书店后台管理
-
left.jsp页面的内容如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
后台左侧导航页面
这样,后台分帧页面的显示效果如下:
前台分帧页面
在WebRoot根目录下新建一个client目录,用于保存前台相关的一系列jsp页面。紧接着在client目录中创建前台首页——index.jsp。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>前台首页 <%@include file="/client/head.jsp" %>......
由于在前台首页中静态引入了head.jsp页面,所以,还要在client目录中新建出这个页面。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>网上书店
这样,前台分帧页面的显示效果如下:
先把前台和后台分帧的页面架子给搭起来,后面在此基础上进行修修改改!创建项目所需的库
create database bookstore;use bookstore;
创建一些全局的工具类和过滤器
在cn.liayun.utils包中创建一个WebUtils工具类,该工具类的功能就是封装客户端提交的表单数据到一个JavaBean中。
package cn.liayun.utils;import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.apache.commons.beanutils.BeanUtils;//主要把请求数据封装到一个JavaBean中public class WebUtils { public staticT request2Bean(HttpServletRequest request, Class beanClass) { try { T bean = beanClass.newInstance(); Map map = request.getParameterMap(); BeanUtils.populate(bean, map); return bean; } catch (Exception e) { throw new RuntimeException(e); } } }
为了业务逻辑层和数据访问层之间的解耦,我们还应使用工厂设计模式来编写一下DaoFactory类来实现。于是,新建一个cn.liayun.factory包,在包中创建一个Dao工厂,即DaoFactory类,该类一般要设计成单例的。
package cn.liayun.factory;import java.io.InputStream;import java.util.Properties;public class DaoFactory { private static Properties prop = new Properties(); private DaoFactory() { try { InputStream in = DaoFactory.class.getClassLoader().getResourceAsStream("cn/liayun/factory/dao.properties"); prop.load(in); } catch (Exception e) { throw new RuntimeException(e); } } private static final DaoFactory instance = new DaoFactory(); public static DaoFactory getInstance() { return instance; } publicT createDao(Class interfaceClass) { try { String key = interfaceClass.getSimpleName(); String className = prop.getProperty(key); return (T) Class.forName(className).newInstance(); } catch (Exception e) { throw new RuntimeException(e); } } }
紧接着,在cn.liayun.factory包下创建一个dao.properties文件,该配置文件的内容如下:
CategoryDao=cn.liayun.dao.impl.CategoryDaoImplBookDao=cn.liayun.dao.impl.BookDaoImplUserDao=cn.liayun.dao.impl.UserDaoImplOrderDao=cn.liayun.dao.impl.OrderDaoImplDbBackDao=cn.liayun.dao.impl.DbBackDaoImpl
接下来,我们要编写一个用于处理全站中文乱码的过滤器CharacterEncodingFilter。
package cn.liayun.web.filter;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class CharacterEncodingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; request.setCharacterEncoding("UTF-8"); chain.doFilter(request, response); } @Override public void destroy() { // TODO Auto-generated method stub }}
紧接着,就要在web.xml文件中配置CharacterEncodingFilter过滤器了。
CharacterEncodingFilter cn.liayun.web.filter.CharacterEncodingFilter CharacterEncodingFilter /*
我们还要编写一个html转义过滤器(HtmlFilter),代码如下:
package cn.liayun.web.filter;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import javax.servlet.http.HttpServletResponse;public class HtmlFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; //request.getParameter(""); chain.doFilter(new MyRequest(request), response); } @Override public void destroy() { // TODO Auto-generated method stub } class MyRequest extends HttpServletRequestWrapper { private HttpServletRequest request; public MyRequest(HttpServletRequest request) { super(request); this.request = request; } @Override public String getParameter(String name) { String value = this.request.getParameter(name); return filter(value); } public String filter(String message) { if (message == null) return (null); char content[] = new char[message.length()]; message.getChars(0, message.length(), content, 0); StringBuilder result = new StringBuilder(content.length + 50); for (int i = 0; i < content.length; i++) { switch (content[i]) { case '<': result.append("<"); break; case '>': result.append(">"); break; case '&': result.append("&"); break; case '"': result.append("""); break; default: result.append(content[i]); } } return (result.toString()); } }}
紧接着,就要在web.xml文件中配置HtmlFilter过滤器了。
HtmlFilter cn.liayun.web.filter.HtmlFilter HtmlFilter /*
在这篇文章中,为了更加优雅地处理事务,我们使用了ThreadLocal类改造过数据库连接工具类JdbcUtils。所以,还得在cn.liayun.utils包中创建这样一个数据库连接工具类JdbcUtils。
package cn.liayun.utils;import java.sql.Connection;import javax.sql.DataSource;import com.mchange.v2.c3p0.ComboPooledDataSource;public class JdbcUtils { private static ThreadLocaltl = new ThreadLocal (); private static DataSource ds; static { ds = new ComboPooledDataSource(); } public static DataSource getDataSource() { return ds; } public static Connection getConnection() { try { //首先得到当前线程上绑定的连接 Connection conn = tl.get(); if (conn == null) { conn = ds.getConnection();//如果当前线程上没有绑定一个连接,则从数据库连接池拿一个连接 } tl.set(conn);//把连接绑定到当前线程上去 return conn; } catch (Exception e) { throw new RuntimeException(e); } } public static void startTransaction() { try { Connection conn = getConnection(); conn.setAutoCommit(false); } catch (Exception e) { throw new RuntimeException(e); } } public static void commitTransaction() { try { Connection conn = getConnection(); if (conn != null) { conn.commit(); } } catch (Exception e) { throw new RuntimeException(e); } } public static void closeConn() { Connection conn = null; try { conn = getConnection(); if (conn != null) { conn.close(); } } catch (Exception e) { throw new RuntimeException(e); } finally { /* if (conn != null) { tl.remove(); } */ tl.remove();//千万要注意,解除当前线程上绑定的连接(从ThreadLocal容器中移除掉对应当前线程上的连接) } } }
由于以上工具类使用了C3P0数据源,所以要在类目录下加入C3P0的配置文件,即c3p0-config.xml,该配置文件中的内容如下:
com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/bookstore root liayun 10 30 20 5 200 50 100 50 1000 0 5
也是在这篇文章中,我们漏讲了一个事务过滤器,如果使用了事务过滤器,那么一次请求范围内的所有操作都将在一个事务里面了,如下图所示。
如果事务过滤器是像下面这样编写的,那么会有什么问题呢? 读者试着思考一下,如果访问的是网站首页——index.jsp,那么该事务过滤器拦截下来之后,势必也要获取连接并开启事务,然后把连接绑定到当前线程上。如此一来,效率势必要差很多。更加合适的做法就是把获取连接、开启事务的操作延迟到第一次访问数据库时,而不是说,我一上来就帮你获取连接、开启事务,这样子做,效率上要好一点。因此,该事务过滤器要修改为: 试想,当我们在后续编写dao层的代码时,一上来势必会调用JdbcUtils类的getConnection方法获取一个连接,而且这个方法要确保获取到的是一个开启事务的连接。因此,还要修改JdbcUtils类的getConnection方法。 千万不要忘了在web.xml文件中配置TransactionFilter事务过滤器。TransactionFilter cn.liayun.web.filter.TransactionFilter TransactionFilter /*
至此,在线网上书店项目的环境总算是搭建好了!
转载地址:https://liayun.blog.csdn.net/article/details/91125908 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!