家居网购项目(权限验证+事务管理)

文章目录

    • 1.过滤器权限认证
        • 1.程序框架图
        • 2.web.xml
        • 3.编写AdminAuthorization
        • 4.编写MemberAuthorization
        • 5.细节
        • 6.结果展示
          • 1.未登录可以任意浏览商品
          • 2.点击添加购物车提示登录
          • 3.点击后台管理,提示管理员登录
          • 4.也做了其余资源的访问验证
    • 2.事务管理
        • 1.思路分析
        • 2.重写JDBCUtilsByDruid
          • 1.getConnection()方法
          • 2.commit()方法
          • 3.rollback()方法
          • 4.删除BasicDao中的所有关闭数据库连接的语句
          • 5.编写过滤器TransactionFilter
          • 6.配置web.xml
          • 7.查看调用可能出现问题的方法是不是抛出了异常
        • 3.结果展示
          • 1.将OrderDaoImpl中的sql故意写错
          • 2.执行保存订单操作
          • 3.查看数据库信息(回滚了,没有生成记录)
    • 3.统一错误页面
        • 1.需求分析
        • 2.修改web.xml
        • 3.导入两个页面
        • 4.修改TransactionFilter,将异常抛给tomcat
        • 5.结果展示
    • 4.会员订单管理—分页查询
        • 需求分析
        • 1.编写dao层
          • 1.修改OrderDao
          • 2.修改OrderDaoImpl
          • 3.单元测试
        • 2.编写service层
          • 1.修改OrderService
          • 2.修改OrderServiceImpl
          • 3.单元测试
        • 3.编写web层
          • 1.修改OrderServlet
          • 2.修改order_manage.jsp
            • 1.显示信息
            • 2.分页导航条
        • 4.结果演示
          • 1.会员登录
          • 2.会员点击订单管理只会显示当前会员的历史订单
    • 5.管理员订单管理—分页查询
        • 需求分析
        • 1.编写dao层
          • 1.修改OrderDao
          • 2.修改OrderDaoImpl
        • 2.编写service层
          • 1.修改OrderService
          • 2.修改OrderServiceImpl
        • 3.编写web层
          • 1.修改OrderServlet
          • 2.修改order_manage.jsp
            • 1.显示信息
            • 2.分页导航条
        • 4.结果展示

1.过滤器权限认证

1.程序框架图

image-20240211092524610

