需求:
验证用户名:必须由字母,数字下划线组成,并且长度为 5 到 12 位
验证密码:必须由字母,数字下划线组成,并且长度为 5 到 12 位
验证确认密码:和密码相同
邮箱验证:xxxxx@xxx.com
验证码:现在只需要验证用户已输入。
代码:
- // 页面加载完成之后
- $(function () {
- // 给注册绑定单击事件
- $("#sub_btn").click(function () {
- // 验证用户名:必须由字母,数字下划线组成,并且长度为 5 到 12 位
- // 1 获取用户名输入框里的内容
- var username = $("#username").val();
-
- // 2 创建正则表达式对象
- var usernamePatt = /^\w{5,12}$/;
-
- // 3 使用 test 方法验证
- if (!usernamePatt.test(username)) {
- // 4 提示用户结果
- $("span.errorMsg").text("用户名不合法!");
- return false;
- }
-
- // 验证密码:必须由字母,数字下划线组成,并且长度为 5 到 12 位
- // 1 获取用户密码输入框里的内容
- var password = $("#password").val();
-
- // 2 创建正则表达式对象
- var passwordPatt = /^\w{5,12}$/;
-
- // 3 使用 test 方法验证
- if (!passwordPatt.test(password)) {
- // 4 提示用户结果
- $("span.errorMsg").text("密码不合法!");
- return false;
- }
-
- // 验证确认密码:和密码相同
- // 1 获取正确密码输入框里的内容
- var repwd = $("#repwd").val();
-
- // 2 与密码相比较
- if (repwd != password) {
- // 4 提示用户
- $("span.errorMsg").text("确认密码与密码不一致!");
- return false;
- }
-
- // 邮箱验证:xxxxx@xxx.com
- // 1 获取邮箱里的内容
- var email = $("#email").val();
- // 2 创建正则表达式对象
- var emailPatt = /^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/;
- // 3 用test方法验证
- if (!emailPatt.test(email)) {
- $("span.errorMsg").text("邮箱格式不正确!");
- return false;
- }
-
- // 验证码:现在只需要验证用户已输入。因为还没讲到服务器。验证码生成。
- // 1.获取验证码里面的内容
- var code = $("#code").val();
- // 2.去掉验证码前后空格
- code = $.trim(code);
- //3.判断全掉空格后的验证码是否为空
- if (code == null || code == "") {
- // 提示用户
- $("span.errorMsg").text("验证码不能为空!");
- return false;
- }
- });
-
- // 给验证码绑定单击事件
- $("#code_img").click(function () {
- // 在事件响应的 function 函数中有一个 this 对象。
- // 这个 this 对象,是当前正在响应事件的 dom 对象
- // src 属性表示验证码 img 标签的 图片路径。它可读,可写
- this.src="kaptcha.jpg?id=" + new Date();
- });
- });

分层的目的是为了解耦。解耦就是为了降低代码的耦合度。方便项目后期的维护和升级。
web 层com.chenyixin.web/servlet/controllerservice 层com.chenyixin.service Service 接口包com.chenyixin.service.impl Service 接口实现类dao 持久层com.chenyixin.dao Dao 接口包com.chenyixin.dao.impl Dao 接口实现类实体 bean 对象com.chenyixin.pojo/entity/domain/bean JavaBean 类测试包com.chenyixin.test/junit工具类com.chenyixin.util

思路:
1.创建数据库book
2.切换数据库到book
3.创建表t_user,用于存储用户信息
4.插入一条数据进行测试
代码:
- CREATE DATABASE book;
- USE book;
-
- CREATE TABLE t_user(
- id INT PRIMARY KEY AUTO_INCREMENT,
- `username` VARCHAR(25) NOT NULL UNIQUE,
- `password` VARCHAR(32) NOT NULL,
- email VARCHAR(200)
- );
-
- INSERT INTO t_user(`username`,`password`,email)
- VALUES('admin','admin','admin@123');
-
- SELECT * FROM t_user;
思路:在pojo中编写一个User类
代码:(构造器与set、get、toString略)
- public class User {
- private Integer id;
- private String username;
- private String password;
- private String email
- }
druid-1.1.9.jarmysql-connector-java-8.0.27.jar以下是测试需要:hamcrest-core-1.3.jarjunit-4.12.jar
- username=root
- password=root
- url=jdbc:mysql://localhost:3306/book
- driverClassName=com.mysql.jdbc.Driver
- initialSize=5
- maxActive=10
思路:
1.在utils包中创建JdbcUtils类,在其静态代码块中创建数据库连接
2. 编写 获取数据库连接的方法
3.编写 关闭数据可连接的方法
代码:
- public class JdbcUtils {
- private static DruidDataSource dataSource;
-
- // 在静态代码块中创建数据库连接
- static {
- try {
- // 获取配置文件jdbc.properties对象
- Properties properties = new Properties();
-
- //读取jdbc.properties属性配置文件
- InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
-
- //从流中加载数据
- properties.load(inputStream);
-
- //创建数据库连接池
- dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- /**
- * 获取数据库连接池中的连接
- *
- * @return 如果返回 null,说明获取连接失败
有值就是获取连接成功 - */
- public static Connection getConnection() {
- Connection conn = null;
- try {
- conn = dataSource.getConnection();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- return conn;
- }
-
- /**
- * 关闭连接,放回数据库连接池
- *
- * @param connection 放入要关闭的连接对象
- */
- public static void close(Connection connection) {
- try {
- if (connection != null) {
- connection.close();
- }
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
在tset包中创建JdbcUtilsTest 进行测试
- public class JdbcUtilsTest {
- public static void main(String[] args) {
- for (int i = 0; i < 100; i++) {
- Connection conn = JdbcUtils.getConnection();
- System.out.println(conn);
- JdbcUtils.close(conn);
- }
- }
- }
思路:
1.在dao包中创建BaseDao,并在其类中创建DbUtils 操作数据库的对象
2.编写update方法用于对数据库的增删改
3.创建 查询返回一个 javaBean 的 sql 语句 的方法
4.创建 查询返回多个 javaBean 的 sql 语句 的方法
5.创建 执行返回一行一列的 sql 语句 的方法
- public abstract class BaseDao {
- private final QueryRunner queryRunner = new QueryRunner();
-
-
- /**
- * 用来执行:Insert\Update\Delete 语句
- *
- * @param sql 传入要执行的sql语句
- * @param args 参数列表
- * @return 返回-1表示update失败,否则成功
- */
- public int update(String sql, Object... args) {
- Connection conn = JdbcUtils.getConnection();
- try {
- return queryRunner.update(conn, sql, args);
- } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- JdbcUtils.close(conn);
- }
- return -1;
- }
-
-
- /**
- * 查询返回一个 javaBean 的 sql 语句
- * @param type 返回的对象类型
- * @param sql 执行的 sql 语句
- * @param args sql 对应的参数值
- * @param
返回的类型的泛型 - * @return 若返回为null,则查看失败
- */
- public
T queryForOne(Class type, String sql, Object... args) { - Connection conn = JdbcUtils.getConnection();
- try {
- return queryRunner.query(conn, sql, new BeanHandler
(type), args); - } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- JdbcUtils.close(conn);
- }
-
- return null;
- }
-
- /**
- * 查询返回多个 javaBean 的 sql 语句
- *
- * @param type 返回的对象类型
- * @param sql 执行的 sql 语句
- * @param args sql 对应的参数值
- * @param
返回的类型的泛型 - * @return 若返回为null, 则查看失败
- */
- public
List queryForList(Class type, String sql, Object... args) { - Connection conn = JdbcUtils.getConnection();
- try {
- queryRunner.query(conn, sql, new BeanListHandler<>(type), args);
- } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- JdbcUtils.close(conn);
- }
- return null;
- }
-
- /**
- * 执行返回一行一列的 sql 语句
- * @param sql 执行的 sql 语句
- * @param args sql对应的参数
- * @return 若返回为null, 则查看失败
- */
- public Object queryForSingleValue(String sql,Object... args) {
- Connection conn = JdbcUtils.getConnection();
- try {
- queryRunner.query(conn,sql,new ScalarHandler(),args);
- } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- JdbcUtils.close(conn);
- }
- return null;
- }
- }
思路:
1.在Dao包中编写UserDao接口
2.在UserDao接口中编写queryUserByUsername,
queryUserByUsernameAndPassword,saveUser抽象方法
3.在Dao.impl包中编写UserDaoImpl类,并继承BaseDao,实现UserDao
4.在UserDaoImpl中编写重写UserDao接口中的方法
5.在test包中创建UserDaoTest进行测试
BaseDao 接口:
- public abstract class BaseDao {
- private final QueryRunner queryRunner = new QueryRunner();
-
-
- /**
- * 用来执行:Insert\Update\Delete 语句
- *
- * @param sql 传入要执行的sql语句
- * @param args 参数列表
- * @return 返回-1表示update失败,否则成功
- */
- public int update(String sql, Object... args) {
- Connection conn = JdbcUtils.getConnection();
- try {
- return queryRunner.update(conn, sql, args);
- } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- JdbcUtils.close(conn);
- }
- return -1;
- }
-
-
- /**
- * 查询返回一个 javaBean 的 sql 语句
- * @param type 返回的对象类型
- * @param sql 执行的 sql 语句
- * @param args sql 对应的参数值
- * @param
返回的类型的泛型 - * @return 若返回为null,则查看失败
- */
- public
T queryForOne(Class type, String sql, Object... args) { - Connection conn = JdbcUtils.getConnection();
- try {
- return queryRunner.query(conn, sql, new BeanHandler
(type), args); - } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- JdbcUtils.close(conn);
- }
-
- return null;
- }
-
- /**
- * 查询返回多个 javaBean 的 sql 语句
- *
- * @param type 返回的对象类型
- * @param sql 执行的 sql 语句
- * @param args sql 对应的参数值
- * @param
返回的类型的泛型 - * @return 若返回为null, 则查看失败
- */
- public
List queryForList(Class type, String sql, Object... args) { - Connection conn = JdbcUtils.getConnection();
- try {
- queryRunner.query(conn, sql, new BeanListHandler<>(type), args);
- } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- JdbcUtils.close(conn);
- }
- return null;
- }
-
- /**
- * 执行返回一行一列的 sql 语句
- * @param sql 执行的 sql 语句
- * @param args sql对应的参数
- * @return 若返回为null, 则查看失败
- */
- public Object queryForSingleValue(String sql,Object... args) {
- Connection conn = JdbcUtils.getConnection();
- try {
- queryRunner.query(conn,sql,new ScalarHandler(),args);
- } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- JdbcUtils.close(conn);
- }
- return null;
- }
- }
UserDaoImpl 类:
- public class UserDaoImpl extends BaseDao implements UserDao {
- @Override
- public User queryUserByUsername(String username) {
- String sql = "select username,password,email from t_user where username=?";
- return queryForOne(User.class,sql,username);
- }
-
- @Override
- public User queryUserByUsernameAndPassword(String username, String password) {
- String sql = "select username,password,email from t_user where username=? and password = ?";
- return queryForOne(User.class,sql,username,password);
- }
-
- @Override
- public int saveUser(User user) {
- String sql = "insert into t_user(username,password,email) values(?,?,?)";
- return update(sql,user.getUsername(),user.getPassword(),user.getEmail());
- }
- }
测试类:
- public class UserDaoTest {
- UserDao userDao = new UserDaoImpl();
-
- @Test
- public void queryUserByUsername() {
- if (userDao.queryUserByUsername("admin134") == null) {
- System.out.println("用户名可用!");
- } else {
- System.out.println("用户名已存在!");
- }
- }
-
- @Test
- public void queryUserByUsernameAndPassword() {
- if (userDao.queryUserByUsernameAndPassword("admin", "admin1234") == null) {
- System.out.println("用户名或密码错误,登录失败");
- } else {
- System.out.println("查询成功");
- }
- }
-
- @Test
- public void saveUser() {
- System.out.println( userDao.saveUser(new User(null,"zhangsan", "123456", "zhangsan@qq.com")));
- }
- }
思路:
1.在service包中创建UserService 接口,该接口含有:
login 登录方法
regist 注册方法
existsUsername 检查用户名是否存在的方法
2.在service.impl包中UserServiceImpl类,并实现UserService 接口的所有方法
3.在test包中创建UserServiceTest类进行测试
UserService 接口:
- public interface UserService {
- /**
- * 登录
- * @param user 要登陆的用户
- * @return 如果返回null,说明登录失败,返回有值,则登录成功
- */
- public User login(User user);
-
- /**
- * 注册
- * @param user 注册的用户
- */
- public void regist(User user);
-
- /**
- * 检查用户名是否存在
- * @param username 用户名
- * @return 返回true表示用户名已经存在,返回false表示用户名可用
- */
- public boolean existsUsername(String username);
- }
UserServiceImpl类:
- public class UserServiceImpl implements UserService {
- UserDao userDao = new UserDaoImpl();
- @Override
- public User login(User user) {
- return userDao.queryUserByUsernameAndPassword(user.getUsername(), user.getPassword());
- }
-
- @Override
- public void regist(User user) {
- userDao.saveUser(user);
- }
-
- @Override
- public boolean existsUsername(String username) {
- return userDao.queryUserByUsername(username) != null;
- }
- }
UserServiceTest类测试:
-
- public class UserServiceTest {
- UserService userService = new UserServiceImpl();
-
- @Test
- public void login() {
- System.out.println(userService.login(new User(null, "aaa", "666666", null)));
- }
-
- @Test
- public void regist() {
- userService.regist(new User(null, "aaa", "666666", "bbj168@qq.com"));
- }
-
- @Test
- public void existsUsername() {
- if (userService.existsUsername("aaa")) {
- System.out.println("用户名已存在!");
- } else {
- System.out.println("用户名可用!");
- }
- }
- }
1、添加 base 标签<base href="http://localhost:8080/book/">
2、修改 base 标签对页面中所有相对路径的影响(浏览器 F12,哪个报红,改哪个)以下是几个修改的示例:<link type="text/css" rel="stylesheet" href="static/css/style.css" ><script type="text/javascript" src="static/script/jquery-1.7.2.js">script>
3、修改注册表单的提交地址和请求方式![]()
需求:
1)访问注册页面2)填写注册信息,提交给服务器3)服务器应该保存用户4)当用户已经存在----提示用户注册 失败,用户名已存在5)当用户不存在-----注册成功
分析:
1.在web包中编写RegistServlet类 并继承 HttpServlet2、获取请求的参数3、检查 验证码是否正确正确4、检查 用户名是否可用可用调用 Service 保存到数据库不可用跳回注册页面不正确跳回注册页面
代码:
- public class RegistServlet extends HttpServlet {
- @Override
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- UserService userService = new UserServiceImpl();
- // 获取请求的参数
- String username = request.getParameter("username");
- String password = request.getParameter("password");
- String email = request.getParameter("email");
- String code = request.getParameter("code");
- // 检查 验证码是否正确
- if (code.equalsIgnoreCase("abcde")) {
- // 正确 检查 用户名是否可用
- if (userService.existsUsername(username)) {
- // 不可用 跳回注册页面
- request.getRequestDispatcher("/pages/user/regist.html").forward(request,response);
- }else{
- // 可用 跳转到注册成功页面
- userService.regist(new User(null, username, password, email));
- request.getRequestDispatcher("/pages/user/regist_success.html").forward(request,response);
- }
-
- }else{
- // 不正确 跳回注册页面
- System.out.println("验证码[" + code + "]错误");
- request.getRequestDispatcher("/pages/user/regist.html").forward(request,response);
- }
- }
- }
xml代码略
1、添加 base 标签<base href="http://localhost:8080/book/">
2、修改 base 标签对页面中所有相对路径的影响(浏览器 F12,哪个报红,改哪个)以下是几个修改的示例:<link type="text/css" rel="stylesheet" href="static/css/style.css" ><script type="text/javascript" src="static/script/jquery-1.7.2.js">script>
3、修改 login.html 表单的提交地址和请求方式 需求如下:
1)访问登陆页面2)填写用户名密码后提交3)服务器判断用户是否存在4)如果登陆失败 --->>>> 返回用户名或者密码错误信息5)如果登录成功 --->>>> 返回登陆成功 信息
分析:
1. 在web包中编写 LoginServlet 类 并继承 HttpServlet2、获取请求的参数3、调用 userService.login()登录处理业务(检查用户名密码是否正确)正确跳到成功页面 login_success.html不正确跳回登录页面
- public class LoginServlet extends HttpServlet {
- private UserService userService = new UserServiceImpl();
-
- @Override
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
- // 获取请求的参数
- String username = request.getParameter("username");
- String password = request.getParameter("password");
-
- // 调用 userService.login()登录处理业务
- User loginUser = userService.login(new User(null,username, password,null));
-
- if (loginUser == null) {
- // 不正确 跳回登录页面
- request.getRequestDispatcher("/pages/user/login.html").forward(request, response);
- } else {
- // 正确 跳转到登录成功页面
- request.getRequestDispatcher("/pages/user/login_success.html").forward(request, response);
- }
- }
-
- }

