一、拦截器
在使用了SpringMVC后,只有一个Servlet,也就是DisptcherServlet。那么,如果我们仍然使用过滤器来完成请求的拦截,由于过滤器是在Servlet之前执行的,就会造成,过滤器会拦截访问DispatcherServlet的所有请求。那么,如果我们有部分请求不想被拦截,怎么办呢?SpringMVC给出了拦截器来实现单元方法的拦截,拦截器的执行是在DispatcherServlet之后和单元方法之前的,这样我们就可以在单元方法被之前之前对请求进行自定义的拦截处理了。
注意:只有URL匹配到了控制单元,拦截器才能生效。
1.拦截器的使用
1.创建拦截器类
在src下创建包,包名随意,并创建java类实现HandlerInterceptor接口。并实现preHandle、postHandle、afterCompletion三个方法。
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor.preHandle");
return fasle;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor.postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("MyInterceptor.afterCompletion");
}
}
2.配置拦截器
拦截器是由DispatcherServlet接收到请求后来调用的,所有需要将拦截器配置为bean,并且配置其拦截范围。
<!--配置注解扫描路径-->
<context:component-scan base-package="com.bjsxt.controller"></context:component-scan>
<!--配置拦截器-->
<mvc:interceptors>
<!--配置具体的拦截器的bean及其拦截范围-->
<mvc:interceptor>
<mvc:mapping path="/myController/demo"/><!--配置拦截的单元方法的访问路径,第一个/表示项目根目录-->
<bean class="com.bjsxt.interceptor.MyInterceptor"></bean><!--配置拦截器的bean对象,只在当前mvc:interceptor内有效-->
</mvc:interceptor>
</mvc:interceptors>
2.拦截方法的介绍
1.preHandle方法
作用:
执行拦截的方法preHandle(),返回false表示拦截此次请求,返回true表示放行。(在控制单元执行之前执行)
参数:
HttpServletRequest request:此次拦截的请求的request对象。
HttpServletResponse response:此次拦截的请求的response对象。
Object handler:HandlerMethod类型,存储了拦截的单元方法的method对象。
2.postHandle方法
作用:
执行拦截的方法postHandle(),可以对ModelAndView进行操作,Model数据进行校验,View操作等。(在控制单元执行之后,视图渲染之前执行)
参数:
HttpServletRequest request:此次拦截的请求的request对象。
HttpServletResponse response:此次拦截的请求的response对象。
Object handler:HandlerMethod类型,存储了拦截的单元方法的method对象。
ModelAndView:存储了model和view信息的对象。
3.afterCompletion方法
作用:
执行拦截的方法afterCompletion(),无论是否出现异常都会执行,可以处理异常,清理资源等。(在视图渲染之后执行)
参数:
HttpServletRequest request:此次拦截的请求的request对象。
HttpServletResponse response:此次拦截的请求的response对象。
Object handler:HandlerMethod类型,存储了拦截的单元方法的method对象。
Exception:存储异常信息的对象,如果没有异常信息则默认为null。
<!--配置拦截器-->
<mvc:interceptors>
<!--配置拦截器的bean对象,拦截所有的单元方法-->
<bean class="com.bjsxt.interceptor.MyInterceptor2"></bean>
<!--配置具体的拦截器的bean极其拦截范围,可以配置多个-->
<mvc:interceptor>
<mvc:mapping path="/myController/demo"/><!--配置拦截的单元方法的访问路径,第一个/表示项目根目录,可以多个-->
<mvc:mapping path="/myController/kk/*"/><!--支持*通配符表示任意个数的任意字符,**表示路径及子路径-->
<bean class="com.bjsxt.interceptor.MyInterceptor"></bean><!--配置拦截器的bean对象,只在当前mvc:interceptor内有效-->
</mvc:interceptor>
</mvc:interceptors>
拦截器栈
拦截器栈指多个拦截器。当一个控制单元被多个拦截器拦截时,就形成了拦截器栈。拦截器栈中拦截器有着严格的执行顺序。执行顺序按照配置顺序执行。先配置的优先级更高。
例如:拦截器A和拦截器B,优先级更高指以控制单元(demo)为核心,前面的方法优先级高的先执行,后面的方法优先级高的后执行。
配置拦截器栈分为局部配置和全局配置。
全局配置:
<mvc:interceptors>
<bean class="com.bjsxt.inteceptor.MyInteceptor"></bean>
<bean class="com.bjsxt.inteceptor.MyInteceptor2"></bean>
</mvc:interceptors>
局部配置:
因为在<mvc:interceptor>
中只能有一个<bean>
,所有如果希望使用局部方式配置拦截器栈,需要配置多个<mvc:interceptor>
标签。
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/show2"/>
<bean class="com.bjsxt.inteceptor.MyInteceptor2"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/show2"/>
<bean class="com.bjsxt.inteceptor.MyInteceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
二、SpringMVC运行原理(常见面试题)
1.客户端向服务器发送请求,SpringMVC总体入口中央调度器DispatcherServlet进行请求分发。
2.中央调度器DispatcherServlet把URL交给映射器处理器HandlerMapping进行解析URL
3.映射处理器HandlerMapping将请求映射为HandlerExecutionChain处理器执行链
1.可以为多个处理器拦截器HandlerInterceptor
2.处理器Handler对象(处理Controller)
4.将处理器执行链HandlerExecutionChain返回到中央调度器DispatcherServlet。
5.DispatcherServlet根据返回的处理器执行链HandlerExecutionChain获得的处理器Handler,根据处理器Handler选择处理器适配器HandlerAdapter。
1.执行拦截器的preHandle()方法。
2.调用具体的Handler处理器(处理Controller),在填充Handler的入参过程中会执行数据转换、数据格式化、数据验证,调用具体的Controller完成处理功能,并创建ModelAndView对象。
3.执行拦截器的postHandle()方法。
6.将ModelAndView对象返回到处理器适配器HandlerAdapter。
7.处理器适配器HandlerAdapter将ModelAndView对象返回到中央调度器DispatcherServlet。
8.中央调度器DispatcherServlet调用视图解析器ViewResolver解析视图。
9.将解析的视图View对象返回到中央调度器DispatcherServlet。
10.渲染视图,将视图返回到中央调度器DispatcherServlet,执行拦截器afterCompletion()方法。
11.中央调度器DispatcherServlet相应会到浏览器。
三、SpringMVC中常用的注解
@Controller:定义控制器。
@RestController:等效于@Controller+@ResponseBody
@ControllerAdvice:基于Spring框架的异常通知实现
@RequestMapping:定义映射路径
@PutMapping:接收put请求,整体更新
@PatchMapping:属于对Put的补充,局部更新
@DeleteMapping:接收delete请求
@PostMapping:接收post请求
@GetMapping:接收get请求
@ResponseBody:把返回值转换为json并设置到响应体中
@CrossOrigin:允许跨域,在响应头添加Access-Control-Allow-Origin属性
@ExceptionHandler:异常处理
@RequestParam:处理请求参数
@RequestHeader: 处理请求头
@RequestBody:把请求体数据转换为对象
@PathVariable:获取restful请求参数
@SessionAttribute:获取Session作用域的值
name:作用域值的名称。如果没有设置name按照参数名称获取。
required:默认为true,表示作用域中必须有这个属性,如果没有,报异常。设置为false,如果没有,返回null