2.web.xml
    <filter><filter-name>AdminAuthorization</filter-name><filter-class>com.sxs.furns.filter.AdminAuthorization</filter-class><init-param><!--设置排除的uri--><param-name>excludeUrls</param-name><param-value>/jiaju_mail/views/manage/manage_login.jsp</param-value></init-param></filter><!--除了登录的管理员页面都要进行管理员验证--><filter-mapping><filter-name>AdminAuthorization</filter-name><url-pattern>/views/manage/*</url-pattern></filter-mapping><!--家居管理--><filter-mapping><filter-name>AdminAuthorization</filter-name><url-pattern>/manage/furnServlet/*</url-pattern></filter-mapping><filter><filter-name>MemberAuthorization</filter-name><filter-class>com.sxs.furns.filter.MemberAuthorization</filter-class></filter><!--登录成功的界面,需要普通权限验证--><filter-mapping><filter-name>MemberAuthorization</filter-name><url-pattern>/views/member/login_ok.jsp</url-pattern></filter-mapping><!--所有的购物车界面,需要普通权限验证--><filter-mapping><filter-name>MemberAuthorization</filter-name><url-pattern>/views/cart/*</url-pattern></filter-mapping><!--购物车和订单servlet,需要普通权限验证--><filter-mapping><filter-name>MemberAuthorization</filter-name><url-pattern>/orderServlet/*</url-pattern></filter-mapping><filter-mapping><filter-name>MemberAuthorization</filter-name><url-pattern>/cartServlet/*</url-pattern></filter-mapping>
3.编写AdminAuthorization
package com.sxs.furns.filter;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;/*** @author 孙显圣* @version 1.0*/
public class AdminAuthorization implements Filter {private List<String> excludeUrlsList = new ArrayList<>(); //排除的资源@Overridepublic void init(FilterConfig filterConfig) throws ServletException {//读取配置文件中的信息String excludeUrls = filterConfig.getInitParameter("excludeUrls");//按照,分割,并添加到集合中String[] split = excludeUrls.split(",");for (String s : split) {excludeUrlsList.add(s);}//放到servletContext中ServletContext servletContext = filterConfig.getServletContext();servletContext.setAttribute("excludeUrls", excludeUrlsList);}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//查看session中的admin是否为trueHttpSession session = ((HttpServletRequest) servletRequest).getSession();Object admin = session.getAttribute("admin");//获取uriString requestURI = ((HttpServletRequest) servletRequest).getRequestURI();//获取排除的uriList<String> excludeUrls = (List<String>) servletRequest.getServletContext().getAttribute("excludeUrls");//遍历并匹配for (String excludeUrl : excludeUrls) {System.out.println(excludeUrl);//如果匹配直接放行if (excludeUrl.equals(requestURI)) {filterChain.doFilter(servletRequest, servletResponse);return;}}if (admin != null) {//放行filterChain.doFilter(servletRequest, servletResponse);} else {//重定向到管理员登录界面((HttpServletResponse) servletResponse).sendRedirect("/jiaju_mail/views/manage/manage_login.jsp");}}@Overridepublic void destroy() {}
}
4.编写MemberAuthorization
package com.sxs.furns.filter;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;/*** 普通权限认证* @author 孙显圣* @version 1.0*/
public class MemberAuthorization implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpSession session = ((HttpServletRequest) servletRequest).getSession();//进行普通权限认证Object username = session.getAttribute("username");Object admin = session.getAttribute("admin");if (username != null || admin != null) {System.out.println("普通权限验证成功!");//放行filterChain.doFilter(servletRequest, servletResponse);} else {//重定向到用户登录界面((HttpServletResponse) servletResponse).sendRedirect("/jiaju_mail/views/member/login.jsp");}}@Overridepublic void destroy() {}
}
5.细节

如果想要过滤一个文件夹下除了某个资源的其余资源,可以将排除的资源URI其放在init-param中,然后通过filter的init方法将其放到servletContext中,然后在doFilter中直接放行

6.结果展示
1.未登录可以任意浏览商品

image-20240211114953238

2.点击添加购物车提示登录

image-20240211115035714

image-20240211115041741

3.点击后台管理,提示管理员登录

image-20240211115128144

image-20240211115115218

4.也做了其余资源的访问验证

2.事务管理

1.思路分析

image-20240211142121222

image-20240211142140091

2.重写JDBCUtilsByDruid
1.getConnection()方法
    private static ThreadLocal<Connection> threadLocalConn = new ThreadLocal<>(); //用于存放本线程的连接//重写getConnection方法,使其每个线程获取的是同一个连接public static Connection getConnection() {try {Connection connection = threadLocalConn.get(); //从threadlocal中获取当前线程的连接//如果没有获取到,则放入一个连接if (connection == null) {connection = dataSource.getConnection();connection.setAutoCommit(false); //取消自动提交threadLocalConn.set(connection);}return connection;} catch (SQLException e) {throw new RuntimeException(e);}}
2.commit()方法
    //提交事务public static void commit() {//获取连接Connection connection = threadLocalConn.get();//如果连接有效则提交事务并关闭连接if (connection != null) {try {connection.commit();} catch (SQLException e) {throw new RuntimeException(e);} finally {try {connection.close();} catch (SQLException e) {throw new RuntimeException(e);}}}//清除threadlocal的连接threadLocalConn.remove();}
3.rollback()方法
    //回滚事务public static void rollback() {Connection connection = threadLocalConn.get();if (connection != null) {try {connection.rollback();} catch (SQLException e) {throw new RuntimeException(e);} finally {try {connection.close();} catch (SQLException e) {throw new RuntimeException(e);}}}threadLocalConn.remove();}