- <%
- String basePath = request.getScheme() + "://" +
- request.getServerName() + ":" +
- request.getServerPort() +
- request.getContextPath() + "/";
-
- String basePath2 = request.getScheme() + "://" +
- request.getServerName() + ":" +
- request.getServerPort() +
- request.getContextPath() + "/";
- %>
- <html>
- <head>
- <title>Titletitle>
- <base href="<%=basePath%>">
- <link type="text/css" rel="stylesheet" href="static/css/style.css">
- <script type="text/javascript" src="static/js/script/jquery-1.7.2.min.js">script>
- head>
- <body>
- <div id="bottom">
- <span>
- 尚硅谷书城.Copyright ©2015
- span>
- div>
- body>
- <div>
- <span>欢迎<span class="um_span">韩总span>光临尚硅谷书城span>
- <a href="pages/order/order.jsp">我的订单a>
- <a href="index.jsp">注销a>
- <a href="index.jsp">返回a>
- div>
- <div>
- <a href="pages/manager/book_manager.jsp">图书管理a>
- <a href="pages/manager/order_manager.jsp">订单管理a>
- <a href="index.jsp">返回商城a>
- div>

表单要回显信息:

第一步:在注册和登录界面中编写隐藏域并修改请求地址
给 login.jsp 添加隐藏域和修改请求地址

给 tegist.jsp 页面添加隐藏域 action,和修改请求地址

