一、Filter
作用:
1、登录验证——不登录不让请求其他资源
2、关键字过滤
.....
使用方法:
- 1、创建一个Filter接口的实现类,重写接口中的抽象方法
public class FilterDemo1 implements Filter {
public void init(FilterConfig config) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
chain.doFilter(req, resp);
}
public void destroy() {
}
}
Filter接口中的方法说明:
①.init方法:服务器启动时,会创建Filter对象,调用唯一的一次init方法。
②.doFilter方法:每次有过滤路径的资源的请求,就调用一次。
chain.doFilter(req, resp);作用是放行。③.destroy方法:服务器正常关闭前,调用一次,一般用于释放资源。
2、用web.xml或者使用注解进行配置
1. web.xml配置
<filter>
<filter-name>demo1</filter-name>
<filter-class>cn.itcast.web.filter.FilterDemo1</filter-class>
</filter>
<filter-mapping>
<filter-name>demo1</filter-name>
<!-- 拦截路径 -->
<url-pattern>拦截路径 </url-pattern>
</filter-mapping>
2.注解配置:
@WebFilter(value = "拦截路径" , dispatcherTypes={拦截方式,..} )
拦截路径的写法:
- 具体资源路径: /index.jsp 只有访问index.jsp资源时,过滤器才会被执行
- 拦截目录: /user/* 访问/user下的所有资源时,过滤器都会被执行
- 后缀名拦截: *.jsp 访问所有后缀名为jsp资源时,过滤器都会被执行
- 拦截所有资源:/* 访问所有资源时,过滤器都会被执行
拦截方式的写法:
设置dispatcherTypes属性
DispatcherType. REQUEST:默认值。浏览器直接请求资源
DispatcherType. FORWARD:转发访问资源
DispatcherType. INCLUDE:包含访问资源
DispatcherType. ERROR:错误跳转资源
DispatcherType. ASYNC:异步访问资源
过滤器链:就好比几层的筛子。
过滤器的执行流程:
1. 过滤器1
2. 过滤器2
3. 资源执行
4. 过滤器2
5. 过滤器1
图片.png
过滤器先后顺序问题:
- 注解配置:按照类名的字符串比较规则比较,值小的先执行
- 如: AFilter 和 BFilter,AFilter就先执行了。
- web.xml配置: <filter-mapping>谁定义在上边,谁先执行
二、动态代理实现request对象增强
代理模式是一种设计模式
所谓代理就是第三方,去调用原来的方法并且在此之上进行一些功能的增强,何为动态代理,就是使用反射技术进行实现,不用依赖于具体的类文件。
关于代理的概念:
- 真实对象:被代理的对象
- 代理对象:真实对象增强之后的对象。
- 代理模式:代理对象代理真实对象,达到增强真实对象功能的目的。
动态代理的实现步骤:
- 代理对象和真实对象实现相同的接口
- 代理对象 = Proxy.newProxyInstance();
- 使用代理对象调用方法。
- 增强方法
newProxyInstance()方法的参数列表:
真实对象.getClass().getClassLoader()——类加载器,把真实对象的Class对象加载进入内存。
真实对象.getClass().getInterfaces()——获取所有的接口的Class对象
new InvocationHandler(){
代理对象调用所有的方法都会执行此方法,调用的方法对象会传给method参数。
代理对象调用方法的参数会传递给args数组对象。
匿名内部类实现 invoke(Object proxy, Method method, Object[] args) 方法
}
敏感字过滤器
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
//拦截资源路径为testSensitiveFilterServlet
@WebFilter("/testSensitiveFilterServlet")
public class SensitivewordsFilter implements Filter {
List<String> sensitiveWordsList = new ArrayList<String>();
public void init(FilterConfig config) throws ServletException {
try{
String realPath = config.getServletContext().getRealPath("/WEB-INF/classes/words.txt");
System.out.println(realPath);
BufferedReader br = new BufferedReader(new FileReader(realPath));
String line = null;
while((line = br.readLine())!=null){
sensitiveWordsList.add(line);
}
System.out.println(sensitiveWordsList);
}catch (Exception e){
e.printStackTrace();
}
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//使用动态代理来增强getParameter方法,完成过滤工作
ServletRequest proxy_Requset = (ServletRequest)Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
@Override
//调用getParameter方法method就是getParameter方法对象
//args是getParameter(String str)的str数据。
//调用setAttribute方法method就是setAttribute方法对象
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("getParameter".equals(method.getName())){
String msg = (String) method.invoke(req,args);
for (String s : sensitiveWordsList) {
if (msg.contains(s)){
msg = msg.replaceAll(s,"***");
}
}
return msg;
}
return method.invoke(req,args);
}
});
chain.doFilter(proxy_Requset, resp);
}
public void destroy() {
}
}
三、监听器Listener
Web三大技术:Servlet、Filter、Listener
事件监听机制
- 事件 :一件事情
- 事件源 :事件发生的地方
- 监听器 :一个对象
- 注册监听:将事件、事件源、监听器绑定在一起。 当事件源上发生某个事件后,执行监听器代码
ServletContextListener:web容器监听器
监听ServletContext对象的创建和销毁
- 方法:
- void contextDestroyed(ServletContextEvent sce) :ServletContext对象被销毁之前会调用该方法
- void contextInitialized(ServletContextEvent sce) :ServletContext对象创建后会调用该方法
- 步骤:
- 定义一个ServletContextListener的实现类,重写接口的抽象方法。
-
- 配置
- web.xml
<listener>
<listener-class>监听器类的路径</listener-class>
</listener>
<!-- 指定初始化参数,一般用来加载默认配置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>
//使用servletContext.getInitParameter("contextConfigLocation");就能获取到param-value里的值。