4.删除BasicDao中的所有关闭数据库连接的语句

原因:数据库连接的关闭,交给最后提交事务或者回滚事务的时候再执行

image-20240211152822089

5.编写过滤器TransactionFilter
package com.sxs.furns.filter;import com.sxs.furns.utils.JDBCUtilsByDruid;import javax.servlet.*;
import java.io.IOException;/*** @author 孙显圣* @version 1.0*/
public class TransactionFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain){//首先放行try {filterChain.doFilter(servletRequest, servletResponse);JDBCUtilsByDruid.commit();} catch (Exception e) {//如果在这次线程中有异常发生,则回滚System.out.println("发现异常,事务回滚!");JDBCUtilsByDruid.rollback();}}@Overridepublic void destroy() {}
}
6.配置web.xml
    <!--在权限验证之后再编写事务过滤器--><filter><filter-name>TransactionFilter</filter-name><filter-class>com.sxs.furns.filter.TransactionFilter</filter-class></filter><!--对所有请求进行过滤--><filter-mapping><filter-name>TransactionFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
7.查看调用可能出现问题的方法是不是抛出了异常

所有的servlet都是basicservlet反射调用的,并且都抛出了异常,这个异常最后会经过过滤器,所以可以在过滤器中捕获到异常

image-20240211153711602

3.结果展示
1.将OrderDaoImpl中的sql故意写错

image-20240211154703922

2.执行保存订单操作

image-20240211165406002

image-20240211165420900

image-20240211165433434

3.查看数据库信息(回滚了,没有生成记录)

image-20240211165458599

image-20240211165508047

3.统一错误页面

1.需求分析

image-20240211170301996

2.修改web.xml
    <!--配置错误页面--><error-page><error-code>404</error-code><location>/views/error/404.jsp</location></error-page><error-page><error-code>500</error-code><location>/views/error/500.jsp</location></error-page>
3.导入两个页面

image-20240211171312340

4.修改TransactionFilter,将异常抛给tomcat

image-20240211171629237

5.结果展示

image-20240211171404475

image-20240211171743485

4.会员订单管理—分页查询

需求分析

可以返回已登录的会员的历史订单信息

1.编写dao层
1.修改OrderDao
    //3.获取当前页需要展示的数据public List<Order> getPageItems(int begin, int pageSize, String id);//4.获取一共的记录条数public Integer getTotalRow(String id);
2.修改OrderDaoImpl
    /*** 分页查询订单* @param begin* @param pageSize* @return*/@Overridepublic List<Order> getPageItems(int begin, int pageSize, String id) {String sql = "select id, create_time as createTime, price, status, member_id as memberId from `order` where id like ? limit ?, ?";return queryMulti(sql, Order.class, "%-" + id , begin, pageSize);}/*** 获取总记录条数* @return*/@Overridepublic Integer getTotalRow(String id) {String sql = "select count(*) from `order` where id like ?";return ((Number) queryScalar(sql,"%-" + id)).intValue();}
