springMVC(10) View实现之InternalResourceView

类图

springMVC(10) View实现之InternalResourceView_第1张图片
InternalResourceView类图

属性

结合InternalResourceView及其父类,我们可以发现它有如下一些属性:

String beanName;
String contentType = "text/html;charset=ISO-8859-1";
String requestContextAttribute;
Map staticAttributes = new LinkedHashMap(); // 静态属性,会与model进行合并
exposePathVariables = true; // 决定请求路径中的变量是否与合并到model中

String url;

boolean alwaysInclude = false; // 如果为true,则总是调用RequestDispatcher的include方式
boolean exposeContextBeansAsAttributes = false; // 决定是否将context中的beans作为属性暴露
Set exposedContextBeanNames; // 决定需要暴露的beans的名称
boolean preventDispatchLoop = false; // 决定是否允许循环循环

渲染流程

整合InternalResourceView及其父类的渲染部分,

// AbstractView
public void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception {
   if (logger.isTraceEnabled()) {
      logger.trace("Rendering view with name '" + this.beanName + "' with model " + model +
         " and static attributes " + this.staticAttributes);
   }

   Map mergedModel = createMergedOutputModel(model, request, response);
   prepareResponse(request, response);    // 用来解决IE的https下载的bug
   renderMergedOutputModel(mergedModel, request, response);
}
// InternalResourceView
protected void renderMergedOutputModel(
      Map model, HttpServletRequest request, HttpServletResponse response) throws Exception {

   // Determine which request handle to expose to the RequestDispatcher.
   HttpServletRequest requestToExpose = getRequestToExpose(request);

   // Expose the model object as request attributes.
   exposeModelAsRequestAttributes(model, requestToExpose);

   // Expose helpers as request attributes, if any.
   exposeHelpers(requestToExpose);

   // Determine the path for the request dispatcher.
   String dispatcherPath = prepareForRendering(requestToExpose, response);

   // Obtain a RequestDispatcher for the target resource (typically a JSP).
   RequestDispatcher rd = getRequestDispatcher(requestToExpose, dispatcherPath);
   if (rd == null) {
      throw new ServletException("Could not get RequestDispatcher for [" + getUrl() +
            "]: Check that the corresponding file exists within your web application archive!");
   }

   // If already included or response already committed, perform include, else forward.
   if (useInclude(requestToExpose, response)) {
      response.setContentType(getContentType());
      if (logger.isDebugEnabled()) {
         logger.debug("Including resource [" + getUrl() + "] in InternalResourceView '" + getBeanName() + "'");
      }
      rd.include(requestToExpose, response);
   }

   else {
      // Note: The forwarded resource is supposed to determine the content type itself.
      if (logger.isDebugEnabled()) {
         logger.debug("Forwarding to resource [" + getUrl() + "] in InternalResourceView '" + getBeanName() + "'");
      }
      rd.forward(requestToExpose, response);
   }
}

我们可以分析整个处理流程如下,

  1. 进行model合并(将静态属性、地址变量和原model合并,与staticAttributes和exposePathVariables属性有关)
  2. 将请求处理器暴露给RequestDispatcher(与exposeContextBeansAsAttributes和exposedContextBeanNames属性有关)
  3. 将合并后的model作为属性暴露给请求
  4. 将helper作为请求属性暴露
  5. 设置路径(这里主要是做了一个url循环判断,与preventDispatchLoop属性的设置有关)
  6. 获取请求、路径对应的RequestDispatcher
  7. 通过include或forward进行请求处理

你可能感兴趣的:(springMVC(10) View实现之InternalResourceView)