`
jbm3072
  • 浏览: 209132 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Spring MVC框架学习笔记 之 View技术

阅读更多

以前,我们详细介绍了Spring的Controller技术。Spring的面向接口编程,使Controller的实现多种多样。View技术也一样。今天的分析先从在Controller中的ModelAndView开始。

public class ModelAndView {     
  private Object view; //View实例或者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;
}
<style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style>

 
可以看到view实例可以指向一个View对象或者字符串。现在先看看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(); 

    /**
     * 绘制视图
     * 绘制视图的第一步是准备请求: 如果是JSP的视图技术
     * 首先会把model设为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; 

}
在这之后,我们再来看看View的实现继承类图,可以看到Spring支持多种类型视图:

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
 
<style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style>
和Controller一样,View的第一个实现也是AbstractView。所以先让我们看看AbstractView对render函数的实现:

 

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

第一步,将静态属性和model的属性都添加到mergedModel里面。如果需要请求上下文,则将请求上下文添加到model中。

静态属性是继承AbstractView进行设置的属性。而请求上下文如果设置的名字就会创建一个request上下文。在requestContext中定义了一些包括本地化和主题的处理工具。

第二步,对响应进行预处理。最后调用子类需要实现的函数renderMergedOutputModel。

对PDF和EXCEL格式我们暂且不管,且Spring支持多种视图技术,这里我们主要关注JSTL技术,

接着我们来看AbstractUrlBasedView 类。在AbstractUrlBasedView 只定义了一个url属性。别的没有什么特殊处理。

接着继承AbstractUrlBasedView 的是InternalResourceView。他对renderMergedOutputModel进行实现,实现如下:

/**
* 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,一般都是传入的参数request
HttpServletRequest requestToExpose = getRequestToExpose(request);

// 将model的数据添加到request属性中
        exposeModelAsRequestAttributes(model, requestToExpose);

// 设置helper,如果存在的话
exposeHelpers(requestToExpose);

// 对绘制进行预处理,从而获得到要分发的url
String dispatcherPath = prepareForRendering(requestToExpose, response);

// 获取请求分发对象
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对请求进行了转发。转发到url上。最后我们看看JSTLView的实现:

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

}
<style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style>

 

在InternalResourceView  中,基本上所有的处理都差不多了。在JSTLView对两个方法进行了覆盖。第一个initServletContext,主要初始化了MessageResource

第二个exposeHelpers将messageSource放在了request里面。

这样view的解析就结束了。接下来容器对jsp进行解析,并进行tag等的处理。然后将生成的页面返回给客户端。

分享到:
评论

相关推荐

    spring mvc学习笔记

    spring mvc学习笔记spring mvc学习笔记spring mvc学习笔记spring mvc学习笔记spring mvc学习笔记

    Spring MVC框架简介和使用

    介绍Spring MVC框架以及使用套路

    Spring MVC 框架学习总结

    Spring MVC 框架学习总结

    精通Spring MVC 4

    Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。Spring MVC4是当前zuixin的版本,在众多特性上有了进一步的提升。, 在精通Spring MVC4中,我们将会从头开始构建一个有用的Web应用。本书共计10章,分别介绍了...

    spring mvc框架依赖全面jar

    spring mvc轻量级框架搭建,依赖全面jar文件包。下载解压直接将jar文件复制到工程中的lib中。

    spring mvc框架源码

    spring mvc源码框架,绝对可以运行。

    spring mvc 框架示例

    Spring MVC属于SpringFrameWork的后续产品...Spring MVC 框架并不知道使用的视图,所以不会强迫您只使用 JSP 技术。Spring MVC 分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。

    Spring MVC学习框架

    spring MVC框架用于web应用快速开发的一个模块。作为当今最主流的web开发框架,开发技能相当热门,值得大家掌握应用。

    Spring MVC 学习笔记

    传智播客 Spring MVC 学习笔记

    Spring MVC框架的各种依赖包下载

    Spring MVC框架的各种依赖包下载 Spring MVC框架的各种依赖包下载

    Spring框架学习笔记

    学习spring总结的笔记 希望对初学者有所帮助

    spring框架的MVC

    Spring MVC属于SpringFrameWork的后续产品...Spring MVC 框架并不知道使用的视图,所以不会强迫您只使用 JSP 技术。Spring MVC 分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。

    spring MVC学习笔记

    spring mvc的学习笔记,主要讲解了基于xml的配置,和如何增加spring mvc拦截器,如何返回json报文

    spring MVC框架搭建

    springMVC与hibernate整合实例

    Spring3 MVC 学习笔记 入门

    Spring3 MVC 学习笔记 入门 Spring3 MVC 学习笔记 入门

Global site tag (gtag.js) - Google Analytics