一、创建项目所需要的包
各个层所对应的包名:
web层:
com.bookmall.web/servlet/controller
service层:
com.bookmall.service Service接口包
com.bookmall.service.impl Service接口实现类
dao层:
com.bookmall.dao Dao接口包
com.bookmall.dao.impl Dao接口实现类
实体bean对象:
com.bookmall.pojo/entity/domain/bean JavaBean类
测试包:
com.bookmall.test/junit
工具包:
com.bookmall.utils
二、创建需要的数据库和表
1 | CREATE DATABASE bookmall; |
三、编写数据库表对应的 JavaBean 对象
在com.bookmall.bean包下创建User类
1 | package com.bookmall.bean; |
四、编写工具类JdbcUtils并测试
1.首先导入所需要的jar包:
2.在src目录下创建jdbc.properties 配置文件:
1 | username=root |
3.在com.bookmall.utils下创建 JdbcUtils 类:
1 | package com.bookmall.utils; |
4.在com.bookmall.test包下创建JdbcUtilsTest类,测试是否连接成功:
1 | package com.bookmall.test; |
五、编写BaseDao
1.导入DBUtils 的jar包:
2.在com.bookmall.dao.impl包下创建BaseDao抽象类:
1 | package com.bookmall.dao.impl; |
六、编写UserDao接口并测试
1.在com.bookmall.dao包下编写UserDao 接口
1 | package com.bookmall.dao; |
2.在com.bookmall.dao包下编写UserDao接口实现类UserDaoImpl
1 | package com.book.dao.impl; |
3.在com.bookmall.test包下创建UserDaoImplTest测试类(UserDaoImpl类下按ctrl+shift+t快速创建测试类),测试UserDaoImpl类中的方法。
1 | package com.bookmall.test; |
七、编写UserService并测试
1.在com.bookmall.service包下创建UserService接口
1 | package com.bookmall.service; |
2.在com.bookmall.service.impl创建UserService接口实现类UserServiceImpl
1 | package com.bookmall.service.impl; |
3.在com.bookmall.test包下创建测试类UserServiceImplTest,测试UserServiceImpl中的方法
1 | package com.bookmall.test; |
八、编写Web层
1.实现注册功能
在com.bookmall.web中创建RegistServlet类
在web.xml文件中配置文件路径
1 | <servlet> |
1 | package com.bookmall.web; |
2.实现登录功能
在com.bookmall.web中创建LogintServlet类
在web.xml文件中配置文件路径
1 | <servlet> |
1 | package com.bookmall.web; |
九、优化代码
1.将多个页面中重复的代码抽取出来:
写入单独的jsp文件中
footer.jsp
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> |
header.jsp
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> |
login_success_menu.jsp
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> |
manage_menu.jsp
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> |
采用静态包含的方式替换重复的代码:
1 | <%-- 静态包含 页脚内容--%> |
1 | <%-- 静态包含 base标签、css样式、jquery文件--%> |
1 | <%-- 静态包含 成功之后的菜单--%> |
1 | <%-- 静态包含 管理菜单--%> |
2.登录、注册错误提示以及表单回显
LoginServlet.java
1 | public class LoginServlet extends HttpServlet { |
login.jsp
1 | <div class="msg_cont"> |
1 | <input class="itxt" type="text" placeholder="请输入用户名" |
RegistServlet.java
1 | public class RegistServlet extends HttpServlet { |
regist.jsp
1 | <span class="errorMsg"> |
1 | <input class="itxt" type="text" placeholder="请输入用户名" |
1 | <input class="itxt" type="text" placeholder="请输入邮箱地址" autocomplete="off" tabindex="1" |
3.将LoginServlet和RegistServlet合并为UserServlet
1 | public class UserServlet extends HttpServlet { |
login.jsp
regist.jsp
4.使用反射优化大量else if 代码
1 |
|
5.抽取BaseServlet
1 | package com.bookmall.web; |
1 | package com.bookmall.web; |
6.数据的封装和抽取 BeanUtils的使用
BeanUtils工具类,可以一次性的把所有请求的参数注入导JavaBean中
1、导入需要的jar 包:
commons-beanutils-1.8.0.jar
commons-logging-1.1.1jar
2、使用BeanUtils类方法实现注入
1 | package com.bookmall.utils; |
UserServlet.java
1 | // 将请求参数一次性封装到user对象中 |
7.使用EL表达式修改表单回显
login.jsp
1 | <%-- |
1 | <%-- |
regist.jsp
1 | <%-- |
1 | <%-- |
1 | <%-- |
十、图书模块
1.创建图书模块的数据库表
1 | USE bookmall; |
2.编写图书模块的JavaBean对象
1 | package com.bookmall.bean; |
3.编写图书模块的DAO并测试
1 | package com.bookmall.dao.impl; |
1 | package com.bookmall.test; |
4.编写图书模块的Service并测试
1 | package com.bookmall.service.impl; |
1 | package com.bookmall.test; |
5.编写图书模块的Web层,和页面联调测试
1、实现展示全部图书
在BookServlet.java中添加list()方法用于展示全部图书信息:
1 | private BookService bookService = new BookServiceImpl(); |
修改图书管理页面的跳转地址:
利用JSTL标签库遍历图书信息在jsp页面中输出:
1、导入JSTL标签库的jar包
taglibs-standard-impl-1.2.1.jar
taglibs-standard-spec-1.2.1.jar
2、在book_manager.jsp中编写遍历图书信息的代码
1 | <c:forEach items="${requestScope.books}" var="book"> |
2、实现添加图书
在BookServlet中添加add()方法用于添加图书:
1 | protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
修改book_edit.jsp:
3、实现删除图书
在BookServlet中添加delete()方法:
1 | protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
修改book_manager.jsp:
添加确认删除提示:
给a标签添加class属性用于对标签选择
给a标签绑定单击事件:
1 | <%-- 给删除按钮绑定单击事件 用于删除操作的确认 --%> |
4、实现修改图书
在bookServlet中添加getBook()用于获取要修改图书的信息:
1 | protected void getBook(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
修改book_edit.jsp让数据回显:
在BookServlet中添加update()方法:
1 | protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
在book_edit.jsp中添加隐藏域用于回传修改图书所需要的id值:
图书信息并没有发生修改的原因:
book_edit.jsp页面中既要进行添加add操作,又要进行修改update操作,最终进行何种操作是根据一个隐藏域决定的,因此需要动态修改隐藏域:在请求发起时附带上要执行操作的值,并注入隐藏域中。
传入update参数:
传入add参数:
注入隐藏域:
5、实现图书的分页
创建Page对象:
1 | package com.bookmall.bean; |
在BookServlet中添page()用于处理分页:
1 | protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
在BookService中添加page(pageNo,pageSize) 获取page对象:
1 | /** |
在BookServiceImpl中实现page(pageNo,pageSize):
1 |
|
在BookDao中添加queryForPageTotal()和queryForItems()方法:
1 | /** |
在BookDaoImpl中实现queryForPageTotal()和queryForItems()方法:
1 |
|
修改manage_menu.jsp页面显示分页后的内容:
修改book_manage.jsp页面,让下方显示页面跳转的功能按键:
1 | <script type="text/javascript"> |
修改hesd.jsp 将basePath保存至pageContext域中:供指定页面跳转时使用
1 | <div id="page_nav"> |
修改增删改操作的重定向地址并传入pageNo参数:
在book_manager.jsp传入页码pageNo:
在book_edit.jsp中添加隐藏域用于传递pageNo给BookServlet:
前台图书的分页展示:|
web目录下的index.jsp只负责转发:
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> |
创建ClientBookServlet用于处理前台的分页请求:
1 | package com.bookmall.web; |
在web目录的/page/client/路径下创建index.jsp用于显示前台图书信息:
1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> |
抽取分页:
在Page对象中添加url属性以及相应的get 和set方法:
分别在BookServlet和ClientBookServlet中设置url属性值:
分别将index.jsp和book_manager.jsp中出现的相应的地址值替换为${requestScope.page.url}
在/pages/common/下创建page_nav.jsp用于提取分页代码:
1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> |
在index.jsp和book_mansger.jsp中的分页代码替换成静态包含代码:
1 | <%@include file="/pages/common/page_nav.jsp"%> |
6、实现价格区间的搜索功能:
在ClientBookClient中添加pageByPrice()方法用于处理搜索请求:
1 | protected void pageByPrice(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
在BookService中添加pageByPrice(pageNo,pageSize,min,max)方法:
1 | /** |
在BookServiceImpl中实现pageByPrice(pageNo,pageSize,min,max)方法:
1 |
|
在BookDao中添加queryForPageTotalCountByPrice(int min, int max)和queryForItemsByPrice(int begin, int pageSize, int min, int max)方法:
1 | /** |
在BookDaoImpl中实现这两种方法:
1 |
|
修改index.jsp向服务器提交搜索请求:
1 | <div class="book_cond"> |
十一、保存用户登录之后的信息
在UserServlet添加保存用户登录信息到Session域中的代码:
在login_success_menu.jsp中 显示用户姓名:
修改index.jsp的菜单显示:
1 | <div> |
注意:
固定相对路径跳转使用的地址必须是相对路径,否则在进行跳转时Tomcat会创建一个新的Session,造成Session会话信息丢失!
十二、注销登录
在userServlet中添加logout()方法用于处理注销请求:
1 | protected void logout(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
修改jsp页面的跳转地址:
十三、使用验证码解决表单的重复提交
表单重复提交有三种常见的情况:
一:提交完表单。服务器使用请求转来进行页面跳转。这个时候,用户按下功能键F5,就会发起最后一次的请求。造成表单重复提交问题。解决方法:使用重定向来进行跳转。
二:用户正常提交服务器,但是由于网络延迟等原因,迟迟未收到服务器的响应,这个时候,用户以为提交失败,
就会着急,然后多点了几次提交操作,也会造成表单重复提交。
三:用户正常提交服务器。服务器也没有延迟,但是提交完成后,用户回退浏览器。重新提交。也会造成表单重复
提交。
1.导入谷歌验证码的jar包:kaptcha-2.3.2.jar
2.在web.xml中配置用于访问生成验证码的Servlet程序的地址
1 | <servlet> |
3.在表单中使用img标签显示验证码图片
1 | <label>验证码:</label> |
4.在服务端中获取生成的验证码并于与客户端发送过来的验证码比较
5.给验证码图片绑定单击事件用于刷新验证码:
1 | // 给验证码图片绑定单击事件 |
十四、购物车模块
1、创建购物车对象
1 | public class Cart { |
2、创建购物车商品项
1 | public class CartItem { |
3、CartServlet用于处理商品的添加、删除、清空和修改数量
1 | public class CartServlet extends BaseServlet { |
4、购物车页面的展示
1 | <script type="text/javascript"> |
5、修改首页
1 | // 添加到购物车 |
1 | <div class="book_add"> |
6、首页购物车数据回显
在addItem()中将添加的图书信息保存到session域中:
在首页显示需要的信息:
1 | <span>您的购物车中有<span style="color: blue">${sessionScope.cart.totalCount}</span>件商品</span> |
十五、订单模块
1、创建Order 与OrderItem对象
1 | public class Order { |
1 | public class OrderItem { |
2、创建OrderDao接口并实现接口中的方法
1 | public interface OrderDao { |
1 | public class OrderDaoImpl extends BaseDao implements OrderDao { |
3、创建 OrderItemDao接口并实现其方法
1 | public interface OrderItemDao { |
1 | public class OrderItemDaoImpl extends BaseDao implements OrderItemDao { |
4、创建OrderService并实现其中的方法
1 | public interface OrderService { |
1 | public class OrderServiceImpl implements OrderService { |
5、创建OrderServlet并添加相应的功能
1 | public class OrderServlet extends BaseServlet { |
5、调整jsp页面
1.修改购物车页面中去结算的跳转地址
2.在order.jsp中显示当前用户的订单信息
1 | <table> |
4.在order_detail.jsp中显示订单的详细信息
1 | <table> |
5.修改首页的后台管理中订单管理的跳转地址
6.在订单管理中显示所有的订单信息
1 | <table> |
十六、使用Filter实现权限检查
1 | package com.bookmall.filter; |
1 | <filter> |
十七、使用Filter和TheadLocal组合管理事务
修改JdbcUtils:
创建一个ThreadLocal对象,用于将获取的连接与当前线程关联:
修改getConnection():
1 | public static Connection getConnection() { |
添加提交并关闭连接的方法以及回滚并关闭连接的方法:
1 | /** |
修改BaseDao,BaseServlet:
1、将所有方法中的关闭连接操作删除,用于保证所用操作都使用同一个连接;
2、在每个方法中都添加抛出异常的语句,提供给执行相应操作的Servlet程序捕获,用于回滚。
使用Filter过滤器为所用的Service方法添加try-catch:
1 | package com.bookmall.filter; |
1 | <filter> |
将所有异常同一交给Tomcat,让Tomcat展示友好的错误信息页面:
配置web.xml
1 | <!-- 配置服务器出错后,自动跳转的页面--> |
十八、使用Ajax判断用户名是否可用
1 | // 给用户名输入框绑定失去焦点事件 |
在UserServlet中添加ajaxExisUsername()
1 | /** |
十九、使用Ajax修改把商品添加到购物车
1 | /** |
1 | var bookid = $(this).attr("bookid");// 获取选中元素的属性值 |
1 | <span>您的购物车中有<span id="cartTotalCount" style="color:red">${sessionScope.cart.totalCount}</span>件商品</span> |