Request#getRequestDispatcher()
包含两个重要方法:请求转发和请求包含。
一个请求跨多个Servlet时,需要使用请求转发和请求包含。
示例伪代码 :
public void requestDispatcher() throws Exception {
Request request = new Request(null);
Response response = new Response();
// 首先需要获得一个RequestDispatcher 对象
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/forward");
requestDispatcher.forward(request,response);// 调用forward()方法进行请求转发
requestDispatcher.include(request,response);// 调用include()方法进行请求包含
response.sendRedirect("/redirect");// 调用sendRedirect()方法进行重定向
}
HandlerInterceptor包含三个方法 :
preHandle
是在找到处理handler对象的HandlerMapping之后,HandlerAdapter调度handler之前执行。
postHandle
是在HandlerAdapter调度handler之后,DispatcherServlet渲染视图之前执行,可以通过ModelAndView来向视图中添加一些信息等,preHandle返回false不执行postHandle。
afterCompletion
是在渲染视图结束后执行,主要可以用来进行事后的资源清理。无论 是否发生异常/preHandle返回false 都会执行
其中postHandle和afterCompletion方法是反顺序执行的。也就是说第一个拦截器会最后一个执行。关于HandlerInterceptor的执行顺序我们可以在HandlerExecutionChain类中找到。
完整示例 :
配置自己的Interceptor进容器,需要按照下示例方式
实现WebMvcConfigurer接口,添加@Configuration注解(可免除),在配置类中,重写addIntercepters方法,添加要拦截的url以及url白名单(需要排除拦截的url)
@Component
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private CustomInterceptor customInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(customInterceptor) // 添加拦截器
.addPathPatterns("/**") // 配置拦截请求url( ** 表示拦截所有请求url)
.excludePathPatterns("/hello"); // 排除某些不需要拦截的请求url(即带有/hello请求不会被拦截)
}
}
WebMvcConfigurer
重要的方法 :
addInterceptors
:从该方法名就可以了解到该方法是添加拦截器,即将拦截器交给IOC去执行,拦截器需要拦截的路径以及需要排除拦截的路径在该方法中配置。addResourceHandlers
:该方法的作用是配置静态资源路径。即某些请求需要读取某个路径下的静态资源内容,需要配置该静态资源的路径,通过该方法可以统一给这些请求配置指定静态资源路径 。addResourceHandlers 示例:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**") // 配置需要添加静态资源的请求url
.addResourceLocations("classpath:/mydata/"); //配置静态资源路径
}
将自己的 HandlerInterceptor 添加进Spring容器 :
@Component
public class CustomInterceptor implements HandlerInterceptor {
//在Controller执行之前调用,如果返回false,controller不执行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("---------CustomInterceptor.preHandle--------");
return true;
}
//controller执行之后,且页面渲染之前调用
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("---------CustomInterceptor.postHandle--------");
}
//页面渲染之后调用,一般用于资源清理操作
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("---------CustomInterceptor.afterCompletion--------");
}
}
到此就完成定义自己的一个HandlerInterceptor。
HandlerInterceptor在实际开发中运用的场景
HandlerAdapter实现类及RequestMappingHandlerAdapter调用过程
RequestMapping的注册及请求匹配过程
Controller的扫描注册及匹配过程
DispatcherServlet请求执行的过程
MVC重要组件及DispatcherServlet执行过程
Handler、HandlerMapping和HandlerAdapter作用及区别