文章目录
- 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.程序框架图
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<>(); //排除的资源
@Override
public 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);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//查看session中的admin是否为true
HttpSession session = ((HttpServletRequest) servletRequest).getSession();
Object admin = session.getAttribute("admin");
//获取uri
String requestURI = ((HttpServletRequest) servletRequest).getRequestURI();
//获取排除的uri
List<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");
}
}
@Override
public 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 {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public 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");
}
}
@Override
public void destroy() {
}
}
5.细节
如果想要过滤一个文件夹下除了某个资源的其余资源,可以将排除的资源URI其放在init-param中,然后通过filter的init方法将其放到servletContext中,然后在doFilter中直接放行
6.结果展示
1.未登录可以任意浏览商品
2.点击添加购物车提示登录
3.点击后台管理,提示管理员登录
4.也做了其余资源的访问验证
2.事务管理
1.思路分析
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中的所有关闭数据库连接的语句
原因:数据库连接的关闭,交给最后提交事务或者回滚事务的时候再执行
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 {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain){
//首先放行
try {
filterChain.doFilter(servletRequest, servletResponse);
JDBCUtilsByDruid.commit();
} catch (Exception e) {
//如果在这次线程中有异常发生,则回滚
System.out.println("发现异常,事务回滚!");
JDBCUtilsByDruid.rollback();
}
}
@Override
public 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反射调用的,并且都抛出了异常,这个异常最后会经过过滤器,所以可以在过滤器中捕获到异常
3.结果展示
1.将OrderDaoImpl中的sql故意写错
2.执行保存订单操作
3.查看数据库信息(回滚了,没有生成记录)
3.统一错误页面
1.需求分析
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.导入两个页面
4.修改TransactionFilter,将异常抛给tomcat
5.结果展示
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
*/
@Override
public 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
*/
@Override
public Integer getTotalRow(String id) {
String sql = "select count(*) from `order` where id like ?";
return ((Number) queryScalar(sql,"%-" + id)).intValue();
}
3.单元测试
@Test
public void getPageItems() {
//查询id为1的会员的订单信息
List<Order> pageItems = orderDao.getPageItems(0, 3, "1");
for (Order pageItem : pageItems) {
System.out.println(pageItem);
}
}
@Test
public void getTotalRow() {
System.out.println("总的记录数为:" + orderDao.getTotalRow("1"));
}
2.编写service层
1.修改OrderService
//3.分页显示订单
public Page<Order> getPageItems(int pageNo, int pageSize, String username);
2.修改OrderServiceImpl
/**
* 根据当前页号和分页的大小返回对应的page对象
*
* @param pageNo
* @param pageSize
* @return
*/
@Override
public Page<Order> getPageItems(int pageNo, int pageSize, String username) {
//根据姓名获取用户id
Member member = memberDao.queryMemberByUsername(username);
//获取总记录数
Integer totalRow = orderDao.getTotalRow(member.getId().toString());
//计算总页数
Integer pageTotalCount = totalRow / pageSize;
if (totalRow % pageSize > 0) {
pageTotalCount ++;
}
//计算begin
int begin = (pageNo - 1) * pageSize;
//获取当页的所有数据
List<Order> pageItems = orderDao.getPageItems(begin, pageSize, member.getId().toString());
//填充page
Page<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();
@Test
public void getPageItems() {
Page<Order> pageItems = orderService.getPageItems(1, 3, "admin");
System.out.println(pageItems);
}
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.显示信息
2.分页导航条
4.结果演示
1.会员登录
2.会员点击订单管理只会显示当前会员的历史订单
5.管理员订单管理—分页查询
需求分析
管理员的订单管理,显示的是所有会员的订单
1.编写dao层
1.修改OrderDao
//5.管理员获取总体的记录条数
public Integer getTotalRow();
//6.管理员获取当前页需要展示的数据
public List<Order> getPageItems(int begin, int pageSize);
2.修改OrderDaoImpl
@Override
public Integer getTotalRow() {
String sql = "select count(*) from `order`";
return ((Number) queryScalar(sql)).intValue();
}
@Override
public 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
@Override
public Page<Order> getPageItems(int pageNo, int pageSize) {
//获取总记录数
Integer totalRow = orderDao.getTotalRow();
//计算总页数
Integer pageTotalCount = totalRow / pageSize;
if (totalRow % pageSize > 0) {
pageTotalCount ++;
}
//计算begin
int begin = (pageNo - 1) * pageSize;
//获取当页的所有数据
List<Order> pageItems = orderDao.getPageItems(begin, pageSize);
//填充page
Page<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);
}