Java Web-Filter and listener
Java Web-Filter and listener
Filter:过滤器
概述
拦截请求,完成一些特殊的功能。
过滤器的作用:
- 一般用于完成通用的一些操作,例如登录验证(通过session来判断访问是否登录,在未登录之前拦截资源访问请求并强制要求登录)、统一编码处理(统一设置
request.setCharacterEncoding("utf-8"))、敏感字符的过滤(例如脏话替换为星号)
快速入门
步骤:
定义一个类,实现接口Filter
注意,有多个包中有Filter接口,我们要的是javax.servlet包下的
复写对应的方法
配置拦截路径
- 通过web.xml配置
- 通过注解配置
示例:
package com.jiading.filter; import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/*")//配置的是urlPattern,对当前目录下的所有资源都添加filter
public class FilterDemo1 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException { } @Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("filterDemo1被执行了");
/*
考虑是否放行
*/
//放行
filterChain.doFilter(servletRequest,servletResponse);
//上面那一行代码不加的话就不放行
} @Override
public void destroy() { }
}
如果使用web.xml配置:
如果要使用web.xml进行配置,我们当然先要为项目配置一个web.xml。
配置过程和配置servlet很像
<filter>
<filter-name>demo1</filter-name>
<filter-class>com.jiading.filter.FilterDemo1</filter-class>
</filter>
<filter-mapping>
<filter-name>demo1</filter-name>
<url-pattern>/*</url-pattern>
</filter-maping>
细节
过滤器执行流程
filter对于一次访问的request和response都要检查一遍
放行代码之前的代码是对于request的检查
放行代码之后的代码是对于response的检查
过滤器生命周期方法
filter对象在服务器启动后就创建,然后调用init方法
在服务器关闭时,filter对象被销毁。如果是正常关闭服务器,则会执行destory方法
每一次请求被拦截时,doFilter方法都被执行
过滤器配置详解
拦截路径的配置
- 具体资源路径:例如/index.jsp
- 拦截目录:例如/user/*
- 后缀名拦截:*.jsp
- 拦截所有资源:例如/*
拦截方式的配置
指的是资源被访问的方式,例如浏览器直接访问、重定向、转发等
拦截方法的配置同样有两种方法:注解配置和web.xml配置
注解配置
设置@WebFilter的dispatcherTypes属性,有五种可能属性
- REQUEST,默认值,拦截浏览器直接请求的资源
- FORWARD,拦截转发访问
- INCLUDE,拦截包含访问资源
- ERROR,拦截错误跳转(errorPage)
- ASYNC,拦截异步访问资源
web.xml配置
在
<filter-mapping>标签下设置<dispatcher>子标签
过滤器链(配置多个过滤器)
对于一条访问,可以配置多个过滤器,形成所谓的“过滤器链”
执行顺序:过滤器1-》过滤器2-》资源访问-》过滤器2-》过滤器1
当拦截路径有重叠时,确定过滤器先后顺序:
注解配置
按照类名的字符串比较规则来比较,值小的先执行,例如一个叫A,一个叫B,那么A就先执行。
web.xml配置
哪个
<filter-mapping>定义在上边,谁就先执行
举例
权限控制(登录验证)
判断是否是与登录相关的资源。如果是,则直接放行;反之则拦截,判断是否已经登录,也就是session里面是否有user
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//1.强制转换
HttpServletRequest request=(HttpServletRequest)req;
//2.获取资源请求路径
String url=request.getRequestURI();
//3.判断是否包含登录相关资源路径
if(uri.contains("/login.jsp")||uri.contains("/loginServlet")||uri.contains(<登录页面需要的图片、验证码、CSS等资源>)){
//证明用户此时的请求就是想要登录,直接放行
chain.doFilter(req,resp);
}else{
//验证用户是否登录,从session中获取user
request.getSession().getAttribute("user");
if(user!=null)//说明用户已经登录了
chain.doFilter(req,resp);
else{
//跳转登录页面
request.setAttribute("login_msg","您尚未登录,请登录");
request.getRequestDispatcher("/login.jsp").forward(request,resp);
}
}
}
敏感词汇过滤
对request对象进行增强,采用设计模式来完成,有23中Java设计模式。装饰模式、代理模式都可以用来增强对象的功能。这里我们选择代理模式的动态代理。
关于代理模式、装饰模式,可以看我的这篇博文
代理模式:
概念
真实对象:被代理的对象
代理对象
代理模式:代理对象来通过代理的方式来增强真实对象的功能
实现方式
- 静态代理:有一个类文件描述代理模式
- 动态代理:在内存中形成代理类
动态代理用的比较多,这里我们就使用动态代理
实现步骤
代理对象和真实对象实现相同的接口
实例化真实对象
使用Proxy.newProxyInstance(classLoader,Class,InvocationHandler)来获取代理对象
classLoader:被代理对象的类加载器
Class:数组,真实对象实现的接口
InvocationHandler:一般通过匿名内部类创建该对象
使用代理对象来调用方法(因为实现了相同的接口,所以可以直接调用代理对象)
增强方法
- 增强参数列表
- 增强返回值类型
- 增强方法体执行逻辑
示例:示例程序见我的这篇博文
实现:
我们使用过滤器对除登录页面之外的所有页面进行过滤,在过滤器内对ServletRequest对象进行代理,该代理对象对getParameters等获取用户输入参数的方法进行增强:通过遍历敏感词数组检查用户输入参数是否包括敏感词(敏感词数组在init()方法中已经加载到了内存中,保存在过滤器对象内),如果包含,就将敏感词进行替换后返回。
这样,如果服务器要调用该对象的getParameters()、getParameterMap()、getParameterValue()等方法来获取用户输入的值时,就会因为方法名被拦截下来,拆包、替换。
因为服务器在通信中只需要获取用户传入的参数,也就是request中的参数,所以凭方法名就可以有效拦截
ServletRequest proxy_req=(ServletRequest)Proxy.newProxyInstance(req.getClass().getClassLoader(),req.getClass().getInterfaces(),new InvocationHandler(){
@Override
public Object invoke(Object proxy,Method method,Object[]args)throws Throwable{
if(method.getName().equals("getParameter")){
String value=(String)method.invoke(req,args);
if(value!=null){
for(String str:list){
if(value.contains(str){
value=value.replaceAll(str,"***");
})
}
}
return value;
}
return method.invoke(req,args);
} })
Listener:监听器
概念
Web三大组件之一
- 事件的监听机制
- 事件:都懂得
- 事件源:事件发生的对象
- 监听器:一段代码或者一个对象
- 注册监听:将事件、事件源、监听器绑定在一起。当时间源上发生某个事件后,执行监听器代码
ServletContextListener
是一个接口,没有对应的实现类,需要自己写
方法:
- void contextInitialized(ServletContext sce),初始化
- void contextDestroyed(ServletContext sce),销毁时调用
这部分用的不多,是略讲的:
步骤:
定义一个类来实现该接口
复写方法
配置:web.xml或者注解
web.xml
<listener>
<listener-class>com.jiading.filter.Listener</listener-class>
</listener>
注解
@WebListener
示例:
Listener.java
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.io.FileInputStream;
import java.io.FileNotFoundException; public class Listener implements ServletContextListener {
/*
在服务器启动后自动创建,用来监听ServletContext对象(也是服务器启动时自动创建)
*/
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//一般用来加载资源文件:
//1.加载ServletContext对象
ServletContext servletContext = servletContextEvent.getServletContext();
//2.加载资源文件
String initParameter = servletContext.getInitParameter("contextConfigLocation");
//3.获取真实路径
String realPath = servletContext.getRealPath(initParameter);
//4.加载资源文件进内存
try {
FileInputStream fis=new FileInputStream(realPath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//我们可以在web.xml中指定初始化信息,详见web.xml
System.out.println("ServletContextListener被创建了");
} @Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContextListener被销毁了");
}
在web.xml中可以创建ServletContext的参数:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/test.xml</param-value>
</context-param>
真正使用时,监听器一般是框架写好的,一般使用的时候会配置就可以了
Java Web-Filter and listener的更多相关文章
- Java Web(五) 监听器Listener
监听器概述 在上一篇里介绍了过滤器Filter,而Listener是Servlet的另一个高级特性.Listener用于监听Java Web程序中的事件,例如创建,修改,删除Session,reque ...
- 【java web】监听器listener
一.简介 Java的监听器,也是系统级别的监听.监听器随web应用的启动而启动.Java的监听器在c/s模式里面经常用到,它会对特定的事件产生产生一个处理.监听在很多模式下用到,比如说观察者模式,就是 ...
- java web filter 学习(2)
本文主要对filter的基本使用进行了讲解,其中涉及到了 filter是什么 一个filter处理一个jsp 多个filter处理一个jsp filter是什么 Filter 是java下的一种过滤器 ...
- java web filter 之一 基础实现
本文主要对filter的基本使用进行了讲解,其中涉及到了 filter是什么 一个filter处理一个jsp 多个filter处理一个jsp filter是什么 Filter 是java下的一种过滤器 ...
- java web filter读取classpath配置文件内容
以下demo,从类路径classpath中获取venus.properties(本项目中用到的文件),思路是在初始化的时候读取,然后放在局部变量里面. package club.codeapes.we ...
- Java Web Filter登录验证
初做网站需要登录验证,转自 :http://blog.csdn.net/daguanjia11/article/details/48995789 Filter: Filter是服务器端的组件,用来过滤 ...
- 学习java web中的listener
web.xml里的顺序为:context-param->listener->filter->servlet 监听器是需要新建一个类,然后按监听的对象继承:ServletContext ...
- 【Java Web开发学习】Spring MVC添加自定义Servlet、Filter、Listener
[Java Web开发学习]Spring MVC添加自定义Servlet.Filter.Listener 转载:https://www.cnblogs.com/yangchongxing/p/9968 ...
- 【Java Web开发学习】Servlet、Filter、Listener
[Java Web开发学习]Servlet 转发:https://www.cnblogs.com/yangchongxing/p/9274739.html 1.Servlet package cn.y ...
- 【Web】servlet、filter和listener
一般地,servlet.filter.listener是配置到web.xml中(web.xml 的加载顺序是:context-param -> listener -> filter -&g ...
随机推荐
- C#中 Dictionary<>的使用及注意事项
1,如果在主体代码中使用,直接在初始化中生成就行 2如果在其他层,比如逻辑层,要注意在事件内部定义,在外部的话,重复调用就会提示“”“已经定义了相同的KEY”,见例子 (例子是转的) Dictiona ...
- 真正解决方案:java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter
今天在使用JDK 12.0 环境下使用Hibernate 时候出现了这个错误,错误日志如下: 故障原因: JAXB API是java EE 的API,因此在java SE 9.0 中不再包含这个 Ja ...
- setShadpwLayer实现阴影效果
package com.loaderman.customviewdemo; import android.content.Context; import android.graphics.*; imp ...
- 【分类算法】感知机(Perceptron)
0 - 算法描述 感知机算法是一类二分类算法,其问题描述为,给定一个训练数据集 $$T=\{(x_1,y_1),(x_2,y_2),\cdots,(x_N,y_N)\},$$ 其中$x_i\in \m ...
- 002-创建型-03-单例模式(Singleton)【7种】、spring单例及原理
一.概述 保证一个类仅有一个实例,并提供一个全局访问点 私有构造器.线程安全.延迟加载.序列化和反序列化安全.反射攻击 1.1.适用场景 1.在多个线程之间,比如servlet环境,共享同一个资源或者 ...
- logging日志管理
日志:记录系统运行时的信息的(调试信息和异常信息) 基本用法: import logging logging.debug("这是一条调试信息") logging.info(&quo ...
- Python之queue模块以及生产消费者模型
队列 队列类似于一条管道,元素先进先出,进put(arg),取get() 有一点需要注意的是:队列都是在内存中操作,进程退出,队列清空,另外,队列也是一个阻塞的形态. 队列分类 队列有很多中,但都依赖 ...
- JQ操作select项
jQuery获取Select元素,并选择的Text和Value: 1. $("#select_id").change(function(){//code...}); //为Se ...
- 车道线检测github集锦
re1. github_lane_detection; end
- js 高级程序设计 第四章学习笔记
问题:怎么才能形象的理解堆栈空间? 1. 声明变量 使用 var 声明的变量会自动被添加到最接近的环境中.在函数内部,最接近的环境就是函数的局部 环境:在 with 语句中,最接近的环境是函数环境.如 ...