3.单元测试
    @Testpublic void getPageItems() {//查询id为1的会员的订单信息List<Order> pageItems = orderDao.getPageItems(0, 3, "1");for (Order pageItem : pageItems) {System.out.println(pageItem);}}@Testpublic void getTotalRow() {System.out.println("总的记录数为:" + orderDao.getTotalRow("1"));}

image-20240211193017269

image-20240211200733207

2.编写service层
1.修改OrderService
    //3.分页显示订单public Page<Order> getPageItems(int pageNo, int pageSize, String username);
2.修改OrderServiceImpl
    /*** 根据当前页号和分页的大小返回对应的page对象** @param pageNo* @param pageSize* @return*/@Overridepublic Page<Order> getPageItems(int pageNo, int pageSize, String username) {//根据姓名获取用户idMember member = memberDao.queryMemberByUsername(username);//获取总记录数Integer totalRow = orderDao.getTotalRow(member.getId().toString());//计算总页数Integer pageTotalCount = totalRow / pageSize;if (totalRow % pageSize > 0) {pageTotalCount ++;}//计算beginint begin = (pageNo - 1) * pageSize;//获取当页的所有数据List<Order> pageItems = orderDao.getPageItems(begin, pageSize, member.getId().toString());//填充pagePage<Order> orderPage = new Page<>();orderPage.setPageNo(pageNo);orderPage.setPageSize(pageSize);orderPage.setPageTotalCount(pageTotalCount);orderPage.setTotalRow(totalRow);orderPage.setItems(pageItems);return orderPage;}
3.单元测试
    OrderService orderService = new OrderServiceImpl();@Testpublic void getPageItems() {Page<Order> pageItems = orderService.getPageItems(1, 3, "admin");System.out.println(pageItems);}

image-20240211194809877

3.编写web层
1.修改OrderServlet
    //分页显示订单public void showPageItems(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取数据Integer pageNo = DataUtils.parseInt(req.getParameter("pageNo"), 1); //默认第一页Integer pageSize = DataUtils.parseInt(req.getParameter("pageSize"), 6); //默认六条记录String username = req.getParameter("username");//获取page对象Page<Order> page = orderService.getPageItems(pageNo, pageSize, username);//请求转发req.setAttribute("page", page);req.getRequestDispatcher("/views/order_manage/order_manage.jsp").forward(req, resp);}
2.修改order_manage.jsp
1.显示信息

image-20240211201128675

2.分页导航条

image-20240211201147642

4.结果演示
1.会员登录

image-20240211202317112

2.会员点击订单管理只会显示当前会员的历史订单

image-20240211202415806

5.管理员订单管理—分页查询

需求分析

管理员的订单管理,显示的是所有会员的订单

1.编写dao层
1.修改OrderDao
    //5.管理员获取总体的记录条数public Integer getTotalRow();//6.管理员获取当前页需要展示的数据public List<Order> getPageItems(int begin, int pageSize);
2.修改OrderDaoImpl
    @Overridepublic Integer getTotalRow() {String sql = "select count(*) from `order`";return ((Number) queryScalar(sql)).intValue();}@Overridepublic List<Order> getPageItems(int begin, int pageSize) {String sql = "select id, create_time as createTime, price, status, member_id as memberId from `order` limit ?, ?";return queryMulti(sql, Order.class, begin, pageSize);}
2.编写service层
1.修改OrderService
    //4.管理员分页显示订单public Page<Order> getPageItems(int pageNo, int pageSize);
2.修改OrderServiceImpl
    @Overridepublic Page<Order> getPageItems(int pageNo, int pageSize) {//获取总记录数Integer totalRow = orderDao.getTotalRow();//计算总页数Integer pageTotalCount = totalRow / pageSize;if (totalRow % pageSize > 0) {pageTotalCount ++;}//计算beginint begin = (pageNo - 1) * pageSize;//获取当页的所有数据List<Order> pageItems = orderDao.getPageItems(begin, pageSize);//填充pagePage<Order> orderPage = new Page<>();orderPage.setPageNo(pageNo);orderPage.setPageSize(pageSize);orderPage.setPageTotalCount(pageTotalCount);orderPage.setTotalRow(totalRow);orderPage.setItems(pageItems);return orderPage;}
3.编写web层
1.修改OrderServlet
    //管理员分页显示订单public void showAllPageItems(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取数据Integer pageNo = DataUtils.parseInt(req.getParameter("pageNo"), 1); //默认第一页Integer pageSize = DataUtils.parseInt(req.getParameter("pageSize"), 6); //默认六条记录//获取page对象Page<Order> page = orderService.getPageItems(pageNo, pageSize);//请求转发req.setAttribute("page", page);req.getRequestDispatcher("/views/manage/order_manage.jsp").forward(req, resp);}
2.修改order_manage.jsp
1.显示信息

image-20240211211148413

2.分页导航条

image-20240211211203728

4.结果展示

image-20240211211304583

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/310398.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git am XXX.patch 文件内容解析

git am XXX.patch 文件内容解析 打补丁的两种方式&#xff1a; 1.patch XXX.patch 2.git am XXX.patch 例如&#xff1a; diff --git a/drivers/crypto/se/ce.c b/drivers/crypto/se/ce.c index e6f68286d4ce6..de1bcb46fbe6b 100644 --- a/drivers/crypto/se/ce.cb/drive…

品牌百度百科词条创建多少钱?

百度百科作为国内最具权威和影响力的知识型平台&#xff0c;吸引了无数品牌和企业争相入驻。一个品牌的百度百科词条&#xff0c;不仅是对品牌形象的一种提升&#xff0c;更是增加品牌曝光度、提高品牌知名度的重要途径。品牌百度百科词条创建多少钱&#xff0c;这成为了许多企…

【vue】ref 和 reactive 对比

ref&#xff1a;存储单个数据&#xff0c;如数值&#xff0c;字符串reactive&#xff1a;存储复杂数据&#xff0c;如对象&#xff0c;数组 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"vie…

《QT实用小工具·二十六》运行时间记录

1、概述 源码放在文章末尾 运行时间记录&#xff0c;包含如下功能&#xff1a; 可以启动和停止服务&#xff0c;在需要的时候启动。 可以指定日志文件存放目录。 可以指定时间日志输出间隔。 可以单独追加一条记录到日志文件。 日志为文本格式&#xff0c;清晰明了。 软…

《前端面试题》- JS基础 - 伪数组

第一次听说伪数组这个概念&#xff0c;听到的时候还以为是说CSS的伪类呢&#xff0c;网上一查&#xff0c;这东西原来还是个很常见的家伙。 何为伪数组 伪数组有两个特点&#xff1a; 具有length属性&#xff0c;其他属性&#xff08;索引&#xff09;为非负整数但是却不具备…

使用DockerCompose配置基于哨兵模式的redis主从架构集群

文章目录 一、注意事项&#xff08;坑点&#xff01;&#xff01;&#xff01;&#xff09;二、配置Redis主从架构集群第一步&#xff1a;创建目录文件结构第二步&#xff1a;编写DockerCompose配置文件第三步&#xff1a;编写redis.conf第四步&#xff1a;启动redis主从集群 三…

Kubernetes 升级不弃 Docker:KubeKey 的丝滑之道

作者&#xff1a;尹珉&#xff0c;KubeSphere Ambaasador&Contributor&#xff0c;KubeSphere 社区用户委员会杭州站站长。 引言 随着 Kubernetes 社区的不断发展&#xff0c;即将迎来 Kubernetes 1.30 版本的迭代。在早先的 1.24 版本中&#xff0c;社区作出一个重要决策…

SysTick滴答定时器 - 延时函数

SysTick定时器 Systick定时器&#xff0c;是一个简单的定时器&#xff0c;对于CM3,CM4内核芯片&#xff0c;都有Systick定时器。Systick定时器常用来做延时&#xff0c;或者实时系统的心跳时钟。这样可以节省MCU资源&#xff0c;不用浪费一个定时器。比如UCOS中&#xff0c;分…

Windows10为Git Bash添加文件传输命令rsync(详细图文配置)

文章目录 1. 安装git bash2. 下载所需要的4个包3. 下载解压包的软件4. 复制每个包下面的usr到git安装目录下4.1 所遇问题4.2 解决 5. 安装完成6. 需要注意 Windows上要使用 rsync命令上传或下载文件&#xff0c;需要使用git bash&#xff0c;git bash没有rsync&#xff0c;需要…

MAC(M1芯片)编译Java项目慢且发热严重问题解决方案

目录 一、背景二、排查三、解决四、效果以及结果展示五、总结 一、背景 使用idea编译项目等操作&#xff0c;经常性发热严重&#xff0c;并且时间慢。直到昨天编译一个项目用时30分钟&#xff0c;电脑温度很高&#xff0c;并且有烧灼的味道&#xff0c;于是有了此篇文章。 二、…

Python的国际化和本地化【第162篇—国际化和本地化】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 随着全球化的发展&#xff0c;多语言支持在软件开发中变得越来越重要。Python作为一种流行的…

VRRP——虚拟路由冗余协议

什么是VRRP 虚拟路由冗余协议VRRP&#xff08;Virtual Router Redundancy Protocol&#xff09;是一种用于提高网络可靠性的容错协议。 通过VRRP&#xff0c;可以在主机的下一跳设备出现故障时&#xff0c;及时将业务切换到备份设备&#xff0c;从而保障网络通信的连续性和可…

【vue】用vite创建vue项目

前置要求 要有Node.js 1. 用vite创建vue项目 在cmd中&#xff0c;进入一个文件夹 在文件资源管理器上面的文件目录中&#xff0c;输入cmd&#xff0c;回车在cmd中通过cd命令进入对应文件夹 创建项目 npm create vitelatest # 创建项目创建项目过程中的一些选项 Ok to pro…

06-vscode+espidf开发调试方法(内置JTAG调试)

使用VS Code和ESP-IDF进行ESP32开发和调试 在我们搭建 IDF 框架后&#xff0c;OpenOCD 已经自动下载好了&#xff0c; 我们通过 JTAG 接口连接使用 OpenOCD 进行调试。而ESP32芯片中内置 了JTAG 电路&#xff0c;无需额外芯片即可调试&#xff0c;更加方便&#xff0c;所以这里…

MySQL表结构的操作

文章目录 1. 创建表2. 查看表3. 修改表4. 删除表 1. 创建表 create table table_name (field1 datatype,field2 datatype,field3 datatype )character set 字符集 collate 校验集 engine 存储引擎;field&#xff1a;列名datatype&#xff1a;列的类型character set&#xff1a…

使用深度学习集成模型进行乳腺癌组织病理学图像分类

基于预训练的VGG16和VGG19架构训练了四种不同的模型&#xff08;即完全训练的 VGG16、微调的 VGG16、完全训练的 VGG19 和微调的 VGG19 模型&#xff09;。最初&#xff0c;我们对所有单独的模型进行了5倍交叉验证操作。然后&#xff0c;我们采用集成策略&#xff0c;取预测概率…

【华为OD机试】围棋的气【C卷|100分】

题目描述 围棋棋盘由纵横各19条线垂直相交组成,棋盘上一共19 x 19 = 361 个交点, 对弈双方一方执白棋,一方执黑棋,落子时只能将棋子置于交点上。 “气”是围棋中很重要的一个概念,某个棋子有几口气,是指其上下左右方向四个相邻的交叉点中, 有几个交叉点没有棋子,由此可…

【EM算法】算法及注解

EM算法又称期望极大算法&#xff0c;是一种迭代算法&#xff0c;每次迭代由两步组成&#xff1a;E步&#xff0c;求期望&#xff08;expectation&#xff09;&#xff1b;M步&#xff0c;求极大&#xff08;maximization&#xff09;。 算法背景 如果概率模型的变量都是观测变…

【报错】TypeError: Cannot read property ‘meta‘ of undefined

&#x1f608;解决思路 首先这里很明显我们能看到是缺少该参数&#xff1a;meta。 但是经过查找后发现和该参数无关。 &#x1f608;解决方法 后来我上网搜了下&#xff0c;网上的回答大部分偏向于是package.json这个文件中的tabBar.list数组对象只有一条的问题。 网上的大…

【Linux】引导与服务

一、系统引导过程 系统引导过程&#xff1a; 开机自检(BIOS) ----> MBR ----> GRUB ----> 加载内核 ----> 启动程序 1.1 开机自检 (1)开机自检&#xff1a;硬件启动POST(BIOS的一个主要功能)来加电检测硬件 (2)指引硬件&#xff1a;主板…