<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    推薦淘寶秋冬男裝熱賣(mài)網(wǎng)店

    追求無(wú)止境

    我的程序人生
    隨筆 - 31, 文章 - 2, 評(píng)論 - 20, 引用 - 0
    數(shù)據(jù)加載中……

    Spring MVC框架學(xué)習(xí)筆記 之 View技術(shù)

    以前,我們?cè)敿?xì)介紹了Spring的Controller技術(shù)。Spring的面向接口編程,使Controller的實(shí)現(xiàn)多種多樣。View技術(shù)也一樣。今天的分析先從在Controller中的ModelAndView開(kāi)始。

    public class ModelAndView {     
      private Object view; //View實(shí)例或者view的字符串    
    /** Model Map */  
      private ModelMap model; //model
     /* * Convenient constructor when there is no model data to expose.     * Can also be used in conjunction with <code>addObject</code>.    
     * @param view View object to render   
      * @see #addObject     */  
     public ModelAndView(View view) {        
        this.view = view;    
    }
    public ModelAndView(String viewName){ 
       this.view = viewName;
    }

     
    可以看到view實(shí)例可以指向一個(gè)View對(duì)象或者字符串。現(xiàn)在先看看View接口:
    public interface View { 
    
        /**
         * Return the content type of the view, if predetermined.
         * <p>Can be used to check the content type upfront,
         * before the actual rendering process.
         * @return the content type String (optionally including a character set),
         * or <code>null</code> if not predetermined.
         */
        String getContentType(); 
    
        /**
         * 繪制視圖
         * 繪制視圖的第一步是準(zhǔn)備請(qǐng)求: 如果是JSP的視圖技術(shù)
         * 首先會(huì)把model設(shè)為request的屬性。
         * 第二步則是真正的繪制視圖
         * @param model Map with name Strings as keys and corresponding model
         * objects as values (Map can also be <code>null</code> in case of empty model)
         * @param request current HTTP request
         * @param response HTTP response we are building
         * @throws Exception if rendering failed
         */
        void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception; 
    
    }
    在這之后,我們?cè)賮?lái)看看View的實(shí)現(xiàn)繼承類(lèi)圖,可以看到Spring支持多種類(lèi)型視圖:

    org.springframework.web.servlet.view.AbstractView (implements org.springframework.beans.factory.BeanNameAware, org.springframework.web.servlet.View)

    • org.springframework.web.servlet.view.document.AbstractExcelView
    • org.springframework.web.servlet.view.document.AbstractJExcelView
    • org.springframework.web.servlet.view.document.AbstractPdfView
    • org.springframework.web.servlet.view.AbstractUrlBasedView (implements org.springframework.beans.factory.InitializingBean)
      • org.springframework.web.servlet.view.jasperreports.AbstractJasperReportsView
        • org.springframework.web.servlet.view.jasperreports.AbstractJasperReportsSingleFormatView
          • org.springframework.web.servlet.view.jasperreports.ConfigurableJasperReportsView
          • org.springframework.web.servlet.view.jasperreports.JasperReportsCsvView
          • org.springframework.web.servlet.view.jasperreports.JasperReportsHtmlView
          • org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView
          • org.springframework.web.servlet.view.jasperreports.JasperReportsXlsView
        • org.springframework.web.servlet.view.jasperreports.JasperReportsMultiFormatView
      • org.springframework.web.servlet.view.document.AbstractPdfStamperView
      • org.springframework.web.servlet.view.AbstractTemplateView
        • org.springframework.web.servlet.view.freemarker.FreeMarkerView
        • org.springframework.web.servlet.view.velocity.VelocityView
          • org.springframework.web.servlet.view.velocity.VelocityToolboxView
            • org.springframework.web.servlet.view.velocity.VelocityLayoutView
      • org.springframework.web.servlet.view.InternalResourceView
        • org.springframework.web.servlet.view.JstlView
        • org.springframework.web.servlet.view.tiles.TilesView
          • org.springframework.web.servlet.view.tiles.TilesJstlView
      • org.springframework.web.servlet.view.RedirectView
      • org.springframework.web.servlet.view.tiles2.TilesView
      • org.springframework.web.servlet.view.xslt.XsltView
    • org.springframework.web.servlet.view.xslt.AbstractXsltView
     
    和Controller一樣,View的第一個(gè)實(shí)現(xiàn)也是AbstractView。所以先讓我們看看AbstractView對(duì)render函數(shù)的實(shí)現(xiàn):

     

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

    // Consolidate static and dynamic model attributes.
    Map mergedModel = new HashMap(this.staticAttributes.size() + (model != null ? model.size() : 0));
    mergedModel.putAll(this.staticAttributes);
    if (model != null) {
    mergedModel.putAll(model);
    }

    // Expose RequestContext?
    if (this.requestContextAttribute != null) {
    mergedModel.put(this.requestContextAttribute, createRequestContext(request, mergedModel));
    }

    prepareResponse(request, response);
    renderMergedOutputModel(mergedModel, request, response);
    }

    第一步,將靜態(tài)屬性和model的屬性都添加到mergedModel里面。如果需要請(qǐng)求上下文,則將請(qǐng)求上下文添加到model中。

    靜態(tài)屬性是繼承AbstractView進(jìn)行設(shè)置的屬性。而請(qǐng)求上下文如果設(shè)置的名字就會(huì)創(chuàng)建一個(gè)request上下文。在requestContext中定義了一些包括本地化和主題的處理工具。

    第二步,對(duì)響應(yīng)進(jìn)行預(yù)處理。最后調(diào)用子類(lèi)需要實(shí)現(xiàn)的函數(shù)renderMergedOutputModel。

    對(duì)PDF和EXCEL格式我們暫且不管,且Spring支持多種視圖技術(shù),這里我們主要關(guān)注JSTL技術(shù),

    接著我們來(lái)看AbstractUrlBasedView 類(lèi)。在AbstractUrlBasedView 只定義了一個(gè)url屬性。別的沒(méi)有什么特殊處理。

    接著繼承AbstractUrlBasedView 的是InternalResourceView。他對(duì)renderMergedOutputModel進(jìn)行實(shí)現(xiàn),實(shí)現(xiàn)如下:

    /**
    * Render the internal resource given the specified model.
    * This includes setting the model as request attributes.
    */
    protected void renderMergedOutputModel(
    Map model, HttpServletRequest request, HttpServletResponse response) throws Exception {

    // 獲取要暴露的request,一般都是傳入的參數(shù)request
    HttpServletRequest requestToExpose = getRequestToExpose(request);

    // 將model的數(shù)據(jù)添加到request屬性中
            exposeModelAsRequestAttributes(model, requestToExpose);

    // 設(shè)置helper,如果存在的話
    exposeHelpers(requestToExpose);

    // 對(duì)繪制進(jìn)行預(yù)處理,從而獲得到要分發(fā)的url
    String dispatcherPath = prepareForRendering(requestToExpose, response);

    // 獲取請(qǐng)求分發(fā)對(duì)象
    RequestDispatcher rd = requestToExpose.getRequestDispatcher(dispatcherPath);
    if (rd == null) {
    throw new ServletException(
    "Could not get RequestDispatcher for [" + getUrl() + "]: check that this file exists within your WAR");
    }

    // 決定使用RequestDispatcher的include方法還是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.
    exposeForwardRequestAttributes(requestToExpose);
    if (logger.isDebugEnabled()) {
    logger.debug("Forwarding to resource [" + getUrl() + "] in InternalResourceView '" + getBeanName() + "'");
    }
    rd.forward(requestToExpose, response);
    }
    }
    可以看到InternalResourceView對(duì)請(qǐng)求進(jìn)行了轉(zhuǎn)發(fā)。轉(zhuǎn)發(fā)到url上。最后我們看看JSTLView的實(shí)現(xiàn):

     
    public class JstlView extends InternalResourceView {
    
        private MessageSource messageSource;
    
        public JstlView() {
        }
    
        
        public JstlView(String url) {
            super(url);
        }
    
        public JstlView(String url, MessageSource messageSource) {
            this(url);
            this.messageSource = messageSource;
        }
    
        protected void initServletContext(ServletContext servletContext) {
            if (this.messageSource != null) {
                this.messageSource = JstlUtils.getJstlAwareMessageSource(servletContext, this.messageSource);
            }
            super.initServletContext(servletContext);
        }
    
        protected void exposeHelpers(HttpServletRequest request) throws Exception {
            if (this.messageSource != null) {
                JstlUtils.exposeLocalizationContext(request, this.messageSource);
            }
            else {
                JstlUtils.exposeLocalizationContext(new RequestContext(request, getServletContext()));
            }
        }
    
    }

     

    在InternalResourceView  中,基本上所有的處理都差不多了。在JSTLView對(duì)兩個(gè)方法進(jìn)行了覆蓋。第一個(gè)initServletContext,主要初始化了MessageResource

    第二個(gè)exposeHelpers將messageSource放在了request里面。

    這樣view的解析就結(jié)束了。接下來(lái)容器對(duì)jsp進(jìn)行解析,并進(jìn)行tag等的處理。然后將生成的頁(yè)面返回給客戶(hù)端。

    posted on 2009-11-26 13:25 追求無(wú)止境 閱讀(8207) 評(píng)論(2)  編輯  收藏

    評(píng)論

    # re: Spring MVC框架學(xué)習(xí)筆記 之 View技術(shù)  回復(fù)  更多評(píng)論   

    不錯(cuò)。。。。
    2009-11-27 09:39 | 字典

    # re: Spring MVC框架學(xué)習(xí)筆記 之 View技術(shù)  回復(fù)  更多評(píng)論   

    99098
    2016-05-19 17:23 | 888

    只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 国产亚洲蜜芽精品久久| 亚洲人成77777在线播放网站不卡 亚洲人成77777在线观看网 | 免费观看激色视频网站(性色)| 国产亚洲精品AA片在线观看不加载 | 亚洲熟妇无码一区二区三区导航| 久久久精品2019免费观看| 久久精品国产精品亚洲艾| 日本在线免费播放| 久久亚洲精品国产精品黑人| 久久精品视频免费看| 亚洲欧洲日韩不卡| 在线永久免费的视频草莓| 国产精品高清视亚洲精品| 国产高清在线免费视频| 一个人看的免费观看日本视频www 一个人看的免费视频www在线高清动漫 | 一个人看www免费高清字幕| 亚洲中文字幕久久精品无码APP| 99re6在线视频精品免费| 亚洲高清资源在线观看| 韩国日本好看电影免费看| 国产成人久久精品亚洲小说| 中文字幕亚洲第一| 中文字幕成人免费视频| 亚洲综合一区国产精品| 亚洲成A人片77777国产| 久久aⅴ免费观看| 亚洲欧美第一成人网站7777| 亚洲视频在线精品| 99久久99久久精品免费观看| 国产人成亚洲第一网站在线播放| 亚洲成AⅤ人影院在线观看| 久久成人免费电影| 亚洲欧洲国产综合AV无码久久| 亚洲国产高清精品线久久| 国产麻豆一精品一AV一免费| 精品亚洲AV无码一区二区三区 | 亚欧乱色国产精品免费视频| 亚洲综合国产精品| 国产午夜免费福利红片| 嫩草影院在线播放www免费观看| 亚洲jizzjizz在线播放久|