springMVC(10) View实现之InternalResourceView

类图

InternalResourceView类图

属性

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

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

String url;

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

渲染流程

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

// AbstractView
public void render(Map<String, ?> 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<String, Object> mergedModel = createMergedOutputModel(model, request, response);
   prepareResponse(request, response);    // 用来解决IE的https下载的bug
   renderMergedOutputModel(mergedModel, request, response);
}
// InternalResourceView
protected void renderMergedOutputModel(
      Map<String, Object> 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进行请求处理
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,384评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,322评论 25 709
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,204评论 4 61
  • -1- 我有一个朋友,是做销售的。在某次会议上认识了一个创业老板,得知朋友有换工作的打算,就约着聊聊。 用几分钟的...
    流年芳华阅读 4,562评论 2 9
  • 全新的第一期基础ashtanga的培训,6月,在静修中心天然的氧吧环境里,从呼吸开始了…… 因为ashtanga的...
    静享运动学习生活时光阅读 1,397评论 0 1