JavaWeb——核心技术2:过滤器、监听器(javaWeb三大组件servlet、filter、listener)

目录

Filter:过滤器

作用:

入门学习:

细节:

案例:

        登录验证(权限控制——后期有权限控制框架)

        过滤铭感词汇

listener:监听器:


Filter:过滤器

生活中:净水器、空气净化器、核酸检测

来回都得拦截————————来回都得拦截

web中:当客户端访问服务器时,拦截下来请求完成特殊功能


作用:

拦截请求,增强请求、完成通用的操作,当需要获取的资源都需要检测时 (如登录验证、特殊字符敏感字符的操作、统一编码处理)

入门学习:

 

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
//访问所有资源执行过滤器
@WebFilter("/*")
public class Filter01 implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //放行资源  没设置不放行    
        filterChain.doFilter(servletRequest,servletResponse);
    }

    public void destroy() {

    }
}

没有注解

没有Filter接口时

AIL+Enter  查找依赖  自动添加依赖。刷新maven

 

细节:

xml配置和注解配置的区别

过滤器的执行流程

过滤器的生命周期方法

过滤器配置详解

过滤器链——一个过滤器接一个过滤器。
 



XML配置路径————
去掉注解、设置过滤器名字、映射引用到什么路径

 过滤器的执行流程————

   ::执行过滤器,执行放行后的资源(既 doFilter方法),再回来执行放行后面的方法     

 过滤器的生命周期:————

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
//访问所有资源执行过滤器
@WebFilter("/*")
public class Filter01 implements Filter {
    /**
     * 服务器启动时,会创建Filter对象,自动执行一次,也只执行一次
     * 作用:执行加载资源
     * @param filterConfig
     * @throws ServletException
     */
    public void init(FilterConfig filterConfig) throws ServletException {



    }

    /**
     * 每次请求被拦截时 执行多次
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //一般在这里对请求做增强
        System.out.println("请求进来了");
        //放行资源  没设置不放行
        filterChain.doFilter(servletRequest,servletResponse); //到这里会输出页面的内容
        //在这里做响应的增强

        System.out.println("请求出去了....");
    }

    /**
     * 服务器正常关闭时 执行一次
     * 作用:释放资源
     */
    public void destroy() {

    }
}

过滤器配置————

        路径配置:

                        1、具体路径:/index.html   

                        2、目录拦截:/user/*   要在servlet配置路径(controller同理)下面图

                        3、后缀名拦截:.jpg

                        4、所有资源:*

                

 

        方式配置:方式指的是  资源被访问的方式。

String[] urlPatterns() default {};//配置路径
    //配置请求方式 
    //属性
//REQUEST:默认值
//FORWARD:转发访问资源
//INCLUDE:包含访问资源
//ERROR:错误跳转资源
//ASYNC:异步访问

这个属性是个数组:相当于可以配置多种配置方式。

注解的源码:

package javax.servlet.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.servlet.DispatcherType;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebFilter {
    String description() default "";

    String displayName() default "";

    WebInitParam[] initParams() default {};

    String filterName() default "";

    String smallIcon() default "";

    String largeIcon() default "";

    String[] servletNames() default {};

    String[] value() default {};//配置路径

    String[] urlPatterns() default {};//配置路径
    //配置请求方式 
    //属性
//REQUEST:默认值
//FORWARD:转发访问资源
//INCLUDE:包含访问资源
//ERROR:错误跳转资源
//ASYNC:异步访问
    DispatcherType[] dispatcherTypes() default {DispatcherType.REQUEST};

    boolean asyncSupported() default false;
}

一个设置转发的类...

 过滤器......

 xml的配置

 过滤器链:

        执行顺序

domain方法....

 

       


 先后顺序:

        注解配置的过滤器:根据人过滤器的类名字母数字顺序比较

        xml配置:谁在前面谁先执行。     

案例:

        登录验证(权限控制——后期有权限控制框架)

        过滤铭感词汇

        

 分析步骤:

 代码实现:、

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@WebFilter("/*")
public class Filter01 implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //1、强转ServletRequest为HttpRequest  只有HttpRequest对象由得到请求路径的方法
        HttpServletRequest request= (HttpServletRequest) servletRequest;
        //2、得到路径判断路径包不包含是不是登录页面的请求
        String requestURI = request.getRequestURI();
        //要判断请求的所有资源 做放行css  js  验证码动态资源  图片等
        if (requestURI.contains("/login.html")
                ||requestURI.contains("/login.servlet")
                ||requestURI.contains("/css/")
                ||requestURI.contains("/js/")
                ||requestURI.contains("/loginServlet")
                ||requestURI.contains("/.jpg")){
            //想登录、放行去登录页面
            filterChain.doFilter(servletRequest,servletResponse);
        }else {
            //不是登录页面、判断是否登录
            String user = (String) request.getSession().getAttribute("user");
            if (user!=null){ //用户名要去数据库找,这里写死
                filterChain.doFilter(servletRequest,servletResponse);
            }else {
                //没有登录、跳转页面
                request.setAttribute("login_msg","没有登录!!!请登录");
                request.getRequestDispatcher("/login.html").forward(servletRequest,servletResponse);
            }
        }
        //放行资源  没设置不放行
        filterChain.doFilter(servletRequest,servletResponse); //到这里会输出页面的内容
        //在这里做响应的增强

        System.out.println("请求出去了....");
    }

    public void destroy() {

    }
}

案例二————————————————————————————————————

这里为什么用动态代理,当出现更多的敏感词汇,直接更改配置文件即可。 

动态代理增强

 增强对象的功能。。 SpringAOP

           设计模式:23中设计模式

                代理模式和装饰着模式可以实现。

代理模式参考 我的Spring AOP

接口(代理和真实对象的公共行为)
public interface shop {
    public String sale(double dollar);
}

 

真实对象
public class Lenovo implements shop {

    public String sale(double dollar) {
        System.out.println("联想电脑卖"+dollar+"元");
        return "我是真实对象那个的返回值";
    }
}
使用者
使用代理对象
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/*
用户对象使用动态代理是生成代理类
 */
