发表于: 2020-07-04 21:13:52
2 1698
今天完成的事情:今天完成任务5拦截器以及提交任务。
明天计划的事情:明天看任务6以及深度思考
遇到的问题:暂无问题
收获:
拦截器(Interceptor)
1. 拦截器用于对URL请求进行前置/后置过滤,Interceptor与Filter相似,但实现方式不一样,拦截器是SpringMVC的组件,底层是基于Sring AOP面向切面编程实现,运行在springIOC容器。过滤器J2EE的标准组件,由第三方容器不同厂商实现的。
2. 使用步骤:
1)配置maven的Servlet-api的依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
scope属性设置在该依赖在哪个环境生效
2)实现HandlerInterceptor接口
实现接口有三个方法:
preHandle - 前置执行处理,该方法执行中返回的是布尔值,如果为true,请求就会送到后面的控制器或者拦截器,如果为false,当前请求会阻止,直接返回到客户端。
postHandle - 目标资源已被Spring MVC框架处理,就是在Controller方法执行完返回后执行的方法
afterCompletion - 响应文本已经产生之后执行的方法
public class MyInterceptor implements HandlerInterceptor {
private Logger logger = LoggerFactory.getLogger(MyInterceptor.class);
@Resource
private UserService userService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//对请求中带/u,并且token为空的直接返回到登录页面,返回false
//对请求中带/u,但是token中有用户信息的,直接跳过登录页面,返回true
//对其他不带有/u的直接放行,返回true
String url = request.getRequestURI();logger.info("当前请求的路径为:{}",url);
//contains(),该方法是判断字符串中是否有子字符串。如果有则返回true,如果没有则返回false。
if(url.contains("jnshuTest4/u/")){
Cookie cookie = CookieUtil.getCookie(request.getCookies(),"token");
if(cookie != null){
String value = URLDecoder.decode(cookie.getValue(),"utf-8");
String token = DESUtil.desDecrypt(value,"12345678");
logger.info("token解密的值为{}",token);
int id = Integer.parseInt(token.split(",")[0]);
User user = new User();
user.setId(id);
User user1 = userService.findOne(user);
request.setAttribute("user",user);
logger.info("将用户{}放入session中",user);
return true;
}
else {
response.sendRedirect(request.getContextPath()+"/user/loginpage");
return false;
}
}
return true;
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
3)applicattionContext配置过滤器地址
<mvc:interceptors>
<mvc:interceptor>
<!--/**是对所有请求路径以及子路经进行拦截-->
<mvc:mapping path="/**"/>
<!--这儿需要注意,拦截器拦截全部请求的话会把包括静态资源请求也拦截到,
如果对某些静态资源不拦截可以配置exclude-mapping-->
<mvc:exclude-mapping path="/css/**"/>
<mvc:exclude-mapping path="/img/**"/>
<mvc:exclude-mapping path="/pic/**"/>
<bean class="com.hyx.interceptor.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
3. 需要注意的点,当有多个拦截器的时候,执行的顺序。
preHandle方法按照在applicationContext中配置的顺序,先进先出执行。但是在执行postHandle和afterCompletion的方法返回的顺序是相反的,先进后出。
Spring MVC执行流程
1. 首先有DispatcherServlet中央处理器对web浏览器发送过来的请求进行拦截
2. 拦截到了请求之后DispatcherServlet会查找Handler(可能是拦截器、控制器),查找Handler 的任务DispatcherServlet会交给HandlerMapper处理器映射器来完成
3. HandlerMapper处理器映射器会通过当前访问的URL得到我们的执行链,然后将执行链 返回给DispatcherServlet中央处理器,HandlerMapper只会获取执行链,不会对其进行处理。 ps:执行链就是请求被一个或者多个拦截器拦截然后被Cotroller处理然后响应回浏览器 并且响应途中被拦截器拦截执行方法,最终响应到达浏览器这样一个链式的过程叫做执行链
4. DispatcherServlet得到执行链之后会向HandlerAdapter处理器适配器发起Handler执行请求
5. HandlerAdapter处理器适配器会根据不同的Handler类型来决定执行不同的方法,例如目标的Handler它的实际类型是一个Interceptor拦截器,它就会去执行前置的处理方法。如果Handler它的实际类型是一个Controller控制器,它就会进入控制器中的对应方法 来调用与URL对应的那个方法
6. 假设Handler它是一个Controller控制器的某个方法,最常见的形式就是返回一个 ModelAndView模型与视图对象被 HandlerAdapter处理器适配器对象接收。
7. HandlerAdapter处理器适配器对象会将ModleAndView对象返回给DispatcherServlet
8. DispatcherServlet接收到ModelAndView对象的时候就会去判断这个当前返回的这个 ModelAndView到底是由哪个模板引擎进行处理的,假设返回的View中的配置是freemaker 作为模板引擎,那么DispatcherServlet会去选择与之对应的ViewResolver视图解析器来进行视图对象的创建 。
9.视图解析器ViewResoiver创建完视图对象View之后,会随着处理返回给DispatcherServlet
10.DispatcherServlet拿到视图对象View之后就会将Model中存放的数据结合模板进行渲染 11.渲染之后就可以得到最终的html,html会随着响应返回给客户端的浏览器,浏览器会进行解释得到最终的结果。
评论