在许多的Java Web 框架都有实现Interceptor 的方法,例如Struct2 是Interceptor就是Spring MVC 就是HandlerInterceptor,而Interceptor 介於DispatcherServlet 与Controller 之间,可以在请求到达Controller 前或回应回传出Controller 时进行拦截,拦截成功一样可以实作一些自定义的业务逻辑或对回应资料进行修改。
建立Interceptor 的常见方法一样有两种,一种是实作org.springframework.web.servlet.HandlerInterceptor 介面,另一种则是继承org.springframework.web.servlet.handler.HandlerInterceptorAdapter 类别,不管是哪种方法都要覆写三个方法。
preHandle(...)
: 该方法是在请求进入Controller 之前执行,用来进行一些初始化或预处理,也可以判断是否继续执行下去。
该方法返回值为Boolean 值,返回false 表示请求结束,後续Interceptor 和Controller 均不会执行,而返回true 表示请求继续,会继续调用下一个Interceptor 或是Controller。
postHandle(...)
: 该方法是Controller 之後执行的方法,会在DispatcherServlet 进行视图渲染以前被调用,所以可以在这个方法中队Controller 处理之後的ModelAndView 物件进行操作。
afterCompletion(...)
: 该方法是在整个请求结束之後,在DispatcherServlet 对视图渲染完成後执行,主要进行资源清理。
package com.example.iThomeIronMan.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.example.iThomeIronMan.controller.LoginRegisterController;
import com.example.iThomeIronMan.model.Member;
@Component
public class IndexInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(LoginRegisterController.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// TODO Auto-generated method stub
String uri = new String(request.getRequestURI());
HttpSession session = request.getSession();
Member member = (Member) session.getAttribute("MemberSession");
// 已登入
if(member != null) {
logger.info(member.getName() + " 访问 " + uri);
return true;
}
// 未登入
else {
return false;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
最後设定拦截器使用InterceptorRegistry 的三个方法。
addInterceptor()
: 注册拦截器。addPathPatterns()
: 新增拦截路径。excludePathPatterns()
: 新增不拦截路径。package com.example.iThomeIronMan.config;
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.WebMvcConfigurer;
import com.example.iThomeIronMan.interceptor.IndexInterceptor;
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Autowired
private IndexInterceptor indexInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// TODO Auto-generated method stub
registry.addInterceptor(indexInterceptor)
.addPathPatterns("/information/**", "/updatePassword/**")
.excludePathPatterns("/login/**", "/register/**", "/css/**", "/images/**", "/js/**");
}
}
我们可以根据上面的介绍画出上面这个流程图,Filter 的作用区间在请求到达Servlet 之前,Interceptor 在Dsipatcher Servlet 接收请求之後在交由Controller 之前;Filter 面对的是请求而Interceptor 面对的是Controller,两者的主要应用场景与功能几乎类似,例如登入认证、Session 检查和处理等等,而主要的差异就是越早的过滤或拦截对系统性能的消耗越少,在应用上就要由开发人员根据实际业务情况综合考虑了。
HandlerInterceptors vs. Filters in Spring MVC
Spring Boot之Filter和Interceptor的对比分析
<<: [Day 24] Facial Landmark: MTCNN
tags: ItIron2021 Javascript 前言 前两天这样搞下来,相信你们对this已...
再来检核DynamoDB的资料, 比较与SQL的不同 回到DynamoDB Portal, 点选第一...
在进行串接前,首先需要有定义串接的规格,例如:串接的协定 (HTTP、或走 FTP 档案交换等等)、...
CDN缓存命中率低的可能原因如下: HTTP Header设置不当导致无法缓存,请检查源站Cache...
CSS的选择器分为基础选择器以及复合选择器 本日将将继续说明复合选择器 复合选择器可以更准确更高效的...