filter过滤器
WEB三大核心组件: Servelt Filter Listener
1、Filter 过滤器概述
过滤目标:请求
可以根据配置条件对 满足条件的请求进行一个检查 检查请求是否满足 条件 如果满足 则该请求可以继续执行 负责 就返回。
2、Filter 实现
方式一:通过实现filter接口
第一步 实现Filter接口来实现自己的Filter
public class HelloFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//FilterConfig 获取Filter的配置信息
String filterName = filterConfig.getFilterName();
String username = filterConfig.getInitParameter("username");
System.out.println( filterName +"---"+username);
}
//执行拦截
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("doFilter....");
//表示对拦截到的请求放行
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
System.out.println("destroy......");
}
}
第二步 配置Filter
<filter>
<filter-name>helloFilter</filter-name>
<filter-class>org.lanqiao.web.filter.HelloFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>helloFilter</filter-name>
<!--指的是可以拦截那些请求 /* 表示拦截所有请求-->
<url-pattern>/*</url-pattern>
</filter-mapping>
方式二:通过继承HttpFilter
继承HttpFilter
public class TestFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("test Filter doFilter");
//this.getFilterConfig() 可以获取filterCcnfig对象
String filterName = this.getFilterConfig().getFilterName();
System.out.println(filterName);
chain.doFilter(request,response);
}
}
3、执行顺序:
当存在多个Filter的时候 Filter的执行顺序与在web.xml中的配置顺序相关 是和<filter-mapping>节点顺序相关
配置在前的先执行
Filter链的执行顺序

4、基于注解的Filter
@WebFilter("/*")
@WebFilter(filterName = "hello" ,value = "/*")
基于注解的Filter链的执行拦截顺序 与Filter类的名称的字典顺序相关。
Q:在开发中 那些请求用该被拦截 而那些请求不应该被拦截?
1 静态资源 不应该被拦截
2 所以 在拦截的时候 应该拦截请求servlet的请求
3 拦截的url .do/.action
5、拦截类型
<dispatcher>指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。用户可以设置多个<dispatcher>子元素用来指定 Filter 对资源的多种调用方式进行拦截。
<dispatcher>子元素可以设置的值及其意义
- REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过 RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
只要发起的操作是一次HTTP请求,比如请求某个URL、发起了一个GET请求、表单提交方式为POST的POST请求、表单提交方式为GET的GET请求。一次重定向则前后相当于发起了两次请求,这些情况下有几次请求就会走几次指定过滤器。
- INCLUDE:如果目标资源是通过RequestDispatcher的include()方法(<jsp:include page=“xxx.jsp” />)访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
- FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
只有当当前页面是通过请求转发转发过来的情形时,才会走指定的过滤器
- ERROR:当配置了错误页面,并且发生错误时拦截器触发 ,如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。针对这种拦截方式,必须在web.xml中配置
<!-- 错误页面的配置-->
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/500.jsp</location>
</error-page>
在配置连接方式的时候 则<url-pattern> 拦截规则 必须时/* 负责不起作用
6、典型应用:
应用一:字符集过滤器
xml配置
<context-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</context-param>
filter实现
@WebFilter("/*")
public class EncodingFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest req, HttpServletResponse resp, FilterChain chain) throws IOException, ServletException {
String encoding = this.getServletContext().getInitParameter("encoding");
req.setCharacterEncoding(encoding);
resp.setContentType("text/html;charset=utf-8");
//放行
chain.doFilter(req,resp);
}
}
应用二:检查用户是否登录
xml配置
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>org.lanqiao.web.filter.CheckLoginFilter</filter-class>
<!--不过滤的请求-->
<init-param>
<param-name>uncheckurl</param-name>
<param-value>login.jsp,login.do,.jpg,.png,.gif,.css,.js</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
filter实现
public class CheckLoginFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
//获取当前的请求路劲
String requestUrl = request.getRequestURL().toString();
//获取请求路径的目标地址
String requestEndUrl = requestUrl.substring(requestUrl.lastIndexOf("/")+1);
//获取FilterConfig对象
FilterConfig config = this.getFilterConfig();
// 获取配置的不检查的请求
String uncheckUrlStr = config.getInitParameter("uncheckurl");
//不检查的请求配置参数按照逗号分隔为数组
String[] uncheckUrlArr = uncheckUrlStr.split(",");
//将数组转换为lsit
List<String> uncheckUrlList = Arrays.asList(uncheckUrlArr);
//如果包含在配置的不检查列表中 则直接放行
if(uncheckUrlList.contains(requestEndUrl)){
chain.doFilter(request,response);
}else{
//用户是否登录 就是看session中是否存在用户对象
HttpSession session = request.getSession();
User user = (User) session.getAttribute("USER");
if(user != null){
chain.doFilter(request,response);
}else{
response.sendRedirect("/login.jsp");
}
}
}
}
本文详细介绍了Servlet Filter的工作原理,包括其实现方式、执行顺序及基于注解的配置。探讨了如何通过Filter进行请求检查和资源拦截,以及其在字符集过滤和用户登录验证中的典型应用。
2134

被折叠的 条评论
为什么被折叠?



