概念:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能
作用: 一般用于完成通用的操作,例如: 登录验证,统一编码处理,敏感字符过滤
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() {
}
}
<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方法,而是执行放行下面的代码
拦截目录指的是要访问指定资源时,自己设置的访问路径,访问路径通过注解或者xml配置文件设置—urlPattern
在标签内部放入如上五个选择其一即可完成设置
字符串比较大小,是从第一个字符的大小开始比较
注意:
接口:
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>
<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>