监听器和过滤器
- 过滤器的概念
- 过滤器的作用
- 过滤器快速入门
-
- 步骤
- 注解配置方式演示:
- xml配置演示
- 过滤器的执行流程
-
- doFilter方法: 每一次请求被拦截资源时,会执行,执行多次
- init方法:服务器启动后,会创建Filter对象,然后调用init方法,只执行一次,用于加载资源
- destroy方法:服务器关闭后,Filter对象被销毁时调用。如果服务器被正常关闭,则会指向destory方法,只执行一次,用于释放资源
- 拦截路径的配置
- 拦截方式的配置----资源被访问的方式
-
- 注解配置
- xml配置
- 过滤器链(配置多个过滤器)
-
- 执行顺序
- 过滤器的先后顺序问题
- 登录验证案例
- 过滤敏感词汇
-
- 分析: 需要对request对象进行增强
- 增强对象的功能
-
- 设计模式: 一些通用的解决问题的固定方式
-
- 1.装饰模式
- 2.代理模式
-
- 实现步骤
- 增强方式
- 监听器---Listener
-
- 监听器机制
- 步骤
-
- 配置web.xml方式---注册监听
- 注解配置,不需要指定路径---注册监听
- 监听器对于我们来说,多用来配置资源
- 演示:
- 生命周期监听器
过滤器的概念
概念:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能
过滤器的作用
作用: 一般用于完成通用的操作,例如: 登录验证,统一编码处理,敏感字符过滤
过滤器快速入门
步骤
- 定义一个类,实现Filter接口
- 复写方法
- 配置拦截路径
1.web.xml方式配置
2.注解方式配置
3.过滤器的生命周期方法
4.过滤器配置详解
5.过滤器链
注解配置方式演示:
@WebFilter("/*")//访问所有资源之前,都会执行该过滤器--->拦截路径
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("过滤器被执行了");
//放行---不然资源无法通过,到达浏览器显示
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
xml配置演示
<filter>
<filter-name>demo1</filter-name>
<filter-class>com.FL.flDemo2</filter-class>
</filter>
<filter-mapping>
<filter-name>demo1</filter-name>
<!--拦截所有资源路径-->
<url-pattern>/*</url-pattern>
</filter-mapping>
过滤器的执行流程
public class flDemo2 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//对request对象请求消息增强
System.out.println("第一次经过过滤器");
//放行
filterChain.doFilter(servletRequest,servletResponse);
//回来的时候,不会重新执行do方法,而是执行放行下面的代码
//对response对象的响应消息增强
System.out.println("第二次经过过滤器");
}
@Override
public void destroy() {
}
}
回来的时候,不会重新执行do方法,而是执行放行下面的代码
doFilter方法: 每一次请求被拦截资源时,会执行,执行多次
init方法:服务器启动后,会创建Filter对象,然后调用init方法,只执行一次,用于加载资源
destroy方法:服务器关闭后,Filter对象被销毁时调用。如果服务器被正常关闭,则会指向destory方法,只执行一次,用于释放资源
拦截路径的配置
拦截目录指的是要访问指定资源时,自己设置的访问路径,访问路径通过注解或者xml配置文件设置—urlPattern
拦截方式的配置----资源被访问的方式
注解配置
xml配置
在标签内部放入如上五个选择其一即可完成设置
过滤器链(配置多个过滤器)
执行顺序
过滤器的先后顺序问题
字符串比较大小,是从第一个字符的大小开始比较
登录验证案例
注意:
过滤敏感词汇
分析: 需要对request对象进行增强
增强对象的功能
设计模式: 一些通用的解决问题的固定方式
1.装饰模式
2.代理模式
实现步骤
接口:
package test;
public interface ProxyInterface {
void sale(int money);
void show();
}
实现接口的真实类:
package test;
public class Proxy1 implements ProxyInterface{
@Override
public void sale(int money) {
System.out.println("价钱为:"+money);
}
@Override
public void show() {
System.out.println("show方法的调用");
}
}
测试主类:
public class main {
public static void main(String[] args) {
//动态代理增强proxy对象
//第一个参数: 类加载器: 真实对象.class.getClassLoader()
//第二个参数: 接口数组:真实对象.class.getInterfaces()
//第三个参数: 处理器:InvocationHandler
Proxy1 p=new Proxy1();
//代理对象和真实对象实现相同接口
ProxyInterface pi= (ProxyInterface) Proxy.newProxyInstance(p.getClass().getClassLoader(), p.getClass().getInterfaces(), new InvocationHandler() {
/*
* 代理逻辑编写的方法,代理对象调用的所有方法都会触发该方法执行
* proxy: 代理对象---》pi
* method: 代理对象调用的方法,被封装为的对象
* args: 代理对象调用方式时,传递的实际参数
* */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("invoke方法执行");
System.out.println(method.getName());
System.out.println(args[0]);
return null;
}
});
pi.sale(8000);
}
}
代理对象和真实对象实现相同接口
调用有参方法:
//动态代理增强proxy对象
//第一个参数: 类加载器: 真实对象.class.getClassLoader()
//第二个参数: 接口数组:真实对象.class.getInterfaces()
//第三个参数: 处理器:InvocationHandler
Proxy1 p=new Proxy1();
//代理对象和真实对象实现相同接口
ProxyInterface pi= (ProxyInterface) Proxy.newProxyInstance(p.getClass().getClassLoader(), p.getClass().getInterfaces(), new InvocationHandler() {
/*
* 代理逻辑编写的方法,代理对象调用的所有方法都会触发该方法执行
* proxy: 代理对象---》pi
* method: 代理对象调用的方法,被封装为的对象
* args: 代理对象调用方式时,传递的实际参数
* */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String s =(String)method.invoke(p, 8000);
return s;
}
});
String sale = pi.sale(8000);
System.out.println(sale);
增强方式
接口:
public interface ProxyInterface {
String sale(double money);
void show();
}
被代理类:
public class Proxy1 implements ProxyInterface{
@Override
public String sale(double money) {
System.out.println("花了"+money+"买联想电脑");
return "联想电脑";
}
@Override
public void show() {
System.out.println("联想电脑展示...");
}
}
测试主类:
public class main {
public static void main(String[] args) {
//动态代理增强proxy对象
//第一个参数: 类加载器: 真实对象.class.getClassLoader()
//第二个参数: 接口数组:真实对象.class.getInterfaces()
//第三个参数: 处理器:InvocationHandler
Proxy1 p=new Proxy1();
//代理对象和真实对象实现相同接口
ProxyInterface pi= (ProxyInterface) Proxy.newProxyInstance(p.getClass().getClassLoader(), p.getClass().getInterfaces(), new InvocationHandler() {
/*
* 代理逻辑编写的方法,代理对象调用的所有方法都会触发该方法执行
* proxy: 代理对象---》pi
* method: 代理对象调用的方法,被封装为的对象
* args: 代理对象调用方式时,传递的实际参数
* */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//1,增强参数
//判断是否是sale方法
if(method.getName().equals("sale"))
{
//1.增强参数---将调用方法时传入的参数值,变为百分之85,在传回
double money=(double)args[0];
money*=0.85;
//增强方法体的逻辑
System.out.println("免运费");
//使用真实对象调用方法
String obj = (String)method.invoke(p, money);
//2,增强返回值类型
return obj+"和赠送的鼠标垫和键盘";
}
else
{
String obj = (String)method.invoke(p, args);
return obj;
}
}
});
String sale = pi.sale(8000);
System.out.println(sale);
}
}
监听器—Listener
监听器机制
步骤
配置web.xml方式—注册监听
<!--配置监听
注册监听
-->
<listener>
<listener-class>com.FL.Listener</listener-class>
</listener>
注解配置,不需要指定路径—注册监听
@WebListener
监听器对于我们来说,多用来配置资源
演示:
Listener监听器对象:
@WebListener
public class Listener implements ServletContextListener{
/*
* 监听ServletContext对象创建的,ServletContext对象服务器启动后自动创建
* 在服务器启动后自动调用
* */
@Override
public void contextInitialized(ServletContextEvent sce) {
//加载资源文件
//1.获取ServletContextEvent对象
ServletContext servletContext = sce.getServletContext();
//2.加载资源文件
String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");
//3,获取真实路径
String realPath = servletContext.getRealPath(contextConfigLocation);
//4.加载进内存
try {
FileInputStream fileInputStream = new FileInputStream(new File(realPath));
System.out.println(fileInputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
/*
* 在服务器关闭后,ServletContext对象被销毁,当服务器正常关闭后该方法被调用
* */
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
web.xml中可以指定要导入的资源文件:
<!--指定初始化参数信息-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>