zoukankan      html  css  js  c++  java
  • 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>

  • 相关阅读:
    今天开始用 VSU 2010
    Visual Studio 2010 模型设计工具 基本应用
    Asp.Net访问Oracle 数据库 执行SQL语句和调用存储过程
    Enterprise Library 4.1 Security Block 快速使用图文笔记
    解决“System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本。”(图)
    一个Oracle存储过程示例
    Enterprise Library 4.1 Application Settings 快速使用图文笔记
    Oracle 10g for Windows 简体中文版的安装过程
    Oracle 11g for Windows 简体中文版的安装过程
    Oracle 9i 数据库 创建数据库 Net 配置 创建表 SQL查询 创建存储过程 (图)
  • 原文地址:https://www.cnblogs.com/nuister/p/13071826.html
Copyright © 2011-2022 走看看