springmvc 拦截器 过滤器

663

拦截器

  • 拦截器是springmvc中的一种,需要实现HandlerInterceptor接口。
  • 拦截器和过滤器类似,功能方向侧重点不同。 过滤器是用来过滤器请求参数,设置编码字符集等工作。拦截器是拦截用户的请求,做请求做判断处理的。
  • 拦截器是全局的,可以对多个Controller做拦截。
    一个项目中可以有0个或多个拦截器, 他们在一起拦截用户的请求。
  • 拦截器常用在:用户登录处理,权限检查, 记录日志。
    image-1675583755765

是基于Java的jdk动态代实现的,实现HandlerInterceptor接口。不依赖于servlet容器,

拦截器针对于contraller方法,并且能获取到所有的类,对类里面所有的方法实现拦截,粒度更小,拦截器中可以注入service,也可以调用业务逻辑

springmvc.xml

    <!--拦截器-->
    <!--后台身份认证-->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/admin/**"/>
            <mvc:mapping path="/admin"/>
            <bean class="cn.noybzy.interceptors.LoginInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
package cn.noybzy.interceptors;

import cn.noybzy.security.bean.UserSecurity;
import lombok.extern.log4j.Log4j;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * 登录验证拦截器
 * @author noybzy
 */
@Log4j
public class LoginInterceptor implements HandlerInterceptor {

    //API 请求通道
    private static final String TOKEN="123456";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        HttpSession session = request.getSession();
        UserSecurity userSecurity = new UserSecurity(session);

        if (userSecurity.getStatus()==1 || TOKEN.equals(request.getParameter("TOKEN"))){
            log.info(userSecurity.getUseremail()+"登录成功!");
            return true;
        }
        log.warn(userSecurity.getUseremail()+"登录失败!");
        response.sendRedirect("/ssmProject_war_exploded/login");
        return false;
    }
}

拦截器的执行

  1. preHandle():在请求被处理之前进行操作
  2. preHandle():在请求被处理之后,但结果还没有渲染前进行操作,可以改变响应结果
  3. afterCompletion():所有的请求响应结束后执行善后工作,清理对象,关闭资源

过滤器

过滤器使用filter实现,拦截的是request请求,基于回调,基于servlect规范

依赖容器,有初始化方法和销毁方法,拦截的是地址,粒度很大

  • 过滤器Filter:过滤器通过实现Filter接口,实现了过滤器的三个方法,分别是初始化方法,dofilter方法和销毁方法,随着容器的启动和销毁而初始化和销毁,依赖于servlet容器,过滤器拦截的是地址栏请求,过滤器实在进入容器后执行的servlet之前后执行,针对的在处理业务之前的操作。

代码

public class Filter1 implements Filter {
 
	public void destroy() {
		// TODO Auto-generated method stub
		System.out.println("过滤器1销毁方法");
	}
 
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		System.out.println("过滤器1,客户端向Servlet发送的请求被我拦截到了,设置请求编码");
		chain.doFilter(request, response);
		System.out.println("过滤器1,Servlet向客户端发送的响应被我拦截到了,设置相应编码");
	}
 
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		System.out.println("过滤器1初始化方法");
	}
 
}

web.xml

public class Filter1 implements Filter {
 
	public void destroy() {
		// TODO Auto-generated method stub
		System.out.println("过滤器1销毁方法");
	}
 
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		System.out.println("过滤器1,客户端向Servlet发送的请求被我拦截到了,设置请求编码");
		chain.doFilter(request, response);
		System.out.println("过滤器1,Servlet向客户端发送的响应被我拦截到了,设置相应编码");
	}
 
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		System.out.println("过滤器1初始化方法");
	}
 
}

对比

  • 两者都是AOP编程思想的实现,都能够实现权限控制和日志记录等问题的处理,但是两者粒度不同拦截对象不一样

  • 适用范围不同:Filter是servlet的规范,只能用于web程序,但是拦截器可以用于application等程序。

  • 规范不同:Filter是servlet的规范。但是Interceptor是spring容器支撑,有spring框架支持。

  • 使用资源不一样:spring的拦截器由于依赖spring,也是spring的一个组件,因此能够在拦截器中使用spring的任何资源和对象。例如service对象,数据源,事务管理等,通过ioc注入拦截器即可,而filter不能

  • 粒度不同:Filter只能在servlet的前后起作用,而拦截器能在方法前后异常前后执行,更加灵活,粒度更小,spring框架程序优先使用拦截器。
    image-1675584393415

参考:
https://blog.csdn.net/huyiju/article/details/83028720
https://blog.csdn.net/weixin_48826996/article/details/126120436