SpringMVC拦截器的实现一般有两种方式
第一种方式是要定义的Interceptor类要实现了Spring的HandlerInterceptor 接口
第二种方式是继承实现了HandlerInterceptor接口的类,比如Spring已经提供的实现了HandlerInterceptor接口的抽象类HandlerInterceptorAdapter
HandlerInterceptor 接口中定义了三个方法,我们就是通过这三个方法来对用户的请求进行拦截处理的。
preHandle(): 这个方法在业务处理器处理请求之前被调用,SpringMVC 中的Interceptor 是链式的调用的,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor 。每个Interceptor 的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor 中的preHandle 方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔值Boolean 类型的,当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法,如果已经是最后一个Interceptor 的时候就会是调用当前请求的Controller 方法。
postHandle():这个方法在当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。postHandle 方法被调用的方向跟preHandle 是相反的,也就是说先声明的Interceptor 的postHandle 方法反而会后执行。
afterCompletion():该方法也是需要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。
定义拦截器基类(需要继承HandlerInterceptorAdapter )
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* 拦截器基类
*
* @author 向振华
* @date 2019/04/17 13:42
*/
public class BaseInterceptor extends HandlerInterceptorAdapter {
/**
* 发送异常信息
*
* @param response
* @param jsonString
*/
void sendMsg(HttpServletResponse response, String jsonString) {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
try (PrintWriter out = response.getWriter()) {
out.append(jsonString);
} catch (IOException e) {
e.printStackTrace();
}
}
}
配置登录拦截器继承拦截器基类
/**
* 登录拦截器
*
* @author 向振华
* @date 2019/04/17 13:42
*/
public class LoginInterceptor extends BaseInterceptor {
@Resource
private LoginService loginService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
//获取当前用户
User user = loginService.currentUser();
if (user == null) {
//前端固定格式
ResponseMessage responseMessage = new ResponseMessage<>(-1, "请登录!");
String jsonString = JSON.toJSONString(responseMessage);
sendMsg(response, jsonString);
return false;
}
return true;
}
}
public class ResponseMessage<T> implements Serializable {
/**
* 1:成功 -1:失败
*/
private int code;
/**
* 消息
*/
private String msg;
/**
* 返回数据
*/
private T data;
}
使拦截器生效配置
/**
* 配置拦截器
*
* @author 向振华
* @date 2019/04/17 13:42
*/
@Configuration
@EnableTransactionManagement
public class MyWebAppConfigurer extends WebMvcConfigurerAdapter {
@Bean
LoginInterceptor loginInterceptor() {
return new LoginInterceptor();
}
/**
* 拦截器配置
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//配置登录拦截器
registry.addInterceptor(loginInterceptor())
.excludePathPatterns("/login")//不需要拦截的url
.excludePathPatterns("/isRegistered")//不需要拦截的url
.addPathPatterns("/**");
//配置其他拦截器(会按配置顺序拦截,先配置的先拦截)
// ...
//加入拦截
super.addInterceptors(registry);
}
}
登录拦截优化:https://blog.youkuaiyun.com/Anenan/article/details/89355500