• D18 Sping Boot 入门 Sping框架--Java Web之书城项目(八) 过滤器


    一、使用Filter过滤器拦截/pages/manager/所有内容,实现权限检查

    新建ManagerFilter

     1 package com.gychen.filter;
     2 
     3 import javax.servlet.*;
     4 import javax.servlet.http.HttpServletRequest;
     5 import java.io.IOException;
     6 
     7 public class ManagerFilter implements Filter {
     8 
     9     @Override
    10     public void init(FilterConfig filterConfig) throws ServletException {
    11 
    12     }
    13 
    14     @Override
    15     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    16 
    17         HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
    18 
    19         Object user =httpServletRequest.getSession().getAttribute("user");
    20 
    21         if (user ==null) {
    22             httpServletRequest.getRequestDispatcher("/pages/user/login.jsp").forward(servletRequest,servletResponse);
    23         } else {
    24             filterChain.doFilter(servletRequest,servletResponse);
    25         }
    26     }
    27 
    28     @Override
    29     public void destroy() {
    30 
    31     }
    32 }
    ManagerFilter

    二、ThreadLocal的使用

    ThreadLocal 的作用,它可以解决多线程的数据安全问题。
    ThreadLocal 它可以给当前线程关联一个数据(可以是普通变量,可以是对象,也可以是数组,集合)
    ThreadLocal 的特点:
      1、ThreadLocal 可以为当前线程关联一个数据。(它可以像 Map 一样存取数据,key 为当前线程)
      2、每一个 ThreadLocal 对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数据,就需要使用多个
        ThreadLocal 对象实例。
      3、每个 ThreadLocal 对象实例定义的时候,一般都是 static 类型
      4、ThreadLocal 中保存数据,在线程销毁后。会由 JVM 虚拟自动释放。

    三、实现Filter和ThreadLocal组合管理事务

    3.1 在JdbcUtils里用ThreadLocal重构

      1 package com.gychen.utils;
      2 
      3 import com.alibaba.druid.pool.DruidDataSource;
      4 import com.alibaba.druid.pool.DruidDataSourceFactory;
      5 
      6 import java.io.InputStream;
      7 import java.sql.Connection;
      8 import java.sql.SQLException;
      9 import java.util.Properties;
     10 
     11 public class JdbcUtils {
     12 
     13     private static DruidDataSource dataSource;
     14     // 用作单线程事务管理
     15     private static ThreadLocal<Connection> conns = new ThreadLocal<Connection>();
     16 
     17     static {
     18 
     19         try {
     20             Properties properties = new Properties();
     21             //读取jdbc.properties配置文件属性
     22             InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
     23             //从流中加载数据
     24             properties.load(inputStream);
     25             //创建 数据库 连接池
     26             dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
     27 //            System.out.println(dataSource.getConnection());
     28         } catch (Exception e) {
     29             e.printStackTrace();
     30         }
     31 
     32     }
     33 
     34 
     35     /**
     36      * 获取数据库连接池中的连接
     37      * @return 如果返回null 说明获取连接失败<br/> 有值就是获取连接成功
     38      */
     39 //    public static Connection getConnection(){
     40 //        Connection conn = null;
     41 //        try {
     42 //            conn = dataSource.getConnection();
     43 //        } catch (SQLException e) {
     44 //            e.printStackTrace();
     45 //        }
     46 //        return  conn;
     47 //    }
     48 
     49     public static Connection getConnection(){
     50         Connection conn = conns.get();
     51         if (conn == null) {
     52             try {
     53                 conn = dataSource.getConnection(); // 从数据库连接池中获取连接
     54 
     55                 conns.set(conn);  // 保存到ThreadLocal对象中,供后面的JBDC操作使用
     56 
     57                 conn.setAutoCommit(false);  // 设置为手动管理事务
     58             } catch (SQLException e) {
     59                 e.printStackTrace();
     60             }
     61         }
     62         return conn;
     63     }
     64 
     65 //    /**
     66 //     * 关闭连接,放回数据库连接池
     67 //     * @param conn
     68 //     */
     69 //    public static void close(Connection conn){
     70 //        if(conn != null){
     71 //            try {
     72 //                conn.close();
     73 //            } catch (SQLException e) {
     74 //                e.printStackTrace();
     75 //            }
     76 //        }
     77 //    }
     78 
     79     /**
     80      * 提交事务并关闭释放连接
     81      */
     82     public static void commitAndClose(){
     83         Connection connection = conns.get();
     84         if (connection != null) {  // 如果不等于null,说明之前使用过连接,操作过数据库
     85             try {
     86                 connection.commit();  // 提交事务
     87             } catch (SQLException e) {
     88                 e.printStackTrace();
     89             } finally {
     90                 try {
     91                     connection.close();   // 关闭连接,释放资源
     92                 } catch (SQLException e) {
     93                     e.printStackTrace();
     94                 }
     95             }
     96 
     97         }
     98         // 一定要执行remove操作,否则会出错(因为Tomcat服务器底层使用了线程池技术)
     99         conns.remove();
    100     }
    101 
    102 
    103     /**
    104      * 回滚事务并关闭释放连接
    105      */
    106     public static void rollbackAndClose(){
    107         Connection connection = conns.get();
    108         if (connection != null) {  // 如果不等于null,说明之前使用过连接,操作过数据库
    109             try {
    110                 connection.rollback();  // 回滚事务
    111             } catch (SQLException e) {
    112                 e.printStackTrace();
    113             } finally {
    114                 try {
    115                     connection.close();   // 关闭连接,释放资源
    116                 } catch (SQLException e) {
    117                     e.printStackTrace();
    118                 }
    119             }
    120 
    121         }
    122         // 一定要执行remove操作,否则会出错(因为Tomcat服务器底层使用了线程池技术)
    123         conns.remove();
    124     }
    125 
    126 
    127     public static void main(String[] args) {
    128 
    129     }
    130 
    131 }
    JdbcUtils

    在Dao里删除close操作并抛出异常

    3.2 使用Filter过滤器统一给所有的Service方法都加上try-catch。来进行实现的管理。

      在com.gychen.filter里新建TransactionFilter并配置web.xml

     1 package com.gychen.filter;
     2 
     3 import com.gychen.utils.JdbcUtils;
     4 
     5 import javax.servlet.*;
     6 import java.io.IOException;
     7 
     8 public class TransactionFilter implements Filter {
     9 
    10     @Override
    11     public void init(FilterConfig filterConfig) throws ServletException {
    12 
    13     }
    14 
    15     @Override
    16     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    17 
    18         try {
    19             filterChain.doFilter(servletRequest,servletResponse);
    20             JdbcUtils.commitAndClose();  // 提交事务
    21         } catch (Exception e) {
    22             JdbcUtils.rollbackAndClose();  // 回滚事务
    23             e.printStackTrace();
    24 
    25         }
    26     }
    27 
    28     @Override
    29     public void destroy() {
    30 
    31     }
    32 }
    TransactionFilter

    在BaseServlet中抛出异常 throw new RuntimeException(e); 

    3.3 将所有异常都统一交给Tomcat展示友好的错误信息页面

    在web.xml中可以通过错误页面配置来进行管理

    1  <!--错误页面管理配置-->
    2     <!-- error-page标签配置 服务器出错之后自动跳转的页面 -->
    3     <error-page>
    4         <!-- error-code是错误类型 -->
    5         <error-code>500</error-code>
    6         <!-- location表示要跳转的页面路径 -->
    7         <location>/pages/error/error500.jsp</location>
    8     </error-page>

    在pages里新建error文件夹,新建erro500.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>error500</title>
    </head>
    <body>
        很抱歉,您访问的页面服务器出现错误
    </body>
    </html>

  • 相关阅读:
    Ubuntu 17 安装sublime
    ubuntu17 设置python3为默认及一些库的安装
    Java中内存分析(一)
    我的学习JavaEE路线
    我爱学习……
    HDU 4602
    K-special Tables
    Gym 100712A - Who Is The Winner
    UVA 1583
    水题 UVA 1586
  • 原文地址:https://www.cnblogs.com/nuister/p/13071826.html
Copyright © 2020-2023  润新知