tomcat拦截请求_SpringMVC:接收到请求后的调用细节,你是否清楚?

分享自己在Java方面的所思所想,希望你看完之后能有更多更深入的了解

本人微信公众号(jwfy的学习分享),欢迎关注~

接收到一个新的请求之后,spring就会去根据请求的URL信息选择具体的代码块去执行操作,如图就是接收到一个新的请求调用图,从Tomcat开始直到把请求分发到spring中,最后到了doDispatch方法。

0035fdd42ac6a169942735b2d8e7989b.png

本篇学习笔记主要就是讲一个新的请求被分发到spring中spring如何处理,至于如何扫描包中的controller,得到URL配置信息可以看 你是否清楚Spring MVC中的URL映射管理器的工作原理 ,而本篇主要介绍了

  • 获取执行链
  • 404页面设置
  • 获取适配器
  • LastModified
  • 内容方法调用(invoke)
  • 视图渲染

让我们更加清楚的知道spring中一般的方法是如何确定调用的具体方法的,适配不同的模板引擎,达到渲染的地步,再者有时候又是API一般只需要返回json结构的数据,其背后的原理是如何实现的,以及我们在使用过程中如何避免出现的各种问题。

doDispatch 方法

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; boolean multipartRequestParsed = false; WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); try { ModelAndView mv = null; // 初始化设置模板为null Exception dispatchException = null; // 初始化异常为null try { processedRequest = checkMultipart(request); multipartRequestParsed = (processedRequest != request); // 文件上传的相关设置和操作 mappedHandler = getHandler(processedRequest); // 根据request获取对应的请求执行链 if (mappedHandler == null || mappedHandler.getHandler() == null) { // 如果没有对应的handler对于,则应该是定义为404,通过noHandlerFound确认 noHandlerFound(processedRequest, response); return; } // 通过handler获得合适的handler适配器 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); String method = request.getMethod(); boolean isGet = "GET".equals(method); if (isGet || "HEAD".equals(method)) { // 是get方法或者head方法 long lastModified = ha.getLastModified(request, mappedHandler.getHandler()); // 如果handler 是LastModified类,则获取其lastModified值,否则返回-1 // lastModify 是spring添加了缓存机制,当重复请求同样的内容,返回403,而不会返回真正的内容,具体可看下面的LastModified机制这一小节 if (logger.isDebugEnabled()) { logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified); } if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) { return; } } // 前置的handler预处理,就是获取执行链的拦截器,对请求进行拦截处理 if (!mappedHandler.applyPreHandle(processedRequest, response)) { // 如果拦截器拦截成功,返回false,直接结束了 // 当然在这其中拦截器肯定需要特定返回自身的内容到response中,便于展示在页面上 // 不过从页面角度出发并没有非常实质性的拦截器处理,这点存疑? return; } // 真正的调用各自的执行方法,返回ModelAndView后续在invoke这一小节细说 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if (asyncManager.isConcurrentHandlingStarted()) { return; } applyDefaultViewName(processedRequest, mv); // 如果mv没有包含有效的视图,则从dispatch的viewNameTranslator属性上获取对应的默认视图 mappedHandler.applyPostHandle(processedRequest, response, mv); // 拦截器的后置处理 } catch (Exception ex) { dispatchException = ex; } catch (Throwable err) { dispatchException = new NestedServletException("Handler dispatch failed
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值