第二步:创建UserServlet类,并将LoginServlet类与RegistSerlet类里的代码复制进去
- @WebServlet(name = "UserServlet", value = "/userServlet")
- public class UserServlet extends HttpServlet {
- private UserService userService = new UserServiceImpl();
-
-
- @Override
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- String action = request.getParameter("action");
- if ("login".equals(action)) {
- login(request, response);
- } else if ("regist".equals(action)) {
- regist(request, response);
- }
- }
-
- /**
- * 处理登录功能
- *
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- protected void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
- // 获取请求的参数
- String username = request.getParameter("username");
- String password = request.getParameter("password");
-
- // 调用 userService.login()登录处理业务
- User loginUser = userService.login(new User(null, username, password, null));
-
- if (loginUser == null) {
- // 不正确
- // 把错误信息,和回显的表单项信息,保存到Request域中
- request.setAttribute("msg", "用户名或密码错误!");
- request.setAttribute("username", username);
- // 跳回登录页面
- request.getRequestDispatcher("/pages/user/login.jsp").forward(request, response);
- } else {
- // 正确 跳转到登录成功页面
- request.getRequestDispatcher("/pages/user/login_success.jsp").forward(request, response);
- }
- }
-
- /**
- * 处理注册功能
- *
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- protected void regist(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- UserService userService = new UserServiceImpl();
- // 获取请求的参数
- String username = request.getParameter("username");
- String password = request.getParameter("password");
- String email = request.getParameter("email");
- String code = request.getParameter("code");
- // 检查 验证码是否正确
- if (code.equalsIgnoreCase("abcde")) {
- // 正确 检查 用户名是否可用
- if (userService.existsUsername(username)) {
- // 不可用
- request.setAttribute("msg", "用户名已存在!");
- request.setAttribute("email", email);
- // 跳回注册页面
- request.getRequestDispatcher("/pages/user/regist.jsp").forward(request, response);
- } else {
- // 可用 跳转到注册成功页面
- userService.regist(new User(null, username, password, email));
-
- request.getRequestDispatcher("/pages/user/regist_success.jsp").forward(request, response);
- }
-
- } else {
- // 不正确
- request.setAttribute("msg", "验证码错误!");
- request.setAttribute("username", username);
- request.setAttribute("email", email);
- // 跳回注册页面
- request.getRequestDispatcher("/pages/user/regist.jsp").forward(request, response);
- }
- }
-
-
- }
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- String action = request.getParameter("action");
- // 获取 action 业务鉴别字符串,获取相应的业务 方法反射对象
- try {
- Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
- // 调用目标业务 方法
- method.invoke(this, request, response);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }

创建BaseServlet抽象类,并继承UserServlet类等,将子类的doPost写到父类中,使其子类可以直接调用,不用再写一遍
- @WebServlet(name = "BaseServlet", value = "/BaseServlet")
- public abstract class BaseServlet extends HttpServlet {
- private UserService userService = new UserServiceImpl();
-
-
- @Override
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- String action = request.getParameter("action");
- // 获取 action 业务鉴别字符串,获取相应的业务 方法反射对象
- try {
- Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
- // 调用目标业务 方法
- method.invoke(this, request, response);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- public class WebUtils {
- public static
T copyParamToBean(Map value, T bean) { -
- try {
- // 把所有请求的参数都注入到 user 对象中
- BeanUtils.populate(bean,value);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return bean;
- }
- }
- CREATE TABLE t_book(
- `id` INT PRIMARY KEY AUTO_INCREMENT,
- `name` VARCHAR(100),
- `price` DECIMAL(11,2),
- `author` VARCHAR(100),
- `sales` INT,
- `stock` INT,
- `img_path` VARCHAR(200)
- );
测试表:
- ## 插入初始化测试数据
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , 'java从入门到放弃' , '国哥' , 80 , 9999 , 9 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , '数据结构与算法' , '严敏君' , 78.5 , 6 , 13 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , '怎样拐跑别人的媳妇' , '龙伍' , 68, 99999 , 52 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , '木虚肉盖饭' , '小胖' , 16, 1000 , 50 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , 'C++编程思想' , '刚哥' , 45.5 , 14 , 95 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , '蛋炒饭' , '周星星' , 9.9, 12 , 53 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , '赌神' , '龙伍' , 66.5, 125 , 535 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , 'Java编程思想' , '阳哥' , 99.5 , 47 , 36 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , 'JavaScript从入门到精通' , '婷姐' , 9.9 , 85 , 95 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , 'cocos2d-x游戏编程入门' , '国哥' , 49, 52 , 62 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , 'C语言程序设计' , '谭浩强' , 28 , 52 , 74 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , 'Lua语言程序设计' , '雷丰阳' , 51.5 , 48 , 82 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , '西游记' , '罗贯中' , 12, 19 , 9999 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , '水浒传' , '华仔' , 33.05 , 22 , 88 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , '操作系统原理' , '刘优' , 133.05 , 122 , 188 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , '数据结构 java版' , '封大神' , 173.15 , 21 , 81 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , 'UNIX高级环境编程' , '乐天' , 99.15 , 210 , 810 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , 'javaScript高级编程' , '国哥' , 69.15 , 210 , 810 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , '大话设计模式' , '国哥' , 89.15 , 20 , 10 , 'static/img/default.jpg');
-
- insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
- values(null , '人月神话' , '刚哥' , 88.15 , 20 , 80 , 'static/img/default.jpg');
-
-
-
- ## 查看表内容
- select id,name,author,price,sales,stock,img_path from t_book;
- public class Book {
- private Integer id;
- private String name;
- private String author;
- private BigDecimal price;
- private Integer sales;
- private Integer stock;
- private String img_path = "static/img/default.jpg";
-
- public Book() {
- }
-
- public Book(Integer id, String name, String author, BigDecimal price, Integer sales, Integer stock, String img_path) {
- this.id = id;
- this.name = name;
- this.author = author;
- this.price = price;
- this.sales = sales;
- this.stock = stock;
- if (img_path != null && "".equals(img_path)) {
- this.img_path = img_path;
- }
- }
-
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getAuthor() {
- return author;
- }
-
- public void setAuthor(String author) {
- this.author = author;
- }
-
- public BigDecimal getPrice() {
- return price;
- }
-
- public void setPrice(BigDecimal price) {
- this.price = price;
- }
-
- public Integer getSales() {
- return sales;
- }
-
- public void setSales(Integer sales) {
- this.sales = sales;
- }
-
- public Integer getStock() {
- return stock;
- }
-
- public void setStock(Integer stock) {
- this.stock = stock;
- }
-
- public String getImg_path() {
- return img_path;
- }
-
- public void setImg_path(String img_path) {
- if (img_path != null && "".equals(img_path)) {
- this.img_path = img_path;
- }
- }
-
- @Override
- public String toString() {
- return "Book{" +
- "id=" + id +
- ", name='" + name + '\'' +
- ", author='" + author + '\'' +
- ", price=" + price +
- ", sales=" + sales +
- ", stock=" + stock +
- ", img_path='" + img_path + '\'' +
- '}';
- }
- }
- public interface BookDao {
- int addBook();
-
- int deleteBook();
-
- int update();
-
- Book queryBookById();
-
- List
queryBooks(); - }
BookDaoImpl实现类:
- public class BookDaoImpl extends BaseDao implements BookDao {
- @Override
- public int addBook(Book book) {
- String sql = "insert into t_book(`name`,`author`,`price`,`sales`,`stock`,`img_path`) values(?,?,?,?,?,?)";
- return update(sql, book.getName(), book.getAuthor(), book.getPrice(),
- book.getSales(), book.getStock(), book.getImg_path());
- }
-
- @Override
- public int deleteBookById(Integer id) {
- String sql = "delete from t_book where id = ?";
- return update(sql,id);
- }
-
- @Override
- public int updateBook(Book book) {
- String sql = "update t_book set `name` = ?,`author` = ?,`price` = ?,`sales` = ?,`stock` = ?,`img_path` = ? where id = ?";
- return update(sql, book.getName(), book.getAuthor(), book.getPrice(),
- book.getSales(), book.getStock(), book.getImg_path(),book.getId());
- }
-
- @Override
- public Book queryBookById(Integer id) {
- String sql = "select `id`,`name`,`author`,`price`,`sales`,`stock`,`img_path` from t_book where id = ?";
- return queryForOne(Book.class,sql,id);
- }
-
- @Override
- public List
queryBooks() { - String sql = "select `id`,`name`,`author`,`price`,`sales`,`stock`,`img_path` from t_book";
- return queryForList(Book.class,sql);
- }
- }
测试:
- public class BookDaoTest {
- private BookDao bookDao = new BookDaoImpl();
-
- @Test
- public void addBook() {
- bookDao.addBook(new Book(null,"强哥好帅","chenyixin",new BigDecimal(123),999,999,null));
- System.out.println("添加成功");
- }
-
- @Test
- public void deleteBookById() {
- bookDao.deleteBookById(21);
- }
-
- @Test
- public void updateBook() {
- bookDao.updateBook(new Book(21, "大家都好帅", "佚名", new BigDecimal(123), 999, 999, null));
- }
-
- @Test
- public void queryBookById() {
- System.out.println(bookDao.queryBookById(21));
- }
-
- @Test
- public void queryBooks() {
- for (Book queryBook : bookDao.queryBooks()) {
- System.out.println(queryBook);
- }
- }
- }
BookService 接口:
- public interface BookService {
- public void addBook(Book book);
-
- public void delete(Integer id);
-
- public void update(Book book);
-
- public Book queryBookById(Integer id);
-
- public List
queryBooks(); - }
BookServiceImpl 实现类:
- public class BookServiceImpl implements BookService {
- private BookDao bookDao = new BookDaoImpl();
- @Override
- public void addBook(Book book) {
- bookDao.addBook(book);
- }
-
- @Override
- public void delete(Integer id) {
- bookDao.deleteBookById(id);
- }
-
- @Override
- public void update(Book book) {
- bookDao.updateBook(book);
- }
-
- @Override
- public Book queryBookById(Integer id) {
- return bookDao.queryBookById(id);
- }
-
- @Override
- public List
queryBooks() { - return bookDao.queryBooks();
- }
- }
测试:
-
- public class BookServiceTest {
- private BookService bookService = new BookServiceImpl();
-
- @Test
- public void addBook() {
- bookService.addBook(new Book(null,"强哥好帅","chenyixin",new BigDecimal(123),999,999,null));
- System.out.println("修改成功");
- }
-
- @Test
- public void delete() {
- bookService.delete(22);
- }
-
- @Test
- public void update() {
- bookService.update(new Book(22, "大家都好帅", "佚名", new BigDecimal(123), 999, 999, null));
- }
-
- @Test
- public void queryBookById() {
- System.out.println( bookService.queryBookById(22));
- }
-
- @Test
- public void queryBooks() {
- for (Book queryBook : bookService.queryBooks()) {
- System.out.println(queryBook);
- }
- }
- }
前后台的简单介绍

图解列表功能流程:

思路流程:
1.在manager_menu.jsp页面中修改【图书管理】请求地址2. 在web包中创建BookServlet类,并添加list方法3.修改 pages/manager/book_manager.jsp 页面的数据遍历输出
1.在manager_menu.jsp页面中修改【图书管理】请求地址

action=list 表示调用list方法 (反射)
2. 创建BookServlet 程序中,并添加 list 方法:
- @WebServlet(name = "BookServlet", value = "/manager/bookServlet")
- public class BookServlet extends BaseServlet {
- private BookService bookService = new BookServiceImpl();
-
- protected void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- //1 通过 BookService 查询全部图书
- System.out.println("进来了");
- List
books = bookService.queryBooks(); -
- //2 把全部图书保存到 Request 域中
- request.setAttribute("books", books);
-
- //3、请求转发到/pages/manager/book_manager.jsp 页面
- request.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(request,response);
- }
-
- }
注意:a标签是get请求,所以要在BaseSerlet中写doGet方法:
- protected void doGet(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- doPost(req, resp);
- }
3.修改 pages/manager/book_manager.jsp 页面的数据遍历输出
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>图书管理title>
- <%@include file="/pages/common/head.jsp" %>
- head>
- <body>
-
- <div id="header">
- <img class="logo_img" alt="" src="static/img/logo.gif">
- <span class="wel_word">图书管理系统span>
- <%@include file="/pages/common/manager_menu.jsp" %>
- div>
-
- <div id="main">
- <table>
- <tr>
- <td>名称td>
- <td>价格td>
- <td>作者td>
- <td>销量td>
- <td>库存td>
- <td colspan="2">操作td>
- tr>
- <c:forEach items="${requestScope.books}" var="book">
- <tr>
- <td>${book.name}td>
- <td>${book.price}td>
- <td>${book.author}td>
- <td>${book.sales}td>
- <td>${book.stock}td>
- <td><a href="pages/manager/book_edit.jsp">修改a>td>
- <td><a href="#">删除a>td>
- tr>
- c:forEach>
- <tr>
- <td>td>
- <td>td>
- <td>td>
- <td>td>
- <td>td>
- <td>td>
- <td><a href="book_edit.jsp">添加图书a>td>
- tr>
-
- table>
- div>
-
- <%@include file="/pages/common/footer.jsp" %>
- body>
- html>

问题说明:表单重复提交:
思路步骤:
1.在book_edit.jsp 页面添加隐藏域并修改form标签的action属性
2.在BookServlet中编写add方法
1.在book_edit.jsp 页面添加隐藏域并修改form标签的action属性

2.在BookServlet中编写add方法
- protected void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 1.获取请求的参数 封装成为Book对象
- Book book = WebUtils.copyParamToBean(request.getParameterMap(), new Book());
-
- // 2.调用BookServlet.addBook()保存图书
- bookService.addBook(book);
-
- // 3.使用重定向跳转到图书列表界面
- response.sendRedirect(request.getContextPath() + "/manager/bookServlet?action=list");
- }
步骤:
1. 修改删除的连接地址
2. 编写BookServlet 程序中的 delete 方法
3. 给删除添加确认提示操作
1. 修改删除的连接地址

- protected void delete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 1.获取请求参数的id,图书编号
- String id = request.getParameter("id");
- int i = WebUtils.parseInt(id, 0);
-
- // 2.调用bookServlet.delete方法,删除图书
- bookService.delete(i);
-
- // 3.重定向回图书列表管理页面
- response.sendRedirect(request.getContextPath() + "/manager/bookServlet?action=list");
- }
- public static int parseInt(String strId, int defaultValue) {
- try {
- return Integer.parseInt(strId);
- } catch (NumberFormatException e) {
- e.printStackTrace();
- }
- return defaultValue;
- }
- protected void getBook(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 1.获取图书编号
- String id = request.getParameter("id");
- int i = WebUtils.parseInt(id, 0);
-
- // 2.条用BookServlet.queryBookById(id),得到要修改的图书信息(book对象)
- Book book = bookService.queryBookById(i);
-
- // 3.把图书保存到Request域中
- request.setAttribute("book", book);
-
- // 4.把请求妆发到/pages/manager/book_edit.jsp页面
- request.getRequestDispatcher("/pages/manager/book_edit.jsp").forward(request,response);
- }
3. 在 book_edit.jsp 页面中显示修改的数据
- <div id="main">
- <form action="manager/bookServlet">
- <input type="hidden" name="action" value="add"/>
- <table>
- <tr>
- <td>名称td>
- <td>价格td>
- <td>作者td>
- <td>销量td>
- <td>库存td>
- <td colspan="2">操作td>
- tr>
- <tr>
- <td><input name="name" type="text" value="${requestScope.book.name}"/>td>
- <td><input name="price" type="text" value="${requestScope.book.price}"/>td>
- <td><input name="author" type="text" value="${requestScope.book.author}"/>td>
- <td><input name="sales" type="text" value="${requestScope.book.sales}"/>td>
- <td><input name="stock" type="text" value="${requestScope.book.stock}"/>td>
- <td><input type="submit" value="提交"/>td>
- tr>
- table>
- form>
-
-
- div>
- protected void update(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 1.获取请求参数,并封装成Book对象
- Book book = WebUtils.copyParamToBean(request.getParameterMap(), new Book());
-
- // 2.调用BookServlet.update(book)方法,修改图书
- bookService.update(book);
-
- // 3.重定向返回图书列表管理页面
- response.sendRedirect(request.getContextPath()+"/manager/bookServlet?action=list");
- }
5. 解决 book_edit.jsp 页面,即要实现添加,又要实现修改操作。
步骤:
1.修改manager_menu.jsp页面中 图书管理地址
2.编写page类
3.编写Bookservlet程序
4. 编写BookService程序
5. 编写BookDao程序
6. 测试BookDao程序
7. 测试BookService程序
8. 修改book_manager.jsp 页面
-
- /**
- * Page 是分页的模型对象
- * @param
是具体的模块的 javaBean 类 - */
- public class Page
{ - public static final Integer PAGE_SIZE = 4;
- // 当前页码
- private Integer pageNo;
- // 总页码
- private Integer pageTotal;
- // 总记录数
- private Integer pateTotalCount;
- // 每页显示数量
- private Integer pateSize = PAGE_SIZE;
- //当前页数据
- private List
items;
- protected void page(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 1.获取请求参数 pageNo 和 pageSize
- int pageNo = WebUtils.parseInt(request.getParameter("pageNo"), 1);
- int pageSize = WebUtils.parseInt(request.getParameter("pageSize"), Page.PAGE_SIZE);
-
- // 2.调用BookServlet.page(pageNo,pageSize),获得page对象
- Page
page = bookService.page(pageNo, pageSize); -
- // 3.将Page对象保存到Request域中
- request.setAttribute("page", page);
-
- // 4.请求转发到 /pages/manager/book_manager.jsp
- request.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(request, response);
- }
Page page(int pageNo, int pageSize);
BookServiceImpl实现类中的page方法:
- public Page
page(int pageNo, int pageSize) { - Page
page = new Page<>(); - // 设置 当前页码
- page.setPageNo(pageNo);
-
- // 设置 当前每页显示数量
- page.setPateSize(pageSize);
-
- // 求总记录数
- Integer pageTotalCount = bookDao.queryForPageTotalCount();
- // 设置总记录数
- page.setPateTotalCount(pageTotalCount);
-
- // 求总页码
- Integer pageTotal = pageTotalCount / pageSize;
- if ((pageTotalCount % pageSize) > 0) {
- pageTotal++;
- }
- // 设置总页码
- page.setPageTotal(pageTotal);
-
- // 求当前页面数据
- // 求页面开始索引
- Integer begin = (pageNo - 1) * pageSize;
- List
items = bookDao.queryForPageItems(begin, pageSize); - // 设置当前页面数据
- page.setItems(items);
-
- return page;
- }
5. 编写BookDao程序
Bookdao接口:
- Integer queryForPageTotalCount();
-
- List
queryForPageItems(Integer begin, int pageSize);
BookdaoImpl实现类:
- @Override
- public Integer queryForPageTotalCount() {
- String sql = "select count(*) from t_book";
- Number number = (Number) queryForSingleValue(sql);
- return number.intValue();
- }
-
- @Override
- public List
queryForPageItems(Integer begin, int pageSize) { - String sql = "select `id`,`name`,`author`,`price`,`sales`,`stock`,`img_path` from t_book limit ?,?";
- return queryForList(Book.class ,sql,begin,pageSize);
- }
6. 测试BookDao程序
- @Test
- public void queryForPageTotalCount() {
- System.out.println(bookDao.queryForPageTotalCount());
- }
-
- @Test
- public void queryForPageItems() {
- for (Book item : bookDao.queryForPageItems(8,4)) {
- System.out.println(item);
- }
- }
7. 测试BookService程序
- @Test
- public void page() {
- System.out.println(bookService.page(1,4));
- }
8. 修改book_manager.jsp 页面
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>图书管理title>
- <%@include file="/pages/common/head.jsp" %>
- head>
- <body>
-
- <div id="header">
- <img class="logo_img" alt="" src="static/img/logo.gif">
- <span class="wel_word">图书管理系统span>
- <%@include file="/pages/common/manager_menu.jsp" %>
-
- div>
-
- <div id="main">
- <table>
- <tr>
- <td>名称td>
- <td>价格td>
- <td>作者td>
- <td>销量td>
- <td>库存td>
- <td colspan="2">操作td>
- tr>
- <c:forEach items="${requestScope.page.items}" var="book">
- <tr>
- <td>${book.name}td>
- <td>${book.price}td>
- <td>${book.author}td>
- <td>${book.sales}td>
- <td>${book.stock}td>
- <td><a href="manager/bookServlet?action=getBook&id=${book.id}">修改a>td>
- <td><a class="deleteClass" href="manager/bookServlet?action=delete&id=${book.id}">删除a>td>
- tr>
- c:forEach>
- <tr>
- <td>td>
- <td>td>
- <td>td>
- <td>td>
- <td>td>
- <td>td>
- <td><a href="pages/manager/book_edit.jsp">添加图书a>td>
- tr>
- table>
- <div id="page_nav">
- <a href="#">首页a>
- <a href="#">上一页a>
- <a href="#">3a>
- 【${requestScope.page.pageNo}】
- <a href="#">5a>
- <a href="#">下一页a>
- <a href="#">末页a>
- 共${requestScope.page.pageTotal}页,${requestScope.page.pageTotalCount}条记录
- 到第<input value="4" name="pn" id="pn_input"/>页
- <input type="button" value="确定">
- div>
- div>
-
- <%@include file="/pages/common/footer.jsp" %>
- body>
- html>
- <div id="page_nav">
- <%--大于首页,才显示--%>
- <c:if test="${requestScope.page.pageNo > 1}">
- <a href="manager/bookServlet?action=page&pageNo=1">首页a>
- <a href="manager/bookServlet?action=page&pageNo=${requestScope.page.pageNo - 1}">上一页a>
- c:if>
- <a href="#">3a>
- 【${requestScope.page.pageNo}】
- <a href="#">5a>
- <%-- 如果已经 是最后一页,则不显示下一页,末页 --%>
- <c:if test="${requestScope.page.pageNo < requestScope.page.pageTotal}">
- <a href="manager/bookServlet?action=page&pageNo=${requestScope.page.pageNo + 1}">下一页a>
- <a href="manager/bookServlet?action=page&pageNo=${requestScope.page.pageTotal}">末页a>
- c:if>
- 共${requestScope.page.pageTotal}页,${requestScope.page.pageTotalCount}条记录
- 到第<input value="4" name="pn" id="pn_input"/>页
- <input type="button" value="确定">
- div>
- // 给按钮绑定点击事件
- $("#searchPageBtn").click(function () {
- var pageNo = $("#pn_input").val();
- // javaScript 语言中提供了一个 location 地址栏对象
- // 它有一个属性叫 href.它可以获取浏览器地址栏中的地址
- // href 属性可读,可写
- location.href = "${requestScope.basePath}manager/bookServlet?action=page&pageNo=" + pageNo;
- });
2. 将
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <%
- String basePath = request.getScheme() + "://" +
- request.getServerName() + ":" +
- request.getServerPort() +
- request.getContextPath() + "/";
- request.setAttribute("basePath",basePath);
- %>
- <html>
- <head>
- <title>Titletitle>
- <base href="<%=basePath%>">
- <link type="text/css" rel="stylesheet" href="static/css/style.css">
- <script type="text/javascript" src="static/js/script/jquery-1.7.2.min.js">script>
- head>
3. BookService 中 page 方法中添加数据边界的有效检查:
- public Page
page(int pageNo, int pageSize) { - Page
page = new Page<>(); -
- // 设置 当前每页显示数量
- page.setPageSize(pageSize);
-
- // 求总记录数
- Integer pageTotalCount = bookDao.queryForPageTotalCount();
- // 设置总记录数
- page.setPageTotalCount(pageTotalCount);
-
- // 求总页码
- Integer pageTotal = pageTotalCount / pageSize;
- if ((pageTotalCount % pageSize) > 0) {
- pageTotal++;
- }
- // 设置总页码
- page.setPageTotal(pageTotal);
-
- // 设置 当前页码
- /* 数据边界的有效检查 */
- if (pageNo < 1) {
- pageNo = 1;
- }
- if (pageNo > pageTotal) {
- pageNo = pageTotal;
- }
- page.setPageNo(pageNo);
-
- // 求当前页面数据
- // 求页面开始索引
- Integer begin = (pageNo - 1) * pageSize;
- List
items = bookDao.queryForPageItems(begin, pageSize); - // 设置当前页面数据
- page.setItems(items);
-
- return page;
- }
分析情况 1 :如果总页码小于等于 5 的情况,页码的范围是: 1- 总页码1 页 12 页 1,23 页 1,2, 34 页 1,2, 3 , 45 页 1,2, 3 , 4 , 5情况 2 :总页码大于 5 的情况。假设一共 10 页小情况 1 :当前页码为前面 3 个: 1 , 2 , 3 的情况,页码范围是: 1-5.【1 】 2 , 3 , 4 , 51【 2 】 3 , 4 , 51,2 【 3 】 4 , 5小情况 2 :当前页码为最后 3 个, 8 , 9 , 10 ,页码范围是:总页码减 4 - 总页码6, 7 【 8 】 9 , 106, 7 , 8 【 9 】 106, 7 , 8 , 9 【 10 】小情况 3 : 4 , 5 , 6 , 7 ,页码范围是:当前页码减 2 - 当前页码加 22, 3, 【4】 , 5 , 63, 4 ,【 5】 , 6 , 74, 5 ,【 6】 , 7 , 85, 6 ,【 7】 , 8 , 9
- <div id="page_nav">
- <%--大于首页,才显示--%>
- <c:if test="${requestScope.page.pageNo > 1}">
- <a href="manager/bookServlet?action=page&pageNo=1">首页a>
- <a href="manager/bookServlet?action=page&pageNo=${requestScope.page.pageNo - 1}">上一页a>
- c:if>
-
- <%--页码输出的开始--%>
- <c:choose>
- <%--情况 1:如果总页码小于等于 5 的情况,页码的范围是:1-总页码--%>
- <c:when test="${requestScope.page.pageTotal <= 5}">
- <c:set var="begin" value="1"/>
- <c:set var="end" value="${requestScope.page.pageTotal}"/>
- c:when>
- <%--情况 2:总页码大于 5 的情况--%>
- <c:when test="${requestScope.page.pageTotal > 5}">
- <c:choose>
- <%--小情况 1:当前页码为前面 3 个:1,2,3 的情况,页码范围是:1-5.--%>
- <c:when test="${requestScope.page.pageNo <= 3}">
- <c:set var="begin" value="1"/>
- <c:set var="end" value="5"/>
- c:when>
- <%--小情况 2:当前页码为最后 3 个,8,9,10,页码范围是:总页码减 4 - 总页码--%>
- <c:when test="${requestScope.page.pageNo > requestScope.page.pageTotal-3}">
- <c:set var="begin" value="${requestScope.page.pageTotal - 4}"/>
- <c:set var="end" value="${requestScope.page.pageTotal}"/>
- c:when>
- <%--小情况 3:4,5,6,7,页码范围是:当前页码减 2 - 当前页码加 2--%>
- <c:otherwise>
- <c:set var="begin" value="${requestScope.page.pageNo - 2}"/>
- <c:set var="end" value="${requestScope.page.pageNo + 2}"/>
- c:otherwise>
- c:choose>
- c:when>
- c:choose>
-
- <c:forEach begin="${begin}" end="${end}" var="i">
- <c:if test="${requestScope.page.pageNo == i}">
- 【${i}】
- c:if>
- <c:if test="${requestScope.page.pageNo != i}">
- <a href="manager/bookServlet?action=page&pageNo=${i}">${i}a>
- c:if>
- c:forEach>
- <%--页码输出的结束--%>
-
- <%-- 如果已经 是最后一页,则不显示下一页,末页 --%>
- <c:if test="${requestScope.page.pageNo < requestScope.page.pageTotal}">
- <a href="manager/bookServlet?action=page&pageNo=${requestScope.page.pageNo + 1}">下一页a>
- <a href="manager/bookServlet?action=page&pageNo=${requestScope.page.pageTotal}">末页a>
- c:if>
- 共${requestScope.page.pageTotal}页,${requestScope.page.pageTotalCount}条记录
- 到第<input value="${requestScope.page.pageNo}" name="pn" id="pn_input"/>页
- <input id="searchPageBtn" type="button" value="确定">
- div>
3、在服务器重定向的时候,获取当前页码追加上进行跳转
- protected void update(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 1.获取请求参数,并封装成Book对象
- Book book = WebUtils.copyParamToBean(request.getParameterMap(), new Book());
-
- // 2.调用BookServlet.update(book)方法,修改图书
- bookService.update(book);
-
- // 3.重定向返回图书列表管理页面
- response.sendRedirect(request.getContextPath() + "/manager/bookServlet?action=page&pageNo=" + request.getParameter("pageNo"));
- }
步骤:
1.复制以分index到pages/client中
2.编写ClientBookServlet程序,并继承BaseServlet父类
3.将原来的index.jsp内容全删,改成去求转发
4.修改复制后的index
2.编写ClientBookServlet程序,并继承BaseServlet父类
- protected void page(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 1.获取请求参数 pageNo 和 pageSize
- int pageNo = WebUtils.parseInt(request.getParameter("pageNo"), 1);
- int pageSize = WebUtils.parseInt(request.getParameter("pageSize"), Page.PAGE_SIZE);
-
- // 2.调用BookServlet.page(pageNo,pageSize),获得page对象
- Page
page = bookService.page(pageNo, pageSize); -
- // 3.将Page对象保存到Request域中
- request.setAttribute("page", page);
-
- // 4.请求转发到 /pages/manager/book_manager.jsp
- request.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(request, response);
- }
3. 将原来的index.jsp内容全删,改成去求转发
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <jsp:forward page="/client/bookServlet?action=page">jsp:forward>
4.修改复制后的index
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
-
- html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>书城首页title>
- <%@include file="/pages/common/head.jsp"%>
- head>
- <body>
-
- <div id="header">
- <img class="logo_img" alt="" src="static/img/logo.gif">
- <span class="wel_word">网上书城span>
- <div>
- <a href="pages/user/login.jsp">登录a> |
- <a href="pages/user/regist.jsp">注册a>
- <a href="pages/cart/cart.jsp">购物车a>
- <a href="pages/manager/manager.jsp">后台管理a>
- div>
- div>
- <div id="main">
- <div id="book">
- <div class="book_cond">
- <form action="" method="get">
- 价格:<input id="min" type="text" name="min" value=""> 元 -
- <input id="max" type="text" name="max" value=""> 元
- <input type="submit" value="查询"/>
- form>
- div>
- <div style="text-align: center">
- <span>您的购物车中有3件商品span>
- <div>
- 您刚刚将<span style="color: red">时间简史span>加入到了购物车中
- div>
- div>
-
- <%-- 书籍的开始 --%>
- <c:forEach items="${requestScope.page.items}" var="book">
- <div class="b_list">
- <div class="img_div">
- <img class="book_img" alt="" src="${book.img_path}"/>
- div>
- <div class="book_info">
- <div class="book_name">
- <span class="sp1">书名:span>
- <span class="sp2">${book.name}span>
- div>
- <div class="book_author">
- <span class="sp1">作者:span>
- <span class="sp2">${book.author}span>
- div>
- <div class="book_price">
- <span class="sp1">价格:span>
- <span class="sp2">¥${book.price}span>
- div>
- <div class="book_sales">
- <span class="sp1">销量:span>
- <span class="sp2">${book.sales}span>
- div>
- <div class="book_amount">
- <span class="sp1">库存:span>
- <span class="sp2">${book.stock}span>
- div>
- <div class="book_add">
- <button>加入购物车button>
- div>
- div>
- div>
- c:forEach>
- <%-- 书籍的结束 --%>
-
- div>
-
- <%-- 分页条的开始 --%>
- <div id="page_nav">
- <%--大于首页,才显示--%>
- <c:if test="${requestScope.page.pageNo > 1}">
- <a href="client/bookServlet?action=page&pageNo=1">首页a>
- <a href="client/bookServlet?action=page&pageNo=${requestScope.page.pageNo - 1}">上一页a>
- c:if>
-
- <%--页码输出的开始--%>
- <c:choose>
- <%--情况 1:如果总页码小于等于 5 的情况,页码的范围是:1-总页码--%>
- <c:when test="${requestScope.page.pageTotal <= 5}">
- <c:set var="begin" value="1"/>
- <c:set var="end" value="${requestScope.page.pageTotal}"/>
- c:when>
- <%--情况 2:总页码大于 5 的情况--%>
- <c:when test="${requestScope.page.pageTotal > 5}">
- <c:choose>
- <%--小情况 1:当前页码为前面 3 个:1,2,3 的情况,页码范围是:1-5.--%>
- <c:when test="${requestScope.page.pageNo <= 3}">
- <c:set var="begin" value="1"/>
- <c:set var="end" value="5"/>
- c:when>
- <%--小情况 2:当前页码为最后 3 个,8,9,10,页码范围是:总页码减 4 - 总页码--%>
- <c:when test="${requestScope.page.pageNo > requestScope.page.pageTotal-3}">
- <c:set var="begin" value="${requestScope.page.pageTotal - 4}"/>
- <c:set var="end" value="${requestScope.page.pageTotal}"/>
- c:when>
- <%--小情况 3:4,5,6,7,页码范围是:当前页码减 2 - 当前页码加 2--%>
- <c:otherwise>
- <c:set var="begin" value="${requestScope.page.pageNo - 2}"/>
- <c:set var="end" value="${requestScope.page.pageNo + 2}"/>
- c:otherwise>
- c:choose>
- c:when>
- c:choose>
-
- <c:forEach begin="${begin}" end="${end}" var="i">
- <c:if test="${requestScope.page.pageNo == i}">
- 【${i}】
- c:if>
- <c:if test="${requestScope.page.pageNo != i}">
- <a href="client/bookServlet?action=page&pageNo=${i}">${i}a>
- c:if>
- c:forEach>
- <%--页码输出的结束--%>
-
- <%-- 如果已经 是最后一页,则不显示下一页,末页 --%>
- <c:if test="${requestScope.page.pageNo < requestScope.page.pageTotal}">
- <a href="client/bookServlet?action=page&pageNo=${requestScope.page.pageNo + 1}">下一页a>
- <a href="client/bookServlet?action=page&pageNo=${requestScope.page.pageTotal}">末页a>
- c:if>
- 共${requestScope.page.pageTotal}页,${requestScope.page.pageTotalCount}条记录
- 到第<input value="${requestScope.page.pageNo}" name="pn" id="pn_input"/>页
- <input id="searchPageBtn" type="button" value="确定">
- div>
- <script type="text/javascript">
- $(function (){
- // 给按钮绑定点击事件
- $("#searchPageBtn").click(function () {
- var pageNo = $("#pn_input").val();
- // javaScript 语言中提供了一个 location 地址栏对象
- // 它有一个属性叫 href.它可以获取浏览器地址栏中的地址
- // href 属性可读,可写
- location.href = "${requestScope.basePath}manager/bookServlet?action=page&pageNo=" + pageNo;
- });
- });
- script>
- <%-- 分页条的结束 --%>
-
- div>
- <%@include file="/pages/common/footer.jsp"%>
- body>
- html>
、
2.在 Servlet 程序的 page 分页方法中设置 url 的分页请求地址
在ClientBookServlet类中

- <%--
- Created by IntelliJ IDEA.
- User: pc
- Date: 2022/7/28
- Time: 21:37
- To change this template use File | Settings | File Templates.
- --%>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <%-- 分页条的开始 --%>
- <div id="page_nav">
- <%--大于首页,才显示--%>
- <c:if test="${requestScope.page.pageNo > 1}">
- <a href="${requestScope.page.url}&pageNo=1">首页a>
- <a href="${requestScope.page.url}&pageNo=${requestScope.page.pageNo - 1}">上一页a>
- c:if>
-
- <%--页码输出的开始--%>
- <c:choose>
- <%--情况 1:如果总页码小于等于 5 的情况,页码的范围是:1-总页码--%>
- <c:when test="${requestScope.page.pageTotal <= 5}">
- <c:set var="begin" value="1"/>
- <c:set var="end" value="${requestScope.page.pageTotal}"/>
- c:when>
- <%--情况 2:总页码大于 5 的情况--%>
- <c:when test="${requestScope.page.pageTotal > 5}">
- <c:choose>
- <%--小情况 1:当前页码为前面 3 个:1,2,3 的情况,页码范围是:1-5.--%>
- <c:when test="${requestScope.page.pageNo <= 3}">
- <c:set var="begin" value="1"/>
- <c:set var="end" value="5"/>
- c:when>
- <%--小情况 2:当前页码为最后 3 个,8,9,10,页码范围是:总页码减 4 - 总页码--%>
- <c:when test="${requestScope.page.pageNo > requestScope.page.pageTotal-3}">
- <c:set var="begin" value="${requestScope.page.pageTotal - 4}"/>
- <c:set var="end" value="${requestScope.page.pageTotal}"/>
- c:when>
- <%--小情况 3:4,5,6,7,页码范围是:当前页码减 2 - 当前页码加 2--%>
- <c:otherwise>
- <c:set var="begin" value="${requestScope.page.pageNo - 2}"/>
- <c:set var="end" value="${requestScope.page.pageNo + 2}"/>
- c:otherwise>
- c:choose>
- c:when>
- c:choose>
-
- <c:forEach begin="${begin}" end="${end}" var="i">
- <c:if test="${requestScope.page.pageNo == i}">
- 【${i}】
- c:if>
- <c:if test="${requestScope.page.pageNo != i}">
- <a href="${requestScope.page.url}&pageNo=${i}">${i}a>
- c:if>
- c:forEach>
- <%--页码输出的结束--%>
-
- <%-- 如果已经 是最后一页,则不显示下一页,末页 --%>
- <c:if test="${requestScope.page.pageNo < requestScope.page.pageTotal}">
- <a href="${requestScope.page.url}&pageNo=${requestScope.page.pageNo + 1}">下一页a>
- <a href="${requestScope.page.url}&pageNo=${requestScope.page.pageTotal}">末页a>
- c:if>
- 共${requestScope.page.pageTotal}页,${requestScope.page.pageTotalCount}条记录
- 到第<input value="${requestScope.page.pageNo}" name="pn" id="pn_input"/>页
- <input id="searchPageBtn" type="button" value="确定">
- div>
- <script type="text/javascript">
- $(function (){
- // 给按钮绑定点击事件
- $("#searchPageBtn").click(function () {
- var pageNo = $("#pn_input").val();
- // javaScript 语言中提供了一个 location 地址栏对象
- // 它有一个属性叫 href.它可以获取浏览器地址栏中的地址
- // href 属性可读,可写
- location.href = "${requestScope.basePath}${requestScope.page.url}&pageNo=" + pageNo;
- });
- });
- script>
- <%-- 分页条的结束 --%>
思路流程图
1.修改表单的发送地址,接添加隐藏域 ,并优化部分代码
2.在ClientBookServlet程序中编写pageByPrice方法
- protected void pageByPrice(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- System.out.println("经过了前台");
- // 1.获取请求参数 pageNo 和 pageSize
- int pageNo = WebUtils.parseInt(request.getParameter("pageNo"), 1);
- int pageSize = WebUtils.parseInt(request.getParameter("pageSize"), Page.PAGE_SIZE);
- int min = WebUtils.parseInt(request.getParameter("min"), 0);
- int max = WebUtils.parseInt(request.getParameter("max"), Integer.MAX_VALUE);
-
- // 2.调用BookServlet.page(pageNo,pageSize),获得page对象
- Page
page = bookService.pageByPrice(pageNo, pageSize,min,max); -
-
- StringBuilder sb = new StringBuilder("client/bookServlet?action=pageByPrice");
- if (request.getParameter("min") != null) {
- sb.append("&min=").append(request.getParameter("min"));
- }
- if (request.getParameter("min") != null) {
- sb.append("&max=").append(request.getParameter("max"));
- }
- page.setUrl(sb.toString());
-
- // 3.将Page对象保存到Request域中
- request.setAttribute("page", page);
-
- // 4.请求转发到 /pages/client/index.js
- request.getRequestDispatcher("/pages/client/index.jsp").forward(request, response);
- }
3.编写BookServlet程序
- public Page
pageByPrice(int pageNo, int pageSize, int min, int max) { - Page
page = new Page<>(); -
- // 设置 当前每页显示数量
- page.setPageSize(pageSize);
-
- // 求总记录数
- Integer pageTotalCount = bookDao.queryForPageTotalCountByPrice(min,max);
- // 设置总记录数
- page.setPageTotalCount(pageTotalCount);
-
- // 求总页码
- Integer pageTotal = pageTotalCount / pageSize;
- if ((pageTotalCount % pageSize) > 0) {
- pageTotal++;
- }
- // 设置总页码
- page.setPageTotal(pageTotal);
-
- // 设置 当前页码
- /* 数据边界的有效检查 */
- if (pageNo < 1) {
- pageNo = 1;
- }
- if (pageNo > pageTotal) {
- pageNo = pageTotal;
- }
- page.setPageNo(pageNo);
-
- // 求当前页面数据
- // 求页面开始索引
- Integer begin = (pageNo - 1) * pageSize;
- List
items = bookDao.queryForPageItemsByPrice(begin, pageSize,min,max); - // 设置当前页面数据
- page.setItems(items);
-
- return page;
-
- }
4.编写Bookdao程序
- @Override
- public Integer queryForPageTotalCountByPrice(int min, int max) {
- String sql = "select count(*) from t_book where price between ? and ?";
- Number number = (Number) queryForSingleValue(sql, min, max);
- return number.intValue();
- }
-
- @Override
- public List
queryForPageItemsByPrice(Integer begin, int pageSize, int min, int max) { - String sql = "select `id`,`name`,`author`,`price`,`sales`,`stock`,`img_path` " +
- "from t_book where price between ? and ? order by price asc limit ?,?";
- return queryForList(Book.class, sql, min, max, begin, pageSize);
- }
5.测试Bookdao程序
- @Test
- public void queryForPageTotalCountByPrice() {
- System.out.println(bookDao.queryForPageTotalCountByPrice(10,50));
- }
-
- @Test
- public void queryForPageItemsByPrice() {
- for (Book item : bookDao.queryForPageItemsByPrice(0,4,10,50)) {
- System.out.println(item);
- }
- }
6.测试BookService程序
- @Test
- public void pageByPrice() {
- System.out.println(bookService.pageByPrice(1,4,10,50));
- }
需求:在用户登录成功后显示用户名欢迎菜单
步骤:1. UserServlet 程序中保存用户登录的信息2.修改 login_succuess_menu.jsp3.还要修改首页 index.jsp 页面的菜单(没登陆时显示登录/注册,若已登录显示用户欢迎菜单)
- /**
- * 处理登录功能
- *
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- protected void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
- // 获取请求的参数
- User user = WebUtils.copyParamToBean(request.getParameterMap(), new User());
-
- // 调用 userService.login()登录处理业务
- User loginUser = userService.login(user);
-
- if (loginUser == null) {
- // 不正确
- // 把错误信息,和回显的表单项信息,保存到Request域中
- request.setAttribute("msg", "用户名或密码错误!");
- request.setAttribute("username", user.getUsername());
- // 跳回登录页面
- request.getRequestDispatcher("/pages/user/login.jsp").forward(request, response);
- } else {
- // 正确
- // 用户信息保存到Session对象中
- request.getSession().setAttribute("loginUser", loginUser);
- // 跳转到登录成功页面
- request.getRequestDispatcher("/pages/user/login_success.jsp").forward(request, response);
- }
- }
2.修改 login_succuess_menu.jsp
- <div id="header">
- <img class="logo_img" alt="" src="static/img/logo.gif">
- <span class="wel_word">网上书城span>
- <div>
- <c:if test="${empty sessionScope.user}" >
- <a href="pages/user/login.jsp">登录a> |
- <a href="pages/user/regist.jsp">注册a>
- c:if>
- <c:if test="${not empty sessionScope.user}">
- <span>欢迎<span class="um_span">${sessionScope.user.username}span>光临尚硅谷书城span>
- <a href="pages/order/order.jsp">我的订单a>
- <a href="index.jsp">注销a>
- c:if>
- <a href="pages/cart/cart.jsp">购物车a>
- <a href="pages/manager/manager.jsp">后台管理a>
- div>
- div>
步骤:1.UserServlet 程序中添加 logout 方法1. 销毁 Session 中用户登录的信息(或者销毁 Session)2. 重定向到首页(或登录页面)。2. 修改【注销】的菜单地址
- /**
- * 注销登录功能
- *
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- protected void logout(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 1、销毁 Session 中用户登录的信息(或者销毁 Session)
- request.getSession().invalidate();
- // 2、重定向到首页
- response.sendRedirect(request.getContextPath());
- }
2. 修改【注销】的菜单地址
表单重复提交有三种常见的情况:一:提交完表单。服务器使用请求转来进行页面跳转。这个时候,用户按下功能键 F5,就会发起最后一次的请求。 造成表单重复提交问题。解决方法:使用重定向来进行跳转二:用户正常提交服务器,但是由于网络延迟等原因,迟迟未收到服务器的响应,这个时候,用户以为提交失败,就会着急,然后多点了几次提交操作,也会造成表单重复提交。三:用户正常提交服务器。服务器也没有延迟,但是提交完成后,用户回退浏览器。重新提交。也会造成表单重复提交。
谷歌验证码 kaptcha 使用步骤如下:1、导入谷歌验证码的 jar 包kaptcha-2.3.2.jar2、在 web.xml 中去配置用于生成验证码的 Servlet 程序3、在表单中使用 img 标签去显示验证码图片并使用它4、在服务器获取谷歌生成的验证码和客户端发送过来的验证码比较使用。
2、在 web.xml 中去配置用于生成验证码的 Servlet 程序
- <servlet>
- <servlet-name>KaptchaServletservlet-name>
- <servlet-class>com.google.code.kaptcha.servlet.KaptchaServletservlet-class>
- servlet>
- <servlet-mapping>
- <servlet-name>KaptchaServletservlet-name>
- <url-pattern>/kaptcha.jpgurl-pattern>
- servlet-mapping>
3、在表单中使用 img 标签去显示验证码图片并使用它
4、在服务器获取谷歌生成的验证码和客户端发送过来的验证码比较使用。
- /**
- * 处理注册功能
- *
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- protected void regist(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- UserService userService = new UserServiceImpl();
- // 获取请求的参数
- User user = WebUtils.copyParamToBean(request.getParameterMap(), new User());
- String code = request.getParameter("code");
-
- // 获取 Session 中的验证码
- HttpSession session = request.getSession();
- // KAPTCHA_SESSION_KEY 可以当作是验证码值的key
- String key = (String) session.getAttribute(KAPTCHA_SESSION_KEY);
- // 删除 Session 中的验证码
- // session.removeAttribute(KAPTCHA_SESSION_KEY);
- session.invalidate();
-
-
- // 检查 验证码是否正确
- if (code.equalsIgnoreCase(key)) {
- // 正确 检查 用户名是否可用
- if (userService.existsUsername(user.getUsername())) {
- // 不可用
- request.setAttribute("msg", "用户名已存在!");
- request.setAttribute("email", user.getEmail());
- // 跳回注册页面
- request.getRequestDispatcher("/pages/user/regist.jsp").forward(request, response);
- } else {
- // 可用 跳转到注册成功页面
- userService.regist(new User(user.getId(), user.getUsername(), user.getPassword(), user.getEmail()));
- request.getRequestDispatcher("/pages/user/regist_success.jsp").forward(request, response);
- }
-
- } else {
- // 不正确
- request.setAttribute("msg", "验证码错误!");
- request.setAttribute("username", user.getUsername());
- request.setAttribute("email", user.getEmail());
- // 跳回注册页面
- request.getRequestDispatcher("/pages/user/regist.jsp").forward(request, response);
- }
- }
给验证码绑定单机事件
- /**
- * 购物车的商品项
- */
- public class CartItem {
- private Integer id;
- private String name;
- private Integer count;
- private BigDecimal price;
- private BigDecimal totalPrice;
- }
- /**
- * 购物车对象
- */
- public class Cart {
- // private Integer totalCount;
- // private BigDecimal totalPrice;
-
- /**
- * key 是商品编号,
- * value,是商品信息
- */
- private Map
items = new LinkedHashMap<>(); -
- /**
- * 添加商品项
- *
- * @param cartItem
- */
- public void addItem(CartItem cartItem) {
- // 先查看购物车中是否已经添加过此商品,
- // 如果已添加,则数量累加,总金额更新,如果没有添加过,直接放到 集合中即可
- CartItem item = items.get(cartItem.getId());
-
- if (item == null) {
- // 之前没添加过此商品
- items.put(cartItem.getId(), cartItem);
- } else {
- // 之前已添加过此商品
- item.setCount(item.getCount() + 1); // 数量
- item.setTotalPrice(item.getPrice().multiply(new BigDecimal(item.getCount())));
- }
- }
-
- /**
- * 删除商品项
- *
- * @param id
- */
- public void deleteItem(Integer id) {
- items.remove(id);
- }
-
- /**
- * 清空购物车
- */
- public void clear() {
- items.clear();
- }
-
- /**
- * 修改商品数量
- *
- * @param id
- * @param count
- */
- public void updateCount(Integer id, Integer count) {
- // 先查看购物车中是否有此商品。如果有,修改商品数量,更新总金额
- CartItem item = items.get(id);
-
- if (item != null) {
- // 修改商品数量
- item.setCount(count);
- // 修改商品总金额
- item.setTotalPrice(item.getPrice().multiply(new BigDecimal(count)));
- }
- }
-
- public Integer getTotalCount() {
- Integer totalCount = 0;
- for (Map.Entry
entry : items.entrySet()) { - totalCount += entry.getValue().getCount();
- }
- return totalCount;
- }
-
-
- public BigDecimal getTotalPrice() {
- BigDecimal totalPrice = new BigDecimal(0);
- for (Map.Entry
entry : items.entrySet()) { - totalPrice = totalPrice.add(entry.getValue().getTotalPrice());
- }
- return totalPrice;
- }
-
-
- public Map
getItems() { - return items;
- }
-
- public void setItems(Map
items) { - this.items = items;
- }
-
- @Override
- public String toString() {
- return "Cart{" +
- "totalCount=" + getTotalCount() +
- ", totalPrice=" + getTotalPrice() +
- ", items=" + items +
- '}';
- }
- }
-
- public class CartTest {
-
- Cart cart = new Cart();
-
- @Test
- public void addItem() {
- cart.addItem(new CartItem(1, "java从入门到放弃", 1, new BigDecimal(1000), new BigDecimal(2000)));
- cart.addItem(new CartItem(1, "java从入门到放弃", 1, new BigDecimal(1000), new BigDecimal(2000)));
- cart.addItem(new CartItem(2, "java从入门到入土", 1, new BigDecimal(100), new BigDecimal(100)));
- System.out.println(cart);
- }
-
- @Test
- public void deleteItem() {
- cart.addItem(new CartItem(1, "java从入门到放弃", 1, new BigDecimal(1000), new BigDecimal(2000)));
- cart.addItem(new CartItem(1, "java从入门到放弃", 1, new BigDecimal(1000), new BigDecimal(2000)));
- cart.addItem(new CartItem(2, "java从入门到入土", 1, new BigDecimal(100), new BigDecimal(100)));
-
- cart.deleteItem(1);
-
- System.out.println(cart);
- }
-
- @Test
- public void clear() {
- cart.addItem(new CartItem(1, "java从入门到放弃", 1, new BigDecimal(1000), new BigDecimal(2000)));
- cart.addItem(new CartItem(1, "java从入门到放弃", 1, new BigDecimal(1000), new BigDecimal(2000)));
- cart.addItem(new CartItem(2, "java从入门到入土", 1, new BigDecimal(100), new BigDecimal(100)));
-
- cart.deleteItem(1);
-
- cart.clear();
-
- System.out.println(cart);
- }
-
- @Test
- public void updateCount() {
- cart.addItem(new CartItem(1, "java从入门到放弃", 1, new BigDecimal(1000), new BigDecimal(2000)));
- cart.addItem(new CartItem(1, "java从入门到放弃", 1, new BigDecimal(1000), new BigDecimal(2000)));
- cart.addItem(new CartItem(2, "java从入门到入土", 1, new BigDecimal(100), new BigDecimal(100)));
-
- cart.updateCount(2,20);
-
- System.out.println(cart);
- }
- }
步骤:1.在index.jsp 页面 给加入 购物车按钮添加绑定事件,使点击时可以跳到CartServlet程序2.编写 CartServlet程序1. 获取请求的参数 商品编号2. 调用 bookService.queryBookById(id):Book 得到图书的信息3. 把图书信息,转换成为 CartItem 商品项4. 调用 Cart.addItem(CartItem);添加商品项5. 重定向回原来商品所在的地址页面
2.编写 CartServlet程序
- /**
- * 加入购物车
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- protected void addItem(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- System.out.println("进来了");
- // 1. 获取请求的参数 商品编号
- int id = WebUtils.parseInt(request.getParameter("id"), 0);
-
- // 2. 调用 bookService.queryBookById(id):Book 得到图书的信息
- Book book = bookService.queryBookById(id);
-
- // 3. 把图书信息,转换成为 CartItem 商品项
- CartItem cartItem = new CartItem(book.getId(), book.getName(), 1, book.getPrice(), book.getPrice());
-
- // 4. 调用 Cart.addItem(CartItem);添加商品项
- Cart cart = (Cart) request.getSession().getAttribute("cart");
- if (cart == null) {
- cart = new Cart();
- request.getSession().setAttribute("cart",cart);
- }
- cart.addItem(cartItem);
-
- // 5. 重定向回原来商品所在的地址页面
- // Referer 可以获取当前页面地址
- System.out.println(cart);
- System.out.println("当前页面地址:" + request.getHeader("Referer"));
- response.sendRedirect(request.getHeader("Referer"));
-
- }
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>购物车title>
- <%@include file="/pages/common/head.jsp" %>
- head>
- <body>
-
- <div id="header">
- <img class="logo_img" alt="" src="static/img/logo.gif">
- <span class="wel_word">购物车span>
- <%@include file="/pages/common/success_menu.jsp" %>
- div>
-
- <div id="main">
-
- <table>
-
- <tr>
- <td>商品名称td>
- <td>数量td>
- <td>单价td>
- <td>金额td>
- <td>操作td>
- tr>
- <c:if test="${empty sessionScope.cart.items}">
- <tr>
- <td colspan="5">
- <a href="index.jsp"> 亲,当前购物车为空!快跟小伙伴们去浏览商品吧!!!a>
- td>
- tr>
- c:if>
- <c:if test="${not empty sessionScope.cart.items}">
-
- <c:forEach items="${sessionScope.cart.items}" var="item">
- <tr>
- <td>${item.value.name}td>
- <td>${item.value.count}td>
- <td>${item.value.price}td>
- <td>${item.value.totalPrice}td>
- <td><a href="#">删除a>td>
- tr>
- c:forEach>
- c:if>
-
-
- table>
- <c:if test="${not empty sessionScope.cart.items}">
- <div class="cart_info">
- <span class="cart_span">购物车中共有<span class="b_count">${sessionScope.cart.totalCount}span>件商品span>
- <span class="cart_span">总金额<span class="b_price">${sessionScope.cart.totalPrice}span>元span>
- <span class="cart_span"><a href="#">清空购物车a>span>
- <span class="cart_span"><a href="pages/cart/checkout.jsp">去结账a>span>
- div>
- c:if>
-
- div>
-
- <%@include file="/pages/common/footer.jsp" %>
- body>
- html>
步骤:
1 .给删除添加请求地址
2. 编写cartServlet程序
3. 给删除添加确认提示操作
1 .给删除添加请求地址

2. 编写cartServlet程序
- /**
- * 删除商品项
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- protected void deleteItem(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 获取商品项编号
- int id = WebUtils.parseInt(request.getParameter("id"), 0);
-
- // 获取购物车对象
- Cart cart = (Cart) request.getSession().getAttribute("cart");
-
- if (cart != null) {
- // 删除 了购物车商品项
- cart.deleteItem(id);
- // 重定向回原来商品所在的地址页面
- response.sendRedirect(request.getHeader("Referer"));
-
- }
- }
3. 给删除添加确认提示操作
-
步骤:
1 .给清除功能添加请求地址,并添加id属性
2. 编写cartServlet程序
3. 给删除添加确认提示操作
1 .给清除功能添加请求地址,并添加id属性
- /**
- * 清空购物车
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- protected void clear(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- //获取购物车对象
- Cart cart = (Cart) request.getSession().getAttribute("cart");
-
- if (cart != null) {
- //清空购物车
- cart.clear();
- // 重定向回原来商品所在的地址页面
- response.sendRedirect(request.getHeader("referer"));
- }
-
- }
3. 给删除添加确认提示操作
- // 给清空购物车绑定事件
- $(function (){
- $("#clearCart").click(function (){
- return confirm("你确定要清空购物车吗?");
- });
- });
思路:

步骤:
1 .在 数量列 添加文本框,并绑定事件
2. 编写cartServlet程序
1 .在 数量列 添加文本框,并绑定事件

- // 给修改数量绑定事件
- $(".updateCount").change(function () {
- // 获取商品id
- var id = $(this).attr("bookId");
- // 获取商品名称
- let name = $(this).parent().parent().find(":first").text();
- // 获取商品数量
- let count = this.value;
- if (confirm("你确定要将【" + name + "】的数量修改成:" + count + "吗")) {
- //发起请求。给服务器保存修改
- location.href = "cartServlet?action=updateCount&id=" + id + "&count=" + count;
- } else {
- // defaultValue 属性是表单项 Dom 对象的属性。它表示默认的 value 属性值。
- this.value = this.defaultValue;
- }
- });
2. 编写cartServlet程序
- /**
- * 修改商品数量
- *
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- protected void updateCount(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 获取请求的参数 商品编号 、商品数量
- int id = WebUtils.parseInt(request.getParameter("id"), 0);
- int count = WebUtils.parseInt(request.getParameter("count"), 1);
-
- // 获取购物车对象
- Cart cart = (Cart) request.getSession().getAttribute("cart");
-
- if (cart != null) {
- // 修改商品数量
- cart.updateCount(id, count);
- // 重定向返回商品原来的地址
- response.sendRedirect(request.getHeader("Referer"));
- }
-
-
- }
步骤:
1.在添加商品到购物车的时候,保存最后一个添加的商品名称
2.在 pages/client/index.jsp 页面中输出购物车信息
1.在添加商品到购物车的时候,保存最后一个添加的商品名称

2.在 pages/client/index.jsp 页面中输出购物车信息
- <c:if test="${empty sessionScope.cart.items}">
- <div style="text-align: center">
- <span> span>
- <div>
- <span style="color: red">您当前的购物车里没有商品哦span>
- div>
- div>
- c:if>
- <c:if test="${not empty sessionScope.cart.items}">
- <div style="text-align: center">
- <span>您的购物车中有${sessionScope.cart.totalCount}件商品span>
- <div>
- 您刚刚将<span style="color: red">${sessionScope.lastName}span>加入到了购物车中
- div>
- div>
- c:if>

- USE book;
- CREATE TABLE t_order(
- order_id VARCHAR(50) PRIMARY KEY,
- create_time DATETIME ,
- price DECIMAL(11,2),
- `status` INT,
- user_id INT,
- FOREIGN KEY (user_id) REFERENCES t_book(id)
- );
-
- CREATE TABLE t_order_item(
- id INT PRIMARY KEY AUTO_INCREMENT,
- name VARCHAR(100),
- count INT,
- price DECIMAL(11,2),
- total_price DECIMAL(11,2),
- order_id VARCHAR(50),
- FOREIGN KEY (order_id) REFERENCES t_order(order_id)
- );
- public class Order {
- private String orderId;
- private Date createTime;
- private BigDecimal price;
- // 0 未发货,1 已发货,2 表示已签收
- private Integer status = 0;
- private Integer userId;
- }
- public class OrderItem {
- private Integer id;
- private String name;
- private Integer count;
- private BigDecimal price;
- private BigDecimal totalPrice;
- private String orderId;
- }
- public interface OrderDao {
- /**
- * 保存订单
- * @param order
- * @return
- */
- public int saveOrder(Order order);
- }
- public class OrderDaoImpl extends BaseDao implements OrderDao {
- @Override
- public int saveOrder(Order order) {
- String sql = "insert into t_order(order_id,create_time,price,`status`,user_id) values(?,?,?,?,?)";
- return update(sql, order.getOrderId(), order.getCreateTime(), order.getPrice(), order.getStatus(), order.getUserId());
- }
-
- }
- public interface OrderItemDao {
-
- /**
- * 保存订单项
- * @param orderItem
- * @return
- */
- public int saveOrderItem(OrderItem orderItem);
-
- }
- public class OrderItemDaoImpl extends BaseDao implements OrderItemDao {
- @Override
- public int saveOrderItem(OrderItem orderItem) {
- String sql = "insert into t_order_item(name,count,price,total_price,order_id) values (?,?,?,?,?)";
- return update(sql, orderItem.getName(), orderItem.getCount(), orderItem.getPrice(), orderItem.getTotalPrice(), orderItem.getOrderId());
- }
-
- }
- public class OrderDaoTest {
- private OrderDao orderDao = new OrderDaoImpl();
-
- @Test
- public void saveOrder() {
- orderDao.saveOrder(new Order("1234567891",new Date(),new BigDecimal(100),0, 1));
- orderDao.saveOrder(new Order("12345678912",new Date(),new BigDecimal(100),0, 1));
- orderDao.saveOrder(new Order("1234567893",new Date(),new BigDecimal(100),0, 1));
- }
- }
- public class OrderItemDaoTest {
- private OrderItemDao orderItemDao = new OrderItemDaoImpl();
-
- @Test
- public void saveOrderItem() {
- orderItemDao.saveOrderItem(new OrderItem(null,"java 从入门到精通", 1,new BigDecimal(100),new BigDecimal(100),"1234567891"));
- orderItemDao.saveOrderItem(new OrderItem(null,"java 从入门到精通11", 1,new BigDecimal(1000),new BigDecimal(100),"12345678912"));
- orderItemDao.saveOrderItem(new OrderItem(null,"java 从入门到精通22", 1,new BigDecimal(10000),new BigDecimal(100),"1234567893"));
- }
- }
- public interface OrderService {
-
- public String createOrder(Cart cart, Integer userId);
- }
- public class OrderServiceImpl extends BaseDao implements OrderService {
- private OrderDao orderDao = new OrderDaoImpl();
- private OrderItemDao orderItemDao = new OrderItemDaoImpl();
-
- @Override
- public String createOrder(Cart cart, Integer userId) {
- // 获取唯一性的订单号
- String orderId = System.currentTimeMillis() + "" + userId;
-
- // 创建一个订单对象
- Order order = new Order(orderId, new Date(), cart.getTotalPrice(), 0, userId);
-
- // 保存订单
- orderDao.saveOrder(order);
-
- // 遍历购物车中每一个商品项转换成为订单项保存到数据库
- for (Map.Entry
item : cart.getItems().entrySet()) { - // 获取每一个购物车中的商品项
- CartItem cartItem = item.getValue();
- // 转换为每一个订单项
- OrderItem orderItem = new OrderItem(null, cartItem.getName(),
- cartItem.getCount(), cartItem.getPrice(), cartItem.getTotalPrice(), orderId);
- // 保存订单项到数据库
- orderItemDao.saveOrderItem(orderItem);
-
- }
- // 清空购物车
- cart.clear();
-
- // 返回订单号
- return orderId;
- }
- }
- public class OrderServiceTest {
- private OrderService orderService = new OrderServiceImpl();
-
- @Test
- public void createOrder() {
- Cart cart = new Cart();
- cart.addItem(new CartItem(1, "java从入门到精通", 1, new BigDecimal(1000), new BigDecimal(1000)));
- cart.addItem(new CartItem(1, "java从入门到精通", 1, new BigDecimal(1000), new BigDecimal(1000)));
- cart.addItem(new CartItem(2, "数据结构与算法", 1, new BigDecimal(100), new BigDecimal(100)));
- OrderService orderService = new OrderServiceImpl();
- System.out.println("订单号是:" + orderService.createOrder(cart, 1));
- }
- }
步骤:1. 编写OrderServlet 程序2. 修改 pages/cart/cart.jsp 页面,结账的请求地址3. 修改 pages/cart/checkout.jsp 页面,输出订单号
- @WebServlet(name = "OrderServlet ", value = "/orderServlet ")
- public class OrderServlet extends BaseServlet {
- private OrderService orderService = new OrderServiceImpl();
-
- protected void createOrder(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 先获取 Cart 购物车对象
- Cart cart = (Cart) request.getSession().getAttribute("cart");
-
- // 获取 Userid
- User loginUser = (User) request.getSession().getAttribute("user");
-
- // 判断用户是否存在,若不存在,则转发到登录界面
- if (loginUser == null) {
- request.getRequestDispatcher("/pages/user/login.jsp").forward(request, response);
- return;
- }
-
- // 调用 orderService.createOrder(Cart,Userid);生成订单 并返回订单号
- // 获取用户id
- Integer id = loginUser.getId();
- System.out.println(id);
- System.out.println(loginUser);
- String orderId = orderService.createOrder(cart, id);
-
- // 将订单号保存到Session域中
- request.getSession().setAttribute("orderId", orderId);
-
- // 将页面请求重定向到checkout.jsp界面
- response.sendRedirect(request.getContextPath() + "/pages/cart/checkout.jsp");
- }
-
- }
2. 修改 pages/cart/cart.jsp 页面,结账的请求地址
步骤:1. 编写OrderServlet 程序2. 修改 manager_menu.jsp 页面,订单管理的请求地址3. 修改 pages/manager/order_manager.jsp 页面,遍历订单
- /**
- * 查看所有订单
- *
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- protected void showAllOrders(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 1 通过 orderService 查询全部订单
- List
orders = orderService.showAllOrders(); -
- // 2 把全部订单保存到 Request 域中
- request.setAttribute("orders", orders);
-
- // 3、请求转发到/pages/order/order.jsp 页面
- request.getRequestDispatcher("/pages/manager/order_manager.jsp").forward(request, response);
-
- }
2. 修改 manager_menu.jsp 页面,订单管理的请求地址
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>订单管理title>
- <%@include file="/pages/common/head.jsp"%>
- head>
- <body>
-
- <div id="header">
- <img class="logo_img" alt="" src="static/img/logo.gif">
- <span class="wel_word">订单管理系统span>
- <%@include file="/pages/common/manager_menu.jsp"%>
- div>
- <div id="main">
- <table>
- <tr>
- <td>日期td>
- <td>金额td>
- <td>详情td>
- <td>发货td>
- tr>
-
- <c:forEach items="${requestScope.orders}" var="order">
- <tr>
- <td>${order.createTime}td>
- <td>${order.price}td>
- <td><a href="#">查看详情a>td>
- <c:if test="${order.status == 0}">
- <td><a href="orderServlet?action=sendOrder&orderId=${order.orderId}">点击发货a>td>
- c:if>
-
- <c:if test="${order.status == 1}">
- <td>等待收货td>
- c:if>
-
- <c:if test="${order.status == 2}">
- <td>已完成td>
- c:if>
-
- tr>
- c:forEach>
-
- table>
- div>
-
- <%@include file="/pages/common/footer.jsp"%>
- body>
- html>
步骤:1. 修改 pages/manager/order_manager.jsp 页面,点击发货的请求地址2. 编写OrderServlet 程序
2. 编写OrderServlet 程序
- /**
- * 管理员发货功能
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- protected void sendOrder(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 获取参数 orderId
- String orderId = request.getParameter("orderId");
-
- orderService.sendOrder(orderId);
-
- response.sendRedirect(request.getHeader("Referer"));
- }
步骤:1. 修改order_manager.jsp 和 order.jsp页,给查看详情添加请求地址2. 编写OrderServlet 程序3. 修改order_detail页面,遍历数据
1.修改order_manager.jsp 和 order.jsp页,给查看详情添加请求地址

2. 编写OrderServlet 程序
- /**
- * 查看订单详情
- *
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- protected void showOrderDetail(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 获取参数 orderId
- String orderId = request.getParameter("orderId");
-
- // 获取订单的详情信息
- List
orderItems = orderService.showOrderDetail(orderId); -
- // 将订单的详情信息保存到Request域中
- request.setAttribute("orderItems", orderItems);
-
- // 请求转发到订单详情页面中
- request.getRequestDispatcher("/pages/order/order_detail.jsp").forward(request, response);
- }
3. 修改order_detail页面,遍历数据
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>订单详情title>
- <%@include file="/pages/common/head.jsp" %>
- head>
- <body>
-
- <div id="header">
- <img class="logo_img" alt="" src="static/img/logo.gif">
- <span class="wel_word">订单详情span>
- <%@include file="/pages/common/success_menu.jsp" %>
- div>
-
- <div id="main">
-
- <table>
-
- <tr>
- <td>商品名称td>
- <td>数量td>
- <td>单价td>
- <td>金额td>
- tr>
- <c:if test="${empty requestScope.orderItems}">
- <tr>
- <td colspan="5">
- <a href="index.jsp">暂无订单a>
- td>
- tr>
- c:if>
- <c:if test="${not empty requestScope.orderItems}">
-
- <c:forEach items="${requestScope.orderItems}" var="item">
- <tr>
- <td>${item.name}td>
- <td>${item.count}td>
- <td>${item.price}td>
- <td>${item.totalPrice}td>
- tr>
- c:forEach>
- c:if>
-
- table>
-
- div>
-
- <%@include file="/pages/common/footer.jsp" %>
- body>
- html>
步骤:1. 修改success_menu.jsp和index.jsp页面,给 我的订单 添加请求地址2. 编写OrderServlet 程序3. 修改order页面,遍历数据
- /**
- * 查看我的订单
- *
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- protected void showMyOrders(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 获取参数 orderId
- int userId = WebUtils.parseInt(request.getParameter("userId"), 0);
-
- if (userId != 0) {
- // 获取订单的详情信息
- List
myOrders = orderService.showMyOrders(userId); -
- // 将订单信息保存到Request域中
- request.setAttribute("myOrders",myOrders);
-
- // 请求转发到我的订单页面中
- request.getRequestDispatcher("/pages/order/order.jsp").forward(request,response);
- }
- }
3. 修改order页面,遍历数据
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>我的订单title>
- <%@include file="/pages/common/head.jsp" %>
- <style type="text/css">
- h1 {
- text-align: center;
- margin-top: 200px;
- }
- style>
- head>
- <body>
-
- <div id="header">
- <img class="logo_img" alt="" src="static/img/logo.gif">
- <span class="wel_word">我的订单span>
- <%@include file="/pages/common/success_menu.jsp" %>
- div>
- <div id="main">
-
- <table>
- <tr>
- <td>订单编号td>
- <td>日期td>
- <td>金额td>
- <td>状态td>
- <td>详情td>
- tr>
- <c:forEach items="${requestScope.myOrders}" var="order">
- <tr>
- <td>${order.orderId}td>
- <td>${order.createTime}td>
- <td>${order.price}td>
- <c:if test="${order.status == 0}">
- <td>未发货td>
- c:if>
- <c:if test="${order.status == 1}">
- <td><a href="orderServlet?action=receiverOrder&orderId=${order.orderId}">确认收货a> td>
- c:if>
- <c:if test="${order.status == 2}">
- <td>已完成td>
- c:if>
- <td><a href="orderServlet?action=showOrderDetail&orderId=${order.orderId}">查看详情a>td>
- tr>
- c:forEach>
- table>
- div>
-
- <%@include file="/pages/common/footer.jsp" %>
- body>
- html>
步骤:1. 修改order.jsp页面,给 确认收货 添加a标签及请求地址2. 编写OrderServlet 程序

- /**
- * 签收订单功能
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- protected void receiverOrder(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 获取参数 orderId
- String orderId = request.getParameter("orderId");
- orderService.receiverOrder(orderId);
- response.sendRedirect(request.getHeader("Referer"));
- }
-
- @WebFilter(filterName = "ManagerFilter")
- public class ManagerFilter implements Filter {
- public void init(FilterConfig config) throws ServletException {
- }
-
- public void destroy() {
- }
-
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
- HttpServletRequest req = (HttpServletRequest) request;
-
- Object user = req.getSession().getAttribute("user");
-
- if (user == null) {
- request.getRequestDispatcher("/pages/user/login.jsp").forward(request, response);
- return;
- }else{
- chain.doFilter(request, response);
- }
- }
- }
xml代码:
- <filter>
- <filter-name>ManagerFilterfilter-name>
- <filter-class>com.chenyixin.book.filter.ManagerFilterfilter-class>
- filter>
- <filter-mapping>
- <filter-name>ManagerFilterfilter-name>
- <url-pattern>/pages/manager/*url-pattern>
- <url-pattern>/manager/bookServleturl-pattern>
- filter-mapping>
原理示意图
-
- public class JdbcUtils {
- private static DruidDataSource dataSource;
- private static ThreadLocal
threadLocal = new ThreadLocal<>(); -
- // 在静态代码块中创建数据库连接
- static {
- try {
- // 获取配置文件jdbc.properties对象
- Properties properties = new Properties();
-
- // 读取jdbc.properties属性配置文件
- InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
-
- // 从流中加载数据
- properties.load(inputStream);
-
- // 创建数据库连接池
- dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- /**
- * 获取数据库连接池中的连接
- *
- * @return 如果返回 null,说明获取连接失败
有值就是获取连接成功 - */
- public static Connection getConnection() {
- Connection conn = threadLocal.get();
- if (conn == null) {
- try {
- conn = dataSource.getConnection(); //从数据库连接池中获取连接
- threadLocal.set(conn); // 保存到 ThreadLocal 对象中,供后面的 jdbc 操作使用
- conn.setAutoCommit(false); // 设置手动管理事务
- } catch (SQLException e) {
- throw new RuntimeException(e);
- }
- }
- return conn;
- }
-
- /**
- * 提交事务,并关闭释放连接
- */
- public static void commitAndClose(){
- Connection conn = threadLocal.get();
- if (conn != null) { // 如果不等于 null,说明 之前使用过连接,操作过数据库
- try {
- conn.commit(); //提交事务
- } catch (SQLException e) {
- e.printStackTrace();
- }finally {
- try {
- conn.close(); // 关闭资源
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- // 一定要执行 remove 操作,否则就会出错。(因为 Tomcat 服务器底层使用了线程池技术)
- threadLocal.remove();
- }
-
- /**
- * 回滚事务,并关闭释放连接
- */
- public static void rollbackAndClose(){
- Connection conn = threadLocal.get();
-
- if (conn != null) { // 如果不等于 null,说明 之前使用过连接,操作过数据库
- try {
- conn.commit(); //回滚事务
- } catch (SQLException e) {
- e.printStackTrace();
- }finally {
- try {
- conn.close(); // 关闭资源
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- // 一定要执行 remove 操作,否则就会出错。(因为 Tomcat 服务器底层使用了线程池技术)
- threadLocal.remove();
- }
-
- /**
- * 关闭连接,放回数据库连接池
- *
- * @param connection 放入要关闭的连接对象
- */
- // public static void close(Connection connection) {
- // try {
- // if (connection != null) {
- // connection.close();
- // }
- // } catch (SQLException e) {
- // e.printStackTrace();
- // }
- // }
- }
-
- public abstract class BaseDao {
- private final QueryRunner queryRunner = new QueryRunner();
-
-
- /**
- * 用来执行:Insert\Update\Delete 语句
- *
- * @param sql 传入要执行的sql语句
- * @param args 参数列表
- * @return 返回-1表示update失败,否则成功
- */
- public int update(String sql, Object... args) {
- Connection conn = JdbcUtils.getConnection();
- try {
- return queryRunner.update(conn, sql, args);
- } catch (SQLException e) {
- throw new RuntimeException(e);
- }
- }
-
-
- /**
- * 查询返回一个 javaBean 的 sql 语句
- * @param type 返回的对象类型
- * @param sql 执行的 sql 语句
- * @param args sql 对应的参数值
- * @param
返回的类型的泛型 - * @return 若返回为null,则查看失败
- */
- public
T queryForOne(Class type, String sql, Object... args) { - Connection conn = JdbcUtils.getConnection();
- try {
- return queryRunner.query(conn, sql, new BeanHandler
(type), args); - } catch (SQLException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * 查询返回多个 javaBean 的 sql 语句
- *
- * @param type 返回的对象类型
- * @param sql 执行的 sql 语句
- * @param args sql 对应的参数值
- * @param
返回的类型的泛型 - * @return 若返回为null, 则查看失败
- */
- public
List queryForList(Class type, String sql, Object... args) { - Connection conn = JdbcUtils.getConnection();
- try {
- return queryRunner.query(conn, sql, new BeanListHandler
(type), args); - } catch (SQLException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * 执行返回一行一列的 sql 语句
- * @param sql 执行的 sql 语句
- * @param args sql对应的参数
- * @return 若返回为null, 则查看失败
- */
- public Object queryForSingleValue(String sql,Object... args) {
- Connection conn = JdbcUtils.getConnection();
- try {
- return queryRunner.query(conn,sql,new ScalarHandler(),args);
- } catch (SQLException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- public class TransactionFilter implements Filter {
- public void init(FilterConfig config) throws ServletException {
- }
-
- public void destroy() {
- }
-
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
- try {
- chain.doFilter(request, response);
- JdbcUtils.commitAndClose(); // 提交事务
- } catch (Exception e) {
- JdbcUtils.rollbackAndClose(); // 回滚事务
- e.printStackTrace();
- }
- }
- }
- <filter>
- <filter-name>TransactionFilterfilter-name>
- <filter-class>com.chenyixin.book.filter.TransactionFilterfilter-class>
- filter>
- <filter-mapping>
- <filter-name>TransactionFilterfilter-name>
-
- <url-pattern>/*url-pattern>
- filter-mapping>
- @Override
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 解决post请求中文乱码问题
- // 一定要在获取请求参数之前调用才有效
- request.setCharacterEncoding("UTF-8");
-
- String action = request.getParameter("action");
- // 获取 action 业务鉴别字符串,获取相应的业务 方法反射对象
- try {
- Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
- // 调用目标业务 方法
- method.invoke(this, request, response);
- } catch (Exception e) {
- // e.printStackTrace();
- throw new RuntimeException(e);
- }
- }
- <error-page>
-
- <error-code>404error-code>
-
- <location>/pages/error/error404.jsplocation>
- error-page>
- <error-page>
- <error-code>500error-code>
- <location>/pages/error/error500.jsplocation>
- error-page>
error404.jsp页面:
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>error404title>
- <%-- 静态包含 base标签、css样式、jQuery文件 --%>
- <%@ include file="/pages/common/head.jsp"%>
-
- head>
- <body>
- <h1>很抱歉。您访问的页面不存在,或已经被删除!!! h1><br/>
- <h1><a href="index.jsp">返回首页a>h1>
-
- body>
- html>
error500.jsp页面:
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>error404title>
- <%-- 静态包含 base标签、css样式、jQuery文件 --%>
- <%@ include file="/pages/common/head.jsp"%>
-
- head>
- <body>
- <h1>很抱歉,您访问的后台程序出现了错误,程序猿小哥,正在努力的为您抢修!!! h1><br/>
- <h1><a href="index.jsp">返回首页a>h1>
-
- body>
- html>
步骤:
1.在UserServlet 程序中添加 ajaxExistsUsername 方法
2. regist.jsp 页面中的代码
- /**
- * 注册用户名的失去焦点事件,判断用户名是否存在
- *
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- protected void ajaxExistsUsername(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 获取请求的参数 username
- String username = request.getParameter("username");
-
- // 调用 userService.existsUsername();
- boolean existsUsername = userService.existsUsername(username);
-
- // 把返回的结果封装成为 map 对象
- Map
map = new HashMap<>(); - map.put("existsUsername", existsUsername);
-
- Gson gson = new Gson();
- String json = gson.toJson(map);
- response.getWriter().write(json);
-
- }
2. regist.jsp 页面中的代码
- // 给用户名添加失去焦点事件
- $("#username").blur(function () {
- // 获取用户名
- var username = this.value;
- if (username != "") {
- $.getJSON("userServlet", "action=ajaxExistsUsername&username=" + username, function (data) {
- if (data.existsUsername) {
- $("span.errorMsg").text("用户名已存在!");
- } else {
- $("span.errorMsg").text("用户名可用!");
- }
- });
- } else {
- $("span.errorMsg").text("用户名不能为空!");
- }
- });

- /**
- * 加入购物车
- *
- * @param request
- * @param response
- * @throws ServletException
- * @throws IOException
- */
- protected void ajaxAddItem(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // 1. 获取请求的参数 商品编号
- int id = WebUtils.parseInt(request.getParameter("id"), 0);
-
- // 2. 调用 bookService.queryBookById(id):Book 得到图书的信息
- Book book = bookService.queryBookById(id);
-
- // 3. 把图书信息,转换成为 CartItem 商品项
- CartItem cartItem = new CartItem(book.getId(), book.getName(), 1, book.getPrice(), book.getPrice());
-
- // 4. 调用 Cart.addItem(CartItem);添加商品项
- Cart cart = (Cart) request.getSession().getAttribute("cart");
- if (cart == null) {
- cart = new Cart();
- request.getSession().setAttribute("cart", cart);
- }
- cart.addItem(cartItem);
-
- // 最后一个添加商品的名称
- request.getSession().setAttribute("lastName", cartItem.getName());
-
- // 返回购物车总的商品数量和最后一个添加的商品名称
- Map
map = new HashMap<>(); - map.put("totalCount", cart.getTotalCount());
- map.put("lastName", cartItem.getName());
-
- Gson gson = new Gson();
- String resultMapJsonString = gson.toJson(map);
-
- response.getWriter().write(resultMapJsonString);
-
-
- }
index.jsp页面
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
-
- html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>书城首页title>
- <%@include file="/pages/common/head.jsp" %>
- <script type="text/javascript">
- $(function () {
- $(".addToCart").click(function () {
- /**
- * 在事件响应的 function 函数 中,有一个 this 对象,这个 this 对象,是当前正在响应事件的 dom 对象
- * attr() 可以设置和获取属性的值
- * location.href: 返回当前页面的完整的URL地址;
- */
- var bookId = $(this).attr("bookId");
- // location.href = "cartServlet?action=addItem&id=" + bookId;
- $.getJSON("cartServlet", "action=ajaxAddItem&id=" + bookId, function (data) {
- $(".totalCount").text("您的购物车中有" + data.totalCount + "件商品");
- $(".lastName").text(data.lastName);
-
- });
- });
- });
- script>
- head>
- <body>
-
- <div id="header">
- <img class="logo_img" alt="" src="static/img/logo.gif">
- <span class="wel_word">网上书城span>
- <div>
- <c:if test="${empty sessionScope.user}">
- <a href="pages/user/login.jsp">登录a> |
- <a href="pages/user/regist.jsp">注册a>
- c:if>
- <c:if test="${not empty sessionScope.user}">
- <span>欢迎<span class="um_span">${sessionScope.user.username}span>光临尚硅谷书城span>
- <a href="orderServlet?action=showMyOrders&userId=${sessionScope.user.id}">我的订单a>
- <a href="userServlet?action=logout">注销a>
- c:if>
- <a href="pages/cart/cart.jsp">购物车a>
- <a href="pages/manager/manager.jsp">后台管理a>
- div>
- div>
- <div id="main">
- <div id="book">
- <div class="book_cond">
- <form action="client/bookServlet" method="get">
- <input type="hidden" name="action" value="pageByPrice"/>
- 价格:<input id="min" type="text" name="min" value="${param.min}"> 元 -
- <input id="max" type="text" name="max" value="${param.max}"> 元
- <input type="submit" value="查询"/>
- form>
- div>
- <c:if test="${empty sessionScope.cart.items}">
- <div style="text-align: center">
- <span class="totalCount"> span>
- <div>
- <span class="lastName" style="color: red">您当前的购物车里没有商品哦span>
- div>
- div>
- c:if>
- <c:if test="${not empty sessionScope.cart.items}">
- <div style="text-align: center">
- <span class="totalCount">您的购物车中有${sessionScope.cart.totalCount}件商品span>
- <div>
- 您刚刚将<span class="lastName" style="color: red">${sessionScope.lastName}span>加入到了购物车中
- div>
- div>
- c:if>
-
-
- <%-- 书籍的开始 --%>
- <c:forEach items="${requestScope.page.items}" var="book">
- <div class="b_list">
- <div class="img_div">
- <img class="book_img" alt="" src="${book.img_path}"/>
- div>
- <div class="book_info">
- <div class="book_name">
- <span class="sp1">书名:span>
- <span class="sp2">${book.name}span>
- div>
- <div class="book_author">
- <span class="sp1">作者:span>
- <span class="sp2">${book.author}span>
- div>
- <div class="book_price">
- <span class="sp1">价格:span>
- <span class="sp2">¥${book.price}span>
- div>
- <div class="book_sales">
- <span class="sp1">销量:span>
- <span class="sp2">${book.sales}span>
- div>
- <div class="book_amount">
- <span class="sp1">库存:span>
- <span class="sp2">${book.stock}span>
- div>
- <div class="book_add">
- <button bookId="${book.id}" class="addToCart">加入购物车button>
- div>
- div>
- div>
- c:forEach>
- <%-- 书籍的结束 --%>
-
- div>
-
- <%-- 分页条的开始 --%>
- <%@include file="/pages/common/nav.jsp" %>
- <%-- 分页条的结束 --%>
-
- div>
- <%@include file="/pages/common/footer.jsp" %>
- body>
- html>