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

文章目录

    • 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.mzph.cn/news/818935.shtml

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

相关文章

程序猿之路

我接触计算机算对自己来说是比较晚的了&#xff0c;上初中的时候就有微机课&#xff0c;但是在那个小县城&#xff0c;上课也只是3个人共用一个电脑&#xff0c;我初中整个过程只会开关机&#xff0c;哈哈&#xff0c;虽然学过word&#xff0c;但是无奈&#xff0c;我插不上手呀…

AJAX请求(axios篇)

目录 一、axios介绍 1.概念 2.功能 3.好处 二、axios用法 1.安装方法 2.GET方法 3.POST方法 4.执行多个并发请求 5.axios API 6.请求方法的别名 7.async/await异步请求 三、axios实例 四、总结 一、axios介绍 1.概念 AJAX是“Asynchronous JavaScript and XML”…

开源相机管理库Aravis例程学习(三)——注册回调multiple-acquisition-callback

开源相机管理库Aravis例程学习&#xff08;三&#xff09;——回调multiple-acquisition-callback 简介例程代码arv_camera_create_streamArvStreamCallbackTypeArvStreamCallback 简介 本文针对官方例程中的&#xff1a;02-multiple-acquisition-callback做简单的讲解。 ara…

ActiveMQ 04 Linux下安装

Active MQ 04 Linux下安装 下载 解压 在init.d下建立软连接 ln -s /usr/local/activemq/bin/activemq ./设置开启启动 chkconfig activemq on 服务管理 service activemq start service activemq status service activemq stopNIO配置 默认配置为tcp&#xff0c;使用的…

C语言 | Leetcode C语言题解之第30题串联所有单词的子串

题目&#xff1a; 题解&#xff1a; typedef struct {char key[32];int val;UT_hash_handle hh; } HashItem;int* findSubstring(char * s, char ** words, int wordsSize, int* returnSize){ int m wordsSize, n strlen(words[0]), ls strlen(s);int *res (int *)mall…

深入理解ClickHouse 的高性能与高可用原理

架构 ClickHouse 的架构设计旨在提供高性能、高吞吐量的数据存储和查询能力&#xff0c;特别适合处理大规模数据集和实时分析场景。ClickHouse 的架构可以分为几个关键组成部分&#xff0c;它们共同工作以提供高效的数据处理能力和高可用性。 主要组件 1. 存储引擎 ClickHo…

【opencv】示例-videocapture_starter.cpp 从视频文件、图像序列或连接到计算机的摄像头中捕获帧...

