题目中的几个知识点,如果用上高中那会儿说的话,就是:
这是高考必考题!易错题!必须掌握!哈哈~
废话不多说,直接上考点内容,拿出笔记,准备,下面高能!
1. 什么是过滤器?
过滤器的英文名称为 Filter, 是 Servlet 技术中最实用的技术。
如同它的名字一样,过滤器是处于客户端和服务器资源文件之间的一道过滤网,帮助我们过滤掉一些不符合要求的请求,通常用作 Session 校验,判断用户权限,如果不符合设定条件,则会被拦截到特殊的地址或者基于特殊的响应。
过滤器的使用
首先需要实现 Filter接口然后重写它的三个方法
init 方法:在容器中创建当前过滤器的时候自动调用
destory 方法:在容器中销毁当前过滤器的时候自动调用
doFilter 方法:过滤的具体操作
举个栗子:我们首先实现接口,重写三个方法,对包含我们要求的四个请求予以放行,将其它请求拦截重定向至/online,只要在将MyFilter实例化后即可,我们在后面整合代码中一起给出。
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;
@Log4j2
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("初始化过滤器");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)servletRequest;
HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response);
String requestUri = request.getRequestURI();
log.info("请求地址是:"+requestUri);
if (requestUri.contains("/addSession")
|| requestUri.contains("/removeSession")
|| requestUri.contains("/online")
|| requestUri.contains("/favicon.ico")) {
filterChain.doFilter(servletRequest, response);
} else {
wrapper.sendRedirect("/online");
}
}
@Override
public void destroy() {
//在服务关闭时销毁
log.info("销毁过滤器");
}
}
项目测试中,我们搞复杂点,直接上两个过滤器:
过滤器1:
public class TestFilter1 implements Filter {
@Override
public void init(FilterConfig filterConfig) {
log.info("过滤器1初始化!!!!");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.info("过滤器1开始!!!!");
long start = System.currentTimeMillis();
filterChain.doFilter(servletRequest, servletResponse);
log.info("过滤器1结束!!!!耗时:" + (System.currentTimeMillis() - start) + "ms");
}
@Override
public void destroy() {
//当Filter被移除或服务器正常关闭时
log.info("过滤器1销毁!!!!");
}
}
过滤器2:
public class TestFilter2 implements Filter {
@Override
public void init(FilterConfig filterConfig) {
log.info("过滤器2初始化!!!!");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.info("过滤器2开始!!!!");
long start = System.currentTimeMillis();
filterChain.doFilter(servletRequest, servletResponse);
log.info("过滤器2结束!!!!耗时:" + (System.currentTimeMillis() - start) + "ms");
}
@Override
public void destroy() {
//当Filter被移除或服务器正常关闭时
log.info("过滤器2销毁!!!!");
}
}
执行结果:
2. 什么是拦截器?
Java中的拦截器是动态拦截 action 调用的对象,然后提供了可以在 action 执行前后增加一些操作,也可以在 action 执行前停止操作,功能与过滤器类似,但是标准和实现方式不同。
- 登录认证:在一些应用中,可能会通过拦截器来验证用户的登录状态,如果没有登录或者登录失败,就会给用户一个友好的提示或者返回登录页面,当然大型项目中都不采用这种方式,都是调单点登录系统接口来验证用户。
- 记录系统日志:我们在常见应用中,通常要记录用户的请求信息,比如请求
ip,方法执行时间等,通过这些记录可以监控系统的状况,以便于对系统进行信息监控、信息统计、计算 PV、性能调优等。 - 通用处理:在应用程序中可能存在所有方法都要返回的信息,这是可以利用拦截器来实现,省去每个方法冗余重复的代码实现。
拦截器的使用
我们需要实现 HandlerInterceptor 类,并且重写三个方法:
-
preHandle:在 Controoler 处理请求之前被调用,返回值是 boolean类型,如果是true就进行下一步操作;若返回false,则证明不符合拦截条件&#x