ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

SpringMVC源码解析 一

2019-12-26 14:55:09  阅读:289  来源: 互联网

标签:resp SpringMVC mappedHandler req request 源码 解析 response processedRequest


  当服务器接收到从浏览器发送的一个请求后, 首先进入HttpServlet#service()方法中

  HttpServlet#service()方法实现:

  @Override

  public void service(ServletRequest req, ServletResponse res)

  throws ServletException, IOException {

  HttpServletRequest request;

  HttpServletResponse response;

  try {

  request = (HttpServletRequest) req;

  response = (HttpServletResponse) res;

  } catch (ClassCastException e) {

  throw new ServletException(lStrings.getString("http.non_http"));

  }

  service(request, response);

  }

  protected void service(HttpServletRequest req, HttpServletResponse resp)

  throws ServletException, IOException {

  String method = req.getMethod();

  if (method.equals(METHOD_GET)) {

  long lastModified = getLastModified(req);

  if (lastModified == -1) {

  // servlet doesn't support if-modified-since, no reason

  // to go through further expensive logic

  doGet(req, resp);

  } else {

  long ifModifiedSince;

  try {

  ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);

  } catch (IllegalArgumentException iae) {

  // Invalid date header - proceed as if none was set

  ifModifiedSince = -1;

  }

  if (ifModifiedSince < (lastModified / 1000 * 1000)) {

  // If the servlet mod time is later, call doGet()

  // Round down to the nearest second for a proper compare

  // A ifModifiedSince of -1 will always be less

  maybeSetLastModified(resp, lastModified);

  doGet(req, resp);

  } else {

  resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);

  }

  }

  } else if (method.equals(METHOD_HEAD)) {

  long lastModified = getLastModified(req);

  maybeSetLastModified(resp, lastModified);

  doHead(req, resp);

  } else if (method.equals(METHOD_POST)) {

  doPost(req, resp);

  } else if (method.equals(METHOD_PUT)) {

  doPut(req, resp);

  } else if (method.equals(METHOD_DELETE)) {

  doDelete(req, resp);

  } else if (method.equals(METHOD_OPTIONS)) {

  doOptions(req,resp);

  } else if (method.equals(METHOD_TRACE)) {

  doTrace(req,resp);

  } else {

  String errMsg = lStrings.getString("http.method_not_implemented");

  Object[] errArgs = new Object[1];

  errArgs[0] = method;

  errMsg = MessageFormat.format(errMsg, errArgs);

  resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);

  }

  }

  在HttpServlet#service(request, response)中调用根据请求类型调用不同的实现方法, doGet, doPost等; 这里发送的是get请求, 因此看doGet()的实现;

  FrameworkServlet#doGet()方法的实现:

  @Override

  protected final void doGet(HttpServletRequest request, HttpServletResponse response)

  throws ServletException, IOException {

  proce***equest(request, response);

  }

  FrameworkServlet#proce***equest()方法实现:

  protected final void proce***equest(HttpServletRequest request, HttpServletResponse response)

  throws ServletException, IOException {

  long startTime = System.currentTimeMillis();

  Throwable failureCause = null;

  LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();

  LocaleContext localeContext = buildLocaleContext(request);

  RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();

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

  WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

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

  initContextHolders(request, localeContext, requestAttributes);

  try {

  /**

  * 请求逻辑处理

  * {@link DispatcherServlet#doService(HttpServletRequest,HttpServletResponse)}

  */

  doService(request, response);

  }

  . . . . . .

  }

  DispatcherServlet#doService()方法实现

  @Override

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

  if (logger.isDebugEnabled()) {

  String resumed = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult() ? " resumed" : "";

  logger.debug("DispatcherServlet with name '" + getServletName() + "'" + resumed +

  " processing " + request.getMethod() + " request for [" + getRequestUri(request) + "]");

  }

  // 设置快照

  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));

  }

  }

  }

  // 使框架对象可用于处理程序并查看对象

  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 {

  /**

  * 核心逻辑处理

  */

  doDispatch(request, response);

  }

  finally {

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

  //使用快照恢复Request属性

  if (attributesSnapshot != null) {

  restoreAttributesAfterInclude(request, attributesSnapshot);

  }

  }

  }

  }

  DispatcherServlet#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 {郑州人流医院 http://www.zykdfk.com/

  ModelAndView mv = null; //封装view和数据信息

  Exception dispatchException = null; //封装异常信息

  try {

  processedRequest = checkMultipart(request);

  multipartRequestParsed = (processedRequest != request);

  /**

  * 1. 获取处理器

  * mappedHandler: HandlerExecutionChain

  */

  mappedHandler = getHandler(processedRequest);

  if (mappedHandler == null) {

  noHandlerFound(processedRequest, response);

  return;

  }

  /**

  * 2. 获取适配器

  */

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

  // 如果处理程序支持,则处理最后修改的标头

  String method = request.getMethod();

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

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

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

  if (logger.isDebugEnabled()) {

  logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);

  }

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

  return;

  }

  }

  /**

  * 执行HandlerExecutionChain中的拦截器

  */

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

  return;

  }

  /**

  * 3. 通过适配器执行处理器, 也就是我们编写的Controller类; 注意: 这里调用的是适配器的handle()方法

  * {@link AbstractHandlerMethodAdapter#handle(HttpServletRequest, HttpServletResponse, Object)}

  *

  * mv: ModelAndView实例{@link AbstractHandlerMethodAdapter#handle(HttpServletRequest,HttpServletResponse, Object)}

  */

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

  if (asyncManager.isConcurrentHandlingStarted()) {

  return;

  }

  applyDefaultViewName(processedRequest, mv);

  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);

  }

  /**

  * 4. 视图解析

  */

  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);

  }

  }

  }

  }

  分析(注: 以下模块解析比较复杂, 拆分为不同播客分析):

  根据请求信息获取对应处理器

  根据映射处理器获取对应的适配器

  通过适配器执行处理器, 也就是编写的Controller类中的相应方法

  视图解析

  请求解析过程图


标签:resp,SpringMVC,mappedHandler,req,request,源码,解析,response,processedRequest
来源: https://blog.51cto.com/14335413/2462048

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有