public class user {
    public static void main(String[] args) {
        final Lenovo lenovo=new Lenovo();
        /**
         * 三个参数
         *  代理的真实对象、代理对象实现的接口、真实对象要执行方法时要经过的接口(固定写法,只需要处理invoke方法的逻辑)
         *  生成的是object,需要强转为 接口类型
         *  invoke方法(被代理对象:真实对象、方法、方法的参数)
         */
        shop shopComputer = (shop) Proxy.newProxyInstance(Lenovo.class.getClassLoader(), Lenovo.class.getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("代理对象的方法被调用了");

                //判断是不是规定需要增强的方法
                if (method.getName().equals("sale")) {
                    //1、增强参数
                    double money = Double.parseDouble(args[0].toString());
                    money = money + 100;
                    //真实对象调用方法,利用的是反射中的方法对象那个的invoke 和上面的invoke区别开来
                    System.out.println("开始增强方法体");
                    String invoke = (String) method.invoke(lenovo, money);
                    System.out.println(invoke);
                    System.out.println("已经增强方法体");
                    //2、增强返回值
                    //invoke变量是真实返回值
                    return invoke + "成功增强方法返回值";
                    //3、增强方法体在method.invoke方法执行前后  加入方法体。
                }else {
                    return "不是增强的方法执行了";
                }
            }
        });
        //这里调用的代理对象的sale方法,但是在实际执行在invoke里面。
        String ni=shopComputer.sale(123);
        System.out.println(ni);
    }

}
——————————————————————————————————————————————————————————————————————————
输出


代理对象的方法被调用了
开始增强方法体
联想电脑卖223.0元
我是真实对象那个的返回值
已经增强方法体
我是真实对象那个的返回值成功增强方法返回值

分析,

增强request的获取参数的方法

放行,传递代理对象

过滤器::::::::

import javax.jws.Oneway;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

@WebFilter("/*")
public class Filter01 implements Filter {
    //加载文件  开启时执行一次
    private List<String> list=new ArrayList<String>();
    public void init(FilterConfig filterConfig) throws ServletException {

        try {
            //加载文件的上下文
            ServletContext servletContext = filterConfig.getServletContext();
            //获取文件的路径
            String nihao=servletContext.getRealPath("/nihao.text");
            //读取
            BufferedReader bf=new BufferedReader(new FileReader(nihao));
            String n=null;
            if (n.equals(bf.readLine())){
                list.add(n);
            }
            bf.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //1、创建代理对象
        Object getParameter = Proxy.newProxyInstance(
                servletRequest.getClass().getClassLoader(),
                servletRequest.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //2、判断是否是需要增强的方法
                        if (method.getName().equals("getParameter")) {
                            //反射控制  执行方法的返回值
                            String value= (String) method.invoke(servletRequest, args);
                            if (value!=null){
                                for (String ss:list) {
                                    if (value.contains(ss)){
                                        value=value.replaceAll(ss,"***");
                                    }
                                }
                            }
                            //再执行getParameter者个方法时,得到的就是这个返回值
                            return value;
                        }
                        return method.invoke(servletRequest, args);
                    }
                });
    }

    public void destroy() {

    }
}

servlet接口

 

 

注意点,这个项目需要部署在tomcat上

文件位置要写好

判断时逻辑要清楚

servletContext  去了解好。

判断getParameterMap

判断getParameterValue

listener:监听器:

伴随某个事件的创建而存在

事件的监听机制:

 事件:创建了servletContext对象

事件源:tomcat

监听器:我们自己创建的类

注册监听:xml  /注解

XML配置:

下面配置时将某个类作为监听器

 监听器时伴随servletContext对象的创建二创建............重要

初始化执行方法一般用来加载文件

 

自己定义的监听器

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class ContextLoadListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        //获取ServletContext对象  代表整个项目负责和服务器交互通信
        ServletContext servletContext = servletContextEvent.getServletContext();
        //配置加载的映射xml,
        String str=servletContext.getInitParameter("contextConfigLocation");
        //3. 获取资源文件在服务器的地址
        String s=servletContext.getRealPath(str);
        //加载资源文件
        try {
            FileInputStream fis=new FileInputStream(s);
            System.out.println(fis);
            fis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("监听器被销毁了");
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值