java前端控制器如何处理请求_SpringMVC到底是如何处理请求的?

@Override

protected final void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

processRequest(request, response);

}

protected final void processRequest(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

// 系统计时开始时间

long startTime = System.currentTimeMillis();

Throwable failureCause = null;

// 国际化

LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();

LocaleContext localeContext = buildLocaleContext(request);

//构建ServletRequestAttributes对象

RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();

ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);

//异步管理

WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());

//初始化ContextHolders

initContextHolders(request, localeContext, requestAttributes);

try {

doService(request, response);

}

catch (ServletException | IOException ex) {

failureCause = ex;

throw ex;

}

catch (Throwable ex) {

failureCause = ex;

throw new NestedServletException("Request processing failed", ex);

}

finally {

//恢复原来的LocaleContext和ServiceRequestAttributes到LocaleContextHolder和RequestContextHolder,避免影响Servlet以外的处理,如Filter

resetContextHolders(request, previousLocaleContext, previousAttributes);

if (requestAttributes != null) {

requestAttributes.requestCompleted();

}

logResult(request, response, failureCause, asyncManager);

//发布ServletRequestHandlerEvent消息,这个请求是否执行成功都会发布消息的

publishRequestHandledEvent(request, response, startTime, failureCause);

}

}

// initContextHolders(request, localeContext, requestAttributes);

private void initContextHolders(HttpServletRequest request,

@Nullable LocaleContext localeContext, @Nullable RequestAttributes requestAttributes) {

if (localeContext != null) {

LocaleContextHolder.setLocaleContext(localeContext, this.threadContextInheritable);

}

if (requestAttributes != null) {

RequestContextHolder.setRequestAttributes(requestAttributes, this.threadContextInheritable);

}

}

该方法大概做了这几件事:国际化的设置,创建 ServletRequestAttributes 对象,初始化上下文 holders (即将 Request 对象放入到线程上下文中,如后续想要在方法中获取 request、response对象此时可以通过调用 LocaleContextHolder 对应方法即可),然后调用 doService 方法。对于 doService 方法,FrameworkServlet 类并未提供实现,该方法由 DispatcherServlet 子类实现:

DispatcherServlet#doService

DispatcherServlet 里面执行处理的入口方法是 doService,由于这个类继承于 FrameworkServlet 类,重写了 doService() 方法:

@Override

protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {

logRequest(request);

// Keep a snapshot of the request attributes in case of an include,

// to be able to restore the original attributes after the include.

Map attributesSnapshot = null;

if (WebUtils.isIncludeRequest(request)) {

attributesSnapshot = new HashMap<>();

Enumeration> attrNames = request.getAttributeNames();

while (attrNames.hasMoreElements()) {

String attrName = (String) attrNames.nextElement();

if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {

attributesSnapshot.put(attrName, request.getAttribute(attrName));

}

}

}

//Spring上下文

request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());

//国际化解析器

request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);

//主题解析器

request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);

//主题

request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());

//重定向的数据

if (this.flashMapManager != null) {

FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);

if (inputFlashMap != null) {

request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));

}

request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());

request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);

}

try {

//request设置完相关的属性做真正的请求处理

doDispatch(request, response);

}

finally {

if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {

// Restore the original attribute snapshot, in case of an include.

if (attributesSnapshot != null) {

restoreAttributesAfterInclude(request, attributesSnapshot);

}

}

}

}

整个方法看下来处理的操作有:处理 include 标签的请求,将上下文放到 request 的属性中,将国际化解析器放到 request 的属性中,将主题解析器放到 request 属性中,将主题放到 request 的属性中,处理重定向的请求数据最后调用 doDispatch 这个核心的方法对请求进行处理:

DispatcherServlet#doDispatch

该方法是在 doService 方法中调用的,从底层设计了整个请求的处理流程:根据 request 找到 Handler

根据 Handler 找到对应的 HandlerAdapter

用 HandlerAdapter 处理 Handler

调用 processDispatchResult 方法处理上面之后的结果(包含View渲染并输出给用户)

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;

Exception dispatchException = null;

try {

// 校验是否为上传请求 是上传请求执行解析 否则返回request

processedRequest = checkMultipart(request);

multipartRequestParsed = (processedRequest != request);

// 根据访问的Handler 返回指定对应的HandlerExecutionChain对象 这里从HandlerMapping 集合中查找 HandlerExecutionChain 对象包含Handler与拦截器HandlerInterceptor列表

mappedHandler = getHandler(processedRequest);

if (mappedHandler == null) {

noHandlerFound(processedRequest, response);

return;

}

// 根据得到的Handler 获取对应的HandlerAdaptor对象

HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

// 处理GET、HEAD请求的Last-Modified

String method = request.getMethod();

boolean isGet = "GET".equals(method);

if (isGet || "HEAD".equals(method)) {

long lastModified = ha.getLastModified(request, mappedHandler.getHandler());

//当数据没有更改时,就直接返回上次的数据,提高效率

if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {

return;

}

}

//执行Interceptor的preHandle

if (!mappedHandler.applyPreHandle(processedRequest, response)) {

return;

}

// 执行Handler 返回ModelAndView

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

//如果需要异步处理,直接返回

if (asyncManager.isConcurrentHandlingStarted()) {

return;

}

//当view为空时,根据request设置默认view,如Handler返回值为void

applyDefaultViewName(processedRequest, mv);

//执行相应Interceptor的postHandle

mappedHandler.applyPostHandle(processedRequest, response, mv);

}

catch (Exception ex) {

dispatchException = ex;

}

catch (Throwable err) {

// As of 4.3, we're processing Errors thrown from handler methods as well,

// making them available for @ExceptionHandler methods and other scenarios.

dispatchException = new NestedServletException("Handler dispatch failed", err);

}

//处理返回结果,包括处理异常、渲染页面,发出完成通知触发Interceptor的afterCompletion

processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

}

catch (Exception ex) {

triggerAfterCompletion(processedRequest, response, mappedHandler, ex);

}

catch (Throwable err) {

triggerAfterCompletion(processedRequest, response, mappedHandler,

new NestedServletException("Handler processing failed", err));

}

finally {

if (asyncManager.isConcurrentHandlingStarted()) {

// Instead of postHandle and afterCompletion

if (mappedHandler != null) {

mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);

}

}

else {

// Clean up any resources used by a multipart request.

if (multipartRequestParsed) {

cleanupMultipart(processedRequest);

}

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值