servlet(六)Filter过滤器

本文介绍Web开发中的拦截器Filter技术,包括Filter的作用、应用场景及生命周期。通过实例展示如何实现登录过滤器,对用户请求进行权限验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、简介

1、为什么需要拦截技术

这有点像我们小学数学中的提取公因式。把那些原本在每次请求或响应中都要重复做的事情,提取出来,统一在另外一个地方进行处理。

2、Filter的应用场景

编码过滤:统一编码。
敏感词过滤:对一些敏感的词用其他符号代替。
认证过滤:对用户请求进行统一的认证。
登录和审核过滤:对用户的访问请求进行记录和审核。
图像装换过滤:转换图像格式。
数据压缩过滤:对用户发生的数据进行压缩,从而减少传输量。
......
3、Filter的生命周期:

(1、)Filter的初始化

 

public void init(FilterConfig filterConfig)throws ServletException;//初始化

Filter的创建和销毁由web服务器负责。web应用程序启动时,web服务器将创建Filter的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能。Filter对象只会创建一次,init方法也只会执行一次。
 

 

(2、)执行拦截

 

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;//拦截请求

这个方法完成实际的过滤操作。当客户请求访问与过滤器关联的URL的时候,Servlet过滤器将先执行doFilter方法。FilterChain参数用于访问后续过滤器。
 

 

(3、)Filter销毁

 

public void destroy();//销毁


Filter对象创建后会驻留在内存,当web应用移除或服务器停止时才被销毁。该方法在Filter的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源。

 

 

 

二、应用:

1、两个步骤:
1)新建一个java类,实现Filter接口,并实现其doFilter方法。
2)在web.xml文件中(或使用注解的方式),对编写的filter类进行注册,并设置它所能拦截的资源。

 

例:登录过滤器,只可以在地址栏输入登录网址,检测到没有登录则调到登录界面:

/**   
 * 
 * 
 * @Package: com.iflytek.controller 
 * @author: tingzhang   
 * @date:     - -   上午  :  :   
 */
package com.iflytek.controller;

import java.io.IOException;
 
  import javax.servlet.Filter;
  import javax.servlet.FilterChain;
  import javax.servlet.FilterConfig;
  import javax.servlet.ServletException;
  import javax.servlet.ServletRequest;
  import javax.servlet.ServletResponse;
  import javax.servlet.http.HttpServletRequest;
   import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.iflytek.po.User;
   
    /** 
 * @ClassName: LoginFilter 
 * @Description: 登录过滤器
 * @author:tingzhnag7
 * @date: 2018-3-11 下午1:42:24  
 */
public class LoginFilter implements Filter {
   
       @Override
       public void init(FilterConfig filterConfig) throws ServletException {
           // TODO Auto-generated method stub
   
       }
   
       @Override
       public void doFilter(ServletRequest request, ServletResponse response,
               FilterChain chain) throws IOException, ServletException {
           // 获得在下面代码中要用的request,response,session对象
           HttpServletRequest servletRequest = (HttpServletRequest) request;
           HttpServletResponse servletResponse = (HttpServletResponse) response;
           HttpSession session = servletRequest.getSession();
   
           // 获得用户请求的URI
           String path = servletRequest.getRequestURI();
           //System.out.println(path);
           
           // 从session里取用户信息
           User user = (User) session.getAttribute("user");
   
           /*创建类Constants.java,里面写的是无需过滤的页面
           for (int i =  ; i < Constants.NoFilter_Pages.length; i++) {
   
               if (path.indexOf(Constants.NoFilter_Pages[i]) > - ) {
                   chain.doFilter(servletRequest, servletResponse);
                   return;
               }
           }*/
           
           // 登陆页面无需过滤
           if(path.indexOf("/login") > -1 ) {
               chain.doFilter(servletRequest, servletResponse);
               return;
           }
   
           System.out.println("拦截器"+user);
           // 判断如果没有取到员工信息,就跳转到登陆页面
           if (user == null ) {
               // 跳转到登陆页面
               servletResponse.sendRedirect("../login/login");
           } else {
               // 已经登陆,继续此次请求
               chain.doFilter(request, response);
           }
   
       }
   
       @Override
       public void destroy() {
           // TODO Auto-generated method stub
   
       }
   
   }

在web.xml里注册一下就OK了:

<!-- 配置登陆过滤器 -->
 
 
  
  <filter>
             <filter-name>login</filter-name>
             <filter-class>com.iflytek.controller.LoginFilter</filter-class>
        </filter>
      
          <filter-mapping>
              <filter-name>login</filter-name>
             <url-pattern>/*</url-pattern>
     </filter-mapping>
  
 
     

较全面的过滤器:

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * ajax请求session是否失效判断过滤器。
 * <pre>
 * 该过滤器只针对ajax请求,对于非ajax请求不执行任何逻辑操作。
 * 如果是ajax请求,判断当前session是否失效,如果已经失效,则响应头增加session失效标识。
 * </pre>
 * @author chaofang3
 *
 */
public class AjaxSessionFilter implements Filter {

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse resp = (HttpServletResponse) response;
		if (isAjaxRequest(req) && filterURI(req)) {
			// 判断session是否失效
			if (WebUtil.getCurrentUser(req) == null) {
				resp.setHeader("sessionstatus", "timeout");
				return;
			}
		}
		chain.doFilter(request, response);
	}

	/**
	 * 当前请求是否为ajax异步请求。
	 * @param request 当前request
	 * @return 如果当前请求为ajax请求,返回true,否则返回false
	 */
	private boolean isAjaxRequest(HttpServletRequest request) {
		return "XMLHttpRequest".equalsIgnoreCase(request
				.getHeader("x-requested-with"));
	}

	/**
	 * 当前请求是否过滤请求。
	 * <pre>
	 * 如果为过滤请求,则判断ajax请求的session是否失效。
	 * 当前只有绑定操作是非过滤请求。
	 * </pre>
	 * @param request 当前request请求
	 * @return 如果是登录操作,则不是过滤URI,返回false,否则返回true
	 */
	private boolean filterURI(HttpServletRequest request) {
		return !(request.getRequestURI().contains("ssoservice.jsp") || request.getRequestURI().contains("/login/") || request.getRequestURI().contains("/loginSuccess/") || request.getRequestURI().contains("/autoLogin/") || request.getRequestURI().contains("/reg/")|| request.getRequestURI().contains("/loginState/") || request.getRequestURI().contains("/getLoginFailTime/")
				 || request.getRequestURI().contains("/stat/"));
	}

	@Override
	public void destroy() {

	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

w_t_y_y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值