java-1115
admin
2024-01-22 15:01:04
0

Filter:过滤器

  1. 概念:

    1. web过滤器:拦截浏览器的请求,完成一些特殊功能。
    2. 过滤器作用:一般用于完成通过的操作。(例如帮助服务器检查一些字段是否携带,比如访问界面的时候需要带token,否则返回登录界面)
  2. 快速入门:

    1. 步骤:
      1. 定义一个类,实现接口Filter
      2. 复写方法
      3. 配置拦截路径(定义访问什么资源的时候,过滤器生效),两种配置方法
        1. Web.xml
        2. 注解 @WebFilter( )我们需要配置里面的urlPatten这个属性,这个属性等于value,所以可以省略不写。
          1. @WebFilter(“/*”) 代表访问所有资源的时候都会拦截
  3. 过滤器细节:

    1. web.xml配置

      demo1com.emnets.java1115.Filter.FilterDemo1
      
      demo1/*
      
      
    2. 过滤器的执行流程

      1. doFilter方法中:req就是请求参数,

        1. 首先执行chain.doFilter(req,resp)方法之前的代码,可能会有一些对req参数的校验,如果通过就放行
        2. chain.doFilter(req,resp) 这个方法是放行方法,就是让服务器去处理请求
        3. 执行完放行后会回到chain.doFilter(req,resp)这个方法的下一行代码继续执行。
        //  对request对象的请求消息增强
        System.out.println("filterDemo2...");
        //  放行
        chain.doFilter(request, response);
        //  对response对象的响应消息增强
        System.out.println("filterDemo2 executing!");
        
    3. 过滤器生命周期方法

      1. init方法:服务器启动后会创建Filter对象,然后调用init方法,服务器自动完成(仅执行一次)用于加载资源
      2. doFilter方法:每一次请求被拦截资源时会执行,方法内包含拦截的逻辑
      3. destroy方法:服务器关闭之后。Filter对象被销毁。如果服务器正常关闭,则会执行destroy(仅执行一次)释放资源
    4. 过滤器的配置详解(两种配置)

      1. 拦截路径配置:

        1. “/*”:拦截所有资源
        2. “/资源”:具体资源路径,只有访问资源时过滤器才会执行,使用较少。
        3. “/user/*”:目录拦截,访问user目录下的所有资源时,过滤器都会执行。
        4. “*.jsp”:后追拦截,访问所有后缀名为jsp的资源时,过滤器都会拦截。
      2. 拦截方式配置:资源访问的方式(直接请求、转发是两种不同的方式)

        1. 注解配置:设置dispatcherTypes的属性

          1. REQUEST:默认值,浏览器直接请求资源(重要)
          2. FORWARD:转发访问资源(重要)
          3. INCLUDE:包含访问资源
          4. ERROR:错误跳转资源
          5. ASYNC:异步访问资源
        2. 注解配置多个值:

          1. @WebFilter(value = "/*",dispatcherTypes = {DispatcherType.REQUEST,DispatcherType.FORWARD})
            
        3. web.xml配置方式:

          1.    demo1com.emnets.java1115.Filter.FilterDemo1demo1/*FORWARDREQUEST
            
        4. 思考题:如果同时配置了请求和转发的过滤,那么一次请求触发的转发会触发几次过滤器

          1. 答案:2次 ,请求和转发分别都会触发过滤器
          2. 理解:虽然是一次请求,但是在服务器内部进行了跳转,每次切换资源都会触发过滤器
    5. 过滤器链(配置多个过滤器)

      1. 执行顺序 :如果有两个过滤器:f1 和 f2
        1. f1执行
        2. f2执行
        3. 资源执行
        4. f2回来执行
        5. f1回来执行
      2. 过滤器设计的先后顺序:
        1. 注解配置:按照类名的字符串比较规则比较,值小的先执行,
          1. 例如:AFilter 和 BFilter比较,A先执行
        2. web.xml配置: 谁定义在上面,谁先执行
    6. 案例一:登录验证

      1. 步骤:
        1. 排除登录相关的资源,
          1. 是:直接放行
          2. 不是:判断是否已经登录
            1. 未登录:
            2. 已登录:
      @Override
      public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {//  0.强制转换HttpServletRequest request = (HttpServletRequest)req;//  1.获取请求资源的请求路径String requestURI = request.getRequestURI();//  2.判断是否包含登录相关//  2.1 同时还要注意排除各种css/js/图片/验证码等资源if(requestURI.contains("/login.jsp")||requestURI.contains("/loginServlet")||requestURI.contains("/css/*")||requestURI.contains("/js/*")||requestURI.contains("/checkCodeServlet")){//  放行登录chain.doFilter(req, resp);}else {//  3.session获取Object user = request.getSession().getAttribute("user");if(user!=null){//  已经登录了 ,放行chain.doFilter(req, resp);}else {//  跳转登录request.setAttribute("login_msg","您尚未登录");request.getRequestDispatcher("/login.jsp").forward(request,resp);}}}
      
    7. 代理模式:

      1. 理解:在运行期间,对象中方法的动态拦截,在拦截前后执行功能操作,而原有对象不改变

      2. 概念:

        1. 真实对象:被代理的对象
        2. 代理对象:
        3. 代理模式:代理对象去代理真实对象,达到增强真是对象功能的目的
      3. 实现方式:(区别在于代理对象的生成方式)

        1. 静态代理:由一个类文件描述代理模式
        2. 动态代理:在内存中形成代理类(看不到一个真正的类文件,会在内存中动态生成)
          1. 实现步骤:
            1. 代理对象和真实对象实现相同的接口
            2. 代理对象 = Proxy.newProxyInstance( );进行代理对象的获取
            3. 使用代理对象调用方法。
            4. 增强方法
        3. 动态代理代码:
        public class ProxyTest {/**** @param args*/public static void main(String[] args) {//  1.创建真实对象Lenovo lenovo = new Lenovo();/***   2.动态代理增强lenovo对象*   三个参数:*      1.类加载器 : 真实对象.getClass().getClassLoader()*      2.接口数组 : 真实对象.getClass().getInterfaces()*      3.处理器   :*/SaleComputer proxy_lenovo = (SaleComputer)Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() {/*** 代理逻辑编写的方法:代理对象调用的所有方法,都会触发该方法执行。* 增强代码的逻辑就会在这个方法中执行* @param proxy 代理对象,就是指proxy_lenovo这个对象,一般不用* @param method 代理对象调用的方法会封装成对象,变成参数传递进来* @param args 代理对象调用方法时,传递的实际参数,封装进args,这里面就会有8000这种参数* @return* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("该方法执行了.....");System.out.println(method.getName());return null;}});//  3.调用方法String  computer = proxy_lenovo.sale(8000);System.out.println(computer);}
        }
        
      4. invoke方法的写法

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//  相当于使用真实对象调用该方法Object obj = method.invoke(lenovo, args);//  思考:方法应该如何增强//  这个返回值就是调用了方法后接收的返回值,会根据操作方法的不同而完全不同。return obj;
        }
        
      5. 方法增强方式:

        1. 增强参数列表

          @Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//  首先判断方法是否是需要增强的方法if(method.getName().equals("sale")){//  1.增强参数double money = (double) args[0];money *= 0.85;Object obj = method.invoke(lenovo, money);return obj;}else {//  相当于使用真实对象调用该方法Object obj = method.invoke(lenovo, args);//  这个返回值就是调用了方法后接收的返回值,会根据操作方法的不同而完全不同。return obj;}}
          
        2. 增强返回值类型

           @Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//  首先判断方法是否是需要增强的方法if(method.getName().equals("sale")){//  1.增强返回值double money = (double) args[0];money *= 0.85;String obj = (String)method.invoke(lenovo, money);return obj+"_鼠标垫";}else {//  相当于使用真实对象调用该方法Object obj = method.invoke(lenovo, args);//  这个返回值就是调用了方法后接收的返回值,会根据操作方法的不同而完全不同。return obj;}}
          
        3. 增强方法体执行逻辑

          @Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//  首先判断方法是否是需要增强的方法if(method.getName().equals("sale")){//  1.增强返回值double money = (double) args[0];money *= 0.85;System.out.println("专车接你....");String obj = (String)method.invoke(lenovo, money);System.out.println("免费送货....");return obj+"_鼠标垫";}else {//  相当于使用真实对象调用该方法Object obj = method.invoke(lenovo, args);//  这个返回值就是调用了方法后接收的返回值,会根据操作方法的不同而完全不同。return obj;}}
          
    8. 案例二:过滤敏感词汇

      1. 需求:
        1. 对录入数据的敏感词汇进行过滤
        2. 敏感词汇为“笨蛋”、“坏蛋”
        3. 如果是敏感词汇,替换为“***”
      2. 分析:
        1. 对request对象的getParameter方法进行增强,增强获取参数相关方法
        2. 放行。传递代理对象
      /*** 敏感词汇过滤器*/@WebFilter("/*")
      public class SensitiveWordsFilter implements Filter {private List list = new ArrayList();    //  敏感词汇public void init(FilterConfig config) throws ServletException {try {//  加载文件,获取文件真实路径ServletContext servletContext = config.getServletContext();String realPath = servletContext.getRealPath("/WEB-INF/classes/敏感词汇.txt");//  读取文件BufferedReader br = new BufferedReader(new FileReader(realPath));//  将文件的每一行数据添加到list中String line = null;while ((line = br.readLine())!=null){list.add(line);}br.close();System.out.println(list);} catch (Exception e){e.printStackTrace();}}public void destroy() {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {//  1.创建代理对象,增强getParameter方法ServletRequest proxy_req = (ServletRequest)Proxy.newProxyInstance(request.getClass().getClassLoader(), request.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if(method.getName().equals("getParameter")){//  增强返回值//  获取返回值,对返回值进行过滤String value = (String)method.invoke(request, args);if(value!=null){for(String str:list){if(value.contains(str)){value = value.replaceAll(str,"***");}   // if}   //for}// ifreturn value;}return method.invoke(request,args);}});//  2.放行,传递代理对象chain.doFilter(proxy_req, response);}
      }
      

      为了测试编写了一个servlet一起运行:

      @WebServlet("/testServlet")
      public class TestServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String name = request.getParameter("name");String msg = request.getParameter("msg");System.out.println(name+" : "+msg);}
      }
      
    9. 补充了对getParameterMap方法的增强:

      @Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {//  1.创建代理对象,增强getParameter方法ServletRequest proxy_req = (ServletRequest)Proxy.newProxyInstance(request.getClass().getClassLoader(), request.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if(method.getName().equals("getParameter")){//  增强返回值//  获取返回值,对返回值进行过滤String value = (String)method.invoke(request, args);if(value!=null){for(String str:list){if(value.contains(str)){value = value.replaceAll(str,"***");}   // if}   //for}// ifreturn value;}else if(method.getName().equals("getParameterMap")){Map parameterMap = (Map)method.invoke(request,args);if(!parameterMap.isEmpty()){// 遍历参数列表for(String[] p_value: parameterMap.values()){//  判断是否有子参数if(p_value.length>0){//  遍历子参数for(int i=0;i//  遍历敏感词汇for(String str:list){//  判断是否含有敏感词汇if(p_value[i].contains(str)){//  有则替换p_value[i] = p_value[i].replaceAll(str,"***");}}}}}}return parameterMap;}return method.invoke(request,args);}});//  2.放行,传递代理对象chain.doFilter(proxy_req, response);}
      

Listener:监听器

  1. 概念:web的三大组件之一。

    1. 事件监听机制:
      1. 事件 :一件事情
      2. 事件源 :事件发生的地方
      3. 监听器 :一个对象
      4. 注册监听:将事件、事件源、监听器绑定在一起。当事件源上发生某个事件后,执行监听器代码。
  2. ServletContextListener:监听ServletContext对象的创建和销毁

    1. void contextDestory(ServletContextEvent sce): servletContext对象被销毁前会调用
    2. void contextInitialized(ServletContextEvent sce):servletContext创建之后会调用该方法
  3. 步骤:

    1. 定义一个类,实现servletContextListener接口

    2. 复写方法

    3. 配置

      1. web.xml方式

         com.emnets.java1115.listener.ContextLoaderListener
        
      2. 注解方式

        @WebListener
        
  4. 代码:

    public class ContextLoaderListener implements ServletContextListener {/*** 监听servletContext对象创建。ServletContext对象服务器启动后自动创建。* @param sce*/@Overridepublic void contextInitialized(ServletContextEvent sce) {//  1.获取servletContext对象ServletContext servletContext = sce.getServletContext();//  2.加载资源文件String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");//  3.获取真实路径String realPath = servletContext.getRealPath(contextConfigLocation);//  4.加载进内存try {FileInputStream fis = new FileInputStream(realPath);System.out.println(fis);} catch (FileNotFoundException e) {e.printStackTrace();}System.out.println("servletContext对象被创建了");}/*** 服务器关闭后,ServletContext对象被销毁,当服务器正常关闭后该方法被调用* @param sce*/@Overridepublic void contextDestroyed(ServletContextEvent sce) {System.out.println("ServletContext对象被销毁了");}
    }

相关内容

热门资讯

linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
C++ 机房预约系统(六):学... 8、 学生模块 8.1 学生子菜单、登录和注销 实现步骤: 在Student.cpp的...
A.机器学习入门算法(三):基... 机器学习算法(三):K近邻(k-nearest neigh...
数字温湿度传感器DHT11模块... 模块实例https://blog.csdn.net/qq_38393591/article/deta...
有限元三角形单元的等效节点力 文章目录前言一、重新复习一下有限元三角形单元的理论1、三角形单元的形函数(Nÿ...
Redis 所有支持的数据结构... Redis 是一种开源的基于键值对存储的 NoSQL 数据库,支持多种数据结构。以下是...
win下pytorch安装—c... 安装目录一、cuda安装1.1、cuda版本选择1.2、下载安装二、cudnn安装三、pytorch...
MySQL基础-多表查询 文章目录MySQL基础-多表查询一、案例及引入1、基础概念2、笛卡尔积的理解二、多表查询的分类1、等...
keil调试专题篇 调试的前提是需要连接调试器比如STLINK。 然后点击菜单或者快捷图标均可进入调试模式。 如果前面...
MATLAB | 全网最详细网... 一篇超超超长,超超超全面网络图绘制教程,本篇基本能讲清楚所有绘制要点&#...
IHome主页 - 让你的浏览... 随着互联网的发展,人们越来越离不开浏览器了。每天上班、学习、娱乐,浏览器...
TCP 协议 一、TCP 协议概念 TCP即传输控制协议(Transmission Control ...
营业执照的经营范围有哪些 营业执照的经营范围有哪些 经营范围是指企业可以从事的生产经营与服务项目,是进行公司注册...
C++ 可变体(variant... 一、可变体(variant) 基础用法 Union的问题: 无法知道当前使用的类型是什...
血压计语音芯片,电子医疗设备声... 语音电子血压计是带有语音提示功能的电子血压计,测量前至测量结果全程语音播报࿰...
MySQL OCP888题解0... 文章目录1、原题1.1、英文原题1.2、答案2、题目解析2.1、题干解析2.2、选项解析3、知识点3...
【2023-Pytorch-检... (肆十二想说的一些话)Yolo这个系列我们已经更新了大概一年的时间,现在基本的流程也走走通了,包含数...
实战项目:保险行业用户分类 这里写目录标题1、项目介绍1.1 行业背景1.2 数据介绍2、代码实现导入数据探索数据处理列标签名异...
记录--我在前端干工地(thr... 这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前段时间接触了Th...
43 openEuler搭建A... 文章目录43 openEuler搭建Apache服务器-配置文件说明和管理模块43.1 配置文件说明...