第一阶段:表单验证
验证用户名:必须由字母,数字下划线组成,并且长度在5-12位
验证密码:必须由字母,数字下划线组成,并且长度为5-12位
验证确认密码:和密码相同
邮箱验证:xxxxx@xxx.com
验证码:现在只需要验证用户已输入,因为还没将到服务器,验证码生成。
1、新建一个模块
2、把书城的静态资源拷贝到模块工程下
1 | <script type="text/javascript"> |
第二阶段:用户注册和登录
1、JavaEE项目的三层架构
分层的目的是为了解耦,解耦就是为了降低代码的耦合度,方便项目后期的维护和升级。
1 | web层 com.lxg.web/servlet/controller |
2、编码环节
1、先创建书城需要的数据库和表
1 | drop database if EXISTS book; |
2、编写数据库表对应的JavaBean对象
1 | package com.lxg.domain; |
3、编写工具类JdbcUtils
1 | package com.lxg.utils; |
测试
1 |
|
4、编写BaseDao
1 | package com.lxg.dao; |
5、编写UserDao和测试
1 | package com.lxg.test; |
6、编写UserService和测试
1 | package com.lxg.test; |
7、编写web层
1、用户注册
1 | 需求如下: |
1 | package com.lxg.web; |
2、用户登录
1 | 需求如下: |
1 | package com.lxg.web; |
3、IDEA中的Debug调试的使用
1 | Debug调试代码,首先需要两个元素:断点+Debug启动服务器 |
测试工具栏:
变量窗口,它可以查看当前方法范围内所有有效变量
方法调用窗口
1 | 1、方法调用栈可以查看当前线程有哪些方法调用信息 |
其他常用调试相关按钮:
第三阶段:优化
a:页面jsp动态化
- 在html页面顶行添加page指令
- 修改文件后缀名为:.jsp
3.使用idea搜索替换.html为.jsp
CTRL+SHIF+R:或者CTRL+R
b:抽取页面相同的内容
c:登录,注册错误提示以及表单回显
在Servlet后端代码中将用户信息保存进域对象,
在jsp前端页面代码中使用EL表达式获取信息并显示
d:BaseServlet的抽取
在实际的项目开发中,一个模块,一般只使用一个Servlet程序。
LoginServlet和RegistServle优化为UserServlet:
1 | package main.java.com.lxg.web; |
doPost还可以继续优化为:
1 | String action = req.getParameter("action"); |
如若系统又有其他模块,这个代码可以抽取出来变成BaseServlet
e:数据的封装和抽取BeanUtils的使用
BeanUtils工具类,它可以一次性的把请求的参数注入到javaBean中。
BeanUtils不是jdk的类,是第三方的工具类,所以需要导包
导入需要的jar包:
commons-beanutils-1.8.0.jar
commons-logging-1.1.1.jar使用BeanUti类方法实现注入
1 | package main.java.com.lxg.utils; |
1 | //给参数注入值 |
CTRL+ALT+T快捷键:
第四阶段:使用EL表达式修改表单回显(上面已修改)
第五阶段:图书模块
1、MVC概念
1 | MVC全称:Model模型、View视图、Controller控制器 |
MVC的作用还是为了降低耦合,让代码合理分层,方便后期升级和维护。
2、图书模块
2.1、编写图书模块的数据库表
2.2、编写图书模块的JavaBean
1 | package main.java.com.lxg.domain; |
2.3、编写图书模块的Dao和测试Dao
1 | package main.java.com.lxg.dao; |
1 | package main.java.com.lxg.dao.impl; |
生成测试快捷键:CTRL+SHIFT+T
2.4、编写图书模块的Service和测试Service
1 | package main.java.com.lxg.service; |
1 | package main.java.com.lxg.service.impl; |
2.5、编写图书模块的Web层,和页面联调测试
BookServlet:
1 | package main.java.com.lxg.web; |
需要给BaseServlet加上doGet方法才可处理get请求
1 |
|
实现展示所有图书功能:
使用jstl标签遍历获取数据显示在前端页面:
1 | <c:forEach items="${requestScope.books}" var="book"> |
前后台的介绍:
实现添加图书功能:
请求转发定位到工程目录
请求重定向定位到端口号
1 | protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
实现图书删除功能:
1 | <script type="text/javascript"> |
1 | protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
1 | <td><a class="deleteClass" href="manager/bookServlet?action=delete&id=${book.id}">删除</a></td> |
实现图书修改功能:
获取前端页面数据:
1 | protected void getBook(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
回显数据:
1 | <tr> |
保存修改:
1 | <%--<input type="hidden" name="action" value="${param.method}">--%> |
1 | <%--<td><a href="pages/manager/book_edit.jsp?method=add">添加图书</a></td>--%> |
1 | <%--<td><a href="manager/bookServlet?action=getBook&id=${book.id}&method=update">修改</a></td>--%> |
1 | protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
3、图书分页
分页功能分析
分页模型Page对象的创建
分页初步实现
首页,上一页,末页的实现
跳转到指定页码的功能
数据边界有效的检验
分页条页码的显示(显示5个连续的页码,而且当前页码在中间,除了当前页码之外,每个页码都可以点击跳转到相应的指定页面
修改分页对原来添加修改删除功能的影响
4、前台分页
1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> |
根据价格区间查询数据并分页:
第六阶段:登录登出
1、登录
a、显示用户名
2、登出
a、注销用户
1、销毁session中用户登录的信息(或者销毁session)
2、重定向到首页或者登录界面
3、表单重复提交
有三种常见情况:
1 | 1、提交完表单,服务器使用请求转发来进行页面跳转,这个时候用户按下F5功能键,就会发起最后一次的请求,造成表单重复提交问题。 |
a、验证码
验证码解决表单重复提交的底层原理
b、谷歌kaptcha图片验证码的使用
使用步骤如下:
1 | 1、导入谷歌验证码的jar包(kaptcha-2.3.2.jar) |
4、购物车模块
1、编写购物车模型
2、加入购物车功能的实现
3、购物车的展示
4、删除购物车商品项的功能
5、清空购物车
6、修改商品数量
7、加入购物车提醒功能
5、订单模块
1、创建数据库表
2、编写对应实体类
3、编写dao和测试dao
4、编写service和测试service
5、配置web.xml
6、编写OrderServlet
7、修改页面
第七阶段:权限检查
1、使用过滤器拦截
2、ThreadLocal的使用
1 | 它可以解决多线程的数据安全问题 |
3、使用Filter和ThreadLocal组合管理事务
1、使用ThreadLocal确保所有操作对象都使用同一个连接对象
2、使用Filter统一给所有Service方法都加上try—catch,来实现事物的管理
3、将所有异常都统一交给Tomcat,让Tomcat展示友好的错误信息页面
1 | 在web.xml配置错误页面跳转 |
第八阶段:AJAx
1、使用Ajax验证用户名是否可用
2、使用ajax修改加入购物车功能
第九阶段:
1、库存问题
2、其他模块
1 | var msg = $(this).attr('orderMsg'); |