背景
相信很多同行都有过做后台权限管理或者api token登陆态校验之类的经验,我最开始工作的时候就是做OA系统的,印象最深刻的就是角色权限管理,当时经验少,把权限和业务功能做的耦合度非常的高,常常会在一个action的业务逻辑里面加很多的if else来做权限的判断,这是一段痛苦的经历。
最近开发的项目也有权限后台,提供出去的api要校验token判断登陆态,想起java应该是有拦截器的功能,就学起来用了,非常简单实用,完全跟业务逻辑分离。
spring中的拦截器
spring中提供了拦截器HandlerInterceptor,HandlerInterceptor的功能是:提供了三个方法来拦截请求的三个阶段,preHandle(在请求处理之前)、postHandle(请求处理后视图渲染前)、afterCompletion(请求完全结束之后)。我们不能通过拦截器修改请求内容,但是可以通过抛出异常(或者返回false)来暂停请求的执行。
配置拦截器分为三步:
- 创建我们自己的拦截器类并实现 HandlerInterceptor 接口。
- 创建一个Java配置类继承WebMvcConfigurerAdapter,并重写 addInterceptors 方法。
- 将对像手动添加到拦截器链中(在addInterceptors方法中添加)
具体代码如下:
- 创建拦截器,并实现业务逻辑
package com.ewt360.netschool.service.common;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author Rael.liu
* @since $Revision:1.0.0, $Date: 2018年05月17日 下午5:47 $
*/
public class AdminUserInterceptor implements HandlerInterceptor {
//用户服务
@Autowired
UserService userService;
//在执行Controller方法之前来执行的
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
//校验用户,校验失败则中断请求
boolean result = userService.check(httpServletRequest);
return result;
}
//在执行Controller方法之后返回modelAndView之前来执行,比如可以向视图中添加一些公共数据
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub
}
//完成对页面的渲染之后执行此方法,比如记录请求日志,性能监控
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
// TODO Auto-generated method stub
}
}
- 注册拦截器
/**
* kaike.la Inc.
* Copyright (c) 2014-2016 All Rights Reserved.
*/
package com.ewt360.netschool.service;
import com.ewt360.netschool.service.common.AdminUserInterceptor;
import com.ewt360.netschool.service.common.BackStageUserInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* @author chenghuanhuan@kaike.la
* @since $Revision:1.0.0, $Date: 2018年05月10日 下午7:12 $
*/
@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
@Autowired
private AdminUserInterceptor adminUserInterceptor;
@Autowired
private BackStageUserInterceptor backStageUserInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 多个拦截器组成一个拦截器链
// addPathPatterns 用于添加拦截规则
// excludePathPatterns 用户排除拦截
registry.addInterceptor(adminUserInterceptor).addPathPatterns("/admin/**");
registry.addInterceptor(backStageUserInterceptor).addPathPatterns("/backstage/**");
}
}