/** * file videocapture_starter.cpp * brief 一个使用OpenCV的VideoCapture与捕获设备&#xff0c;视频文件或图像序列的入门示例 * 就像CV_PI一样简单&#xff0c;对吧&#xff1f; * * 创建于: 2010年11月23日 * 作者: Ethan Rublee * * 修改于: 2013年4月17日 * …

【ES6】使用记录

Symbol const sym Symbol(Mo_qyue); console.log(sym.description) //Mo_qyue作为属性名Symbol let mySymbol Symbol() let a {} a[mySymbol] hello; console.log(a[mySymbol]) //hellolet b{[mySymbol]:hello} console.log(b[mySymbol]) //hellolet cObject.defineProp…

金蝶云星空与领星ERP对接集成分布式调入单查询打通添加/编辑本地产品

金蝶云星空与领星ERP对接集成分布式调入单查询打通添加/编辑本地产品 接通系统&#xff1a;金蝶云星空 金蝶K/3Cloud结合当今先进管理理论和数十万家国内客户最佳应用实践&#xff0c;面向事业部制、多地点、多工厂等运营协同与管控型企业及集团公司&#xff0c;提供一个通用的…

Unity 扩展自定义编辑器窗口

在Assets文件夹路径下任意位置创建Editor文件夹&#xff0c;将扩展编辑器的代码放在Editor文件夹下 生成编辑器窗口 代码中首先引用命名空间 using UnityEditor; 然后将创建的类继承自EditorWindow public class MenuEditor : EditorWindow 然后通过扩展编辑器菜单功能调用…

51-40 Align your Latents,基于LDM的高分辨率视频生成

由于数据工程、仿真测试工程&#xff0c;咱们不得不进入AIGC图片视频生成领域。兜兜转转&#xff0c;这一篇与智驾场景特别密切。23年4月&#xff0c;英伟达Nvidia联合几所大学发布了带文本条件融合、时空注意力的Video Latent Diffusion Models。提出一种基于LDM的高分辨率视…

ActiveMQ 06 Request/Response模型实现

Active MQ 06 Request/Response模型实现 QueueRequestor 同步阻塞 TemporaryQueue 异步监听&#xff0c;当消息过多时会创建响应的临时queue JMSCorrelationID 消息属性 异步监听&#xff0c;公用queue 调优总结 Topic加强 可追溯消息 http://activemq.apache.org/re…

自然语言处理(Natural Language Processing, NLP)简介

自然语言处理 (NLP) 是计算机科学的一个分支&#xff0c;更具体地说&#xff0c;是人工智能 (AI) 的分支&#xff0c;旨在让计算机能够以与人类大致相同的方式理解文本和语音。 自然语言处理 (NLP) 将计算语言学&#xff08;基于规则的人类语言建模&#xff09;与统计、机器学…

华为云Stack学习笔记

云服务层-基础设施层-----------------为云服务和华为云stack环境的部署提供基本的硬件支持 1.计算资源&#xff1a;服务器 &#xff08;1&#xff09;国产&#xff1a;兆芯服务器、海光服务器、飞腾服务器、鲲鹏服务器(泰山服务器、黄河服务器、宝德服务器) &#xff08;2&…

JavaWeb--正则表达式

目录 1. 简介 1.1. 语法 1.1.1. 使用RegExp构造函数创建正则表达式 1.1.2. 使用正则表达式字面量语法创建正则表达式 1.1.3. 正则表达式的应用 2. 修饰符 3. 方括号 4. 元字符 5. 量词 6. RegExp对象方法 7. 支持正则的String的方法 8. 正则表达式体验 8.1. 验证 …

【uniapp / vue】中动态添加绑定style 或 class

一、style样式动态设置 1.普通对象动态添加&#xff08;比较常见&#xff09; <template><view><view :style"{color:fontColor}"> </view><view :style"{ paddingTop: num px }"></view><view :style"{bac…

MySQL8.0.36-社区版:通用语法(2)

语法格式规范 sql语句可以以单号或者多行为书写&#xff0c;以分号结尾 可以使用空格或者缩进来增加可读性 mysql的sql语句不区分大小写&#xff0c;但是推荐大写关键字 注释分为单号注释和多行 单号注释&#xff1a;--内容 或者 # 内容 多行注释/* 注释内容 */ sql语句的…

面试算法-175-将有序数组转换为二叉搜索树

题目 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡 二叉搜索树。 示例 1&#xff1a; 输入&#xff1a;nums [-10,-3,0,5,9] 输出&#xff1a;[0,-3,9,-10,null,5] 解释&#xff1a;[0,-10,5,null,-3,null,9] 也将被视…

C++11的新特性

C11是由C标准委员会指定的语言规范。相比于C98/03&#xff0c;C11则带来了数量可观的变化&#xff0c;其中包含了约140 个新特性&#xff0c;以及对C03标准中约600个缺陷的修正&#xff0c;C11能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全&#xff0c;…

数据结构 -- 数组

本篇文章主要是对数组的实操&#xff0c;所以对数组的概念不在赘述&#xff0c;了解更多数组相关可参照链接 Java数组的概念及使用-CSDN博客 1、DynamicArray类 package com.hh.algorithm.array;import java.util.Arrays; import java.util.Iterator; import java.util.functi…