第十二章 ***
关于java-eclipse的一些设置
- 复制项目 需要改的一些参数 请求路径需要改
- 打开这个地方 Filter
- 继续修改 setting里面的文件信息
下载源码
https://blog.csdn.net/dongli_1996/article/details/97142199
***
Springmvc提供了*机制;允许运行目标方法之前进行一些拦截工作,过着目标方法运行之后进行一些其他处理;
Filter:web
*:springmvc
自定义***概述
- Spring MVC也可以使用对请求进行拦截处理,用户可以自定义来实现特定的功能,自定义的***必须实现HandlerInterceptor接口
- preHandle():这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求 request 进行处理。如果程序员决定该对请求进行拦截处理后还要调用其他的,或者是业务处理器去进行处理,则返回true;如果程序员决定不需要再调用其他的组件去处理请求,则返回false。【目标方法运行之前调用,返回boolean true放行 chain.doFilter放行 false不放行】
- postHandle():这个方法在业务处理器处理完请求后,但是DispatcherServlet 向客户端返回响应前被调用,在该方法中对用户请求request进行处理。【目标方法运行之后调用:目标方法调用之后】
- afterCompletion():这个方法在 DispatcherServlet 完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。
【在请求整个完成之后;来到目标页面之后 chain.doFilter放行;资源响应之后】
***方法执行顺序
springmvc的配置文件
默认拦截所有的请求 <mvc:interceptors> <bean class="com.project.service.myInterceptor"></bean> </mvc:interceptors> 配置某个***更详细的信息【注意配置顺序】只拦截/hello <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/hello"/> <bean class="com.project.service.myInterceptor"/> </mvc:interceptor> </mvc:interceptors>
页面代码
<% pageContext.setAttribute("ctp", request.getContextPath()); System.out.println("Hello页面"); %>
控制层的代码
@RequestMapping("/hello") public String getIndex() { System.out.println("目标方法"); return "hello"; }
***代码
public class myInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("myInterceptor+preHandle"); return true; } @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"); } }
多个拦截方法的执行顺序
代码跟上面一样 只是多了一个my2Interceptor ***
配置文件
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/hello"/> <bean class="com.project.service.myInterceptor"/> </mvc:interceptor> <bean class="com.project.service.my2Interceptor"></bean> </mvc:interceptors>
- 正常顺序
出错顺序 在目标方法中定义10/0;
将其中一个***preHandle方法return false; 不放行
应该给拦截第二个* 拦截第一个 第二个也被拦截了
不放行:那一块不放行从此以后都没有,my2Interceptor不放行;但他前面已经放行了的***afterCompletion总会执行,目标方法也没有执行
***总结
源码,正常流程
- 首先进入doDispatch
- 调用方法 获得所有的处理器...适配器 + 获取所有的***【根据当前的请求地址找到那个类能来处理;拿到执行链】
得到执行链
适配器执行目标方法
- 运行 所有的preHandler【有一个返回false目标方法以后都不会执行 直接return 直接跳到afterCompletion】
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception { HandlerInterceptor[] interceptors = getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { for (int i = 0; i < interceptors.length; i++) { HandlerInterceptor interceptor = interceptors[i]; if (!interceptor.preHandle(request, response, this.handler)) { //执行完AfterCompletion() triggerAfterCompletion(request, response, null); //返回一个false return false; } //记录了一下索引 看看哪些索引被运行了 this.interceptorIndex = i; } } return true; }
- PostHandle的处理方法
目标方法只要正常就会走到postHandle
- 只要能运行 到这里的postHandle 就能页面渲染:如果完蛋也是直接跳到afterCompletion
而postHandle 里面 循环【逆序的情况在这里体现】【每个***的postHandle】
- 页面渲染
// Did the handler return a view to render? if (mv != null && !mv.wasCleared()) { //页面渲染 render(mv, request, response); if (errorView) { WebUtils.clearErrorRequestAttributes(request); } }
- AfterCompletion的执行
//页面渲染正常执行AfterCompletion,即使没走到这,AfterCompletion总会执行 if (mappedHandler != null) { mappedHandler.triggerAfterCompletion(request, response, null); }
- 如果运行失败也会执行AfterCompletion
- 有记录最后一个放行的索引,从他开始把之前放行的的AfterCompletion都执行 【逆序】
源码 运行第二个***return false
错误的***的错误的影响
承接上面的 i 然后进行循环
整个方法 return 整个doDispatch return 也就没接着运行了
什么时候用filter 什么时候用***
如果某些功能:需要其他组件配合完成,我们就使用*** 配合springmvc
其他情况可以写filter