SpringBoot实现拦截器和过滤器

一、使用Interceptor拦截器

1.首先新建一个拦截器实现HandlerInterceptor接口

以一个简单的token验证为例,验证通过,将用户信息放入作用域,返回true

不通过返回false

@Service
public class UserTokenInterceptor implements HandlerInterceptor {
	@Autowired
	private SysusertokenMapper sysusertokenMapper;
	@Autowired
	private SysloginuserMapper sysloginuserMapper;
	@Autowired
	private SysuserMapper sysuserMapper;
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// 在请求处理之前进行调用(Controller方法调用之前),返回true才会继续往下执行,返回false取消当前请求
		boolean isAccess = false;
		String tokenCode = request.getHeader("Token");
		if (tokenCode != null && !"".equals(tokenCode)) {
			//查询未过期的
			Sysusertoken sysusertoken = sysusertokenMapper.selectByTokenCode(tokenCode);
			if (sysusertoken != null) {
				Sysloginuser sysloginuser  = sysloginuserMapper.selectByPrimaryKey(sysusertoken.getLoginid());
				Sysuser sysuser = sysuserMapper.selectByPrimaryKey(sysloginuser.getUserid());
				request.getSession().setAttribute("user",sysuser);
				request.getSession().setAttribute("token",tokenCode);			
				isAccess = true;
			}
		}
		return isAccess;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {

	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {

	}

}

2.新建一个配置类来管理拦截器,将你之前新建的拦截器注入进来

addPathPatterns("/**")是拦截所有请求

excludePathPatterns("","",...)配置无需拦截的请求

package com.gcexe.monitor.filter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

@Component
public class UserTokenAppConfigurer extends WebMvcConfigurationSupport{
	
	@Autowired
	private UserTokenInterceptor userTokenInterceptor;
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 多个拦截器组成一个拦截器链
        // addPathPatterns 用于添加拦截规则
        // excludePathPatterns 用户排除拦截
		registry.addInterceptor(userTokenInterceptor).addPathPatterns("/**")
		.excludePathPatterns("/account/login","/account/register");		
		super.addInterceptors(registry);
	}
}

注意加上@Component注解,使其可以被扫描到

二、使用servlet的filter过滤器

新建一个类实现javax.servlet.Filter接口,通过@WebFilter注解来配置要拦截的请求,doFilter方法是要进行的操作。

package com.gcexe.monitor.filter;

import java.io.IOException;
import java.util.Arrays;

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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.gcexe.monitor.persistence.dao.SysloginuserMapper;
import com.gcexe.monitor.persistence.dao.SysuserMapper;
import com.gcexe.monitor.persistence.dao.SysusertokenMapper;
import com.gcexe.monitor.persistence.entity.Sysloginuser;
import com.gcexe.monitor.persistence.entity.Sysuser;
import com.gcexe.monitor.persistence.entity.Sysusertoken;

@Component
@WebFilter(urlPatterns = "/**", filterName = "monitorFilter")
public class TokenAuthorFilter implements Filter {
	@Autowired
	private SysusertokenMapper sysusertokenMapper;
	@Autowired
	private SysloginuserMapper sysloginuserMapper;
	@Autowired
	private SysuserMapper sysuserMapper;

	private static final String[] excludePathPatterns = { "/monitor/account/login", "/monitor/account/register" };

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub

	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
			throws IOException, ServletException {
		// 在请求处理之前进行调用(Controller方法调用之前),返回true才会继续往下执行,返回false取消当前请求
		boolean isFilter = false;
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) resp;
		// 不拦截登陆和注册
		String url = request.getRequestURI();
		if (Arrays.asList(excludePathPatterns).contains(url)) {
			chain.doFilter(request, response);
			return;
		}

		String tokenCode = request.getHeader("Token");
		if (tokenCode != null && !"".equals(tokenCode)) {
			// 查询未过期的
			Sysusertoken sysusertoken = sysusertokenMapper.selectByTokenCode(tokenCode);
			if (sysusertoken != null) {
				Sysloginuser sysloginuser = sysloginuserMapper.selectByPrimaryKey(sysusertoken.getLoginid());
				Sysuser sysuser = sysuserMapper.selectByPrimaryKey(sysloginuser.getUserid());
				request.getSession().setAttribute("user", sysuser);
				request.getSession().setAttribute("token", tokenCode);
				isFilter = true;
			}
		}
		if (isFilter) {
			chain.doFilter(request, response);
		}

	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

}

执行chain.doFilter(request,response)方法类似于上面的返回true,让程序继续往下执行

可以自己配置返回内容,无需拦截的请求,我这里是定义了一个数组,自行判断,对应地址直接执行chain.doFilter(reuqest.response),同样注意加上@Component注解

 

三、过滤器和拦截器区别

主要区别如下:

1、拦截器主要是基于java的反射机制的,而过滤器是基于函数回调

2、拦截器不依赖于servlet容器,过滤器依赖于servlet容器

3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用

4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问

5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次

两种方式均可以使用,相比较而言,第一种方式较为方便,我一开始也是使用的这种,但是后来需要集成Spring Boot Validator框架时,发现验证数据一直不生效,后来发现是和Inteceptor有冲突,去掉拦截就可以验证了,暂时还没找到解决的办法,所以改为使用第二种方法。

  • 5
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值