诡异的InternalResourceViewResolver

现象:
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="suffix" value=".jsp" />
</beans:bean> 
 
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="suffix" value=".html" />
</beans:bean>
    第一种可以正常工作,第二种不行,当然了/WEB-INF/views里面 jsp和html结尾的都可以。
  
WARN : org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/myapp/WEB-INF/views/home.html] in DispatcherServlet with name 'appServlet'
    
    错误的原因就是html页面被加上了/myapp前缀,myapp为我的工程名称。
    分析,从spring的 InternalResourceViewResolver 入手:
   
@Override
    protected AbstractUrlBasedView buildView(String viewName) throws Exception {
         InternalResourceView view = (InternalResourceView) super .buildView(viewName);
          if (this .alwaysInclude != null) {
             view.setAlwaysInclude( this.alwaysInclude );
         }
          if (this .exposeContextBeansAsAttributes != null) {
             view.setExposeContextBeansAsAttributes( this.exposeContextBeansAsAttributes );
         }
          if (this .exposedContextBeanNames != null) {
             view.setExposedContextBeanNames( this.exposedContextBeanNames );
         }
         view.setPreventDispatchLoop( true);
          return view;
    }
    
       从代码来看这个地方只是构建了一个view,应该是没有问题的,最终我跟踪代码到 InternalResourceView renderMergedOutputModel 函数。
    
// 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.
             exposeForwardRequestAttributes(requestToExpose);
              if (logger .isDebugEnabled()) {
                  logger.debug("Forwarding to resource [" + getUrl() + "] in InternalResourceView '" + getBeanName() + "'");
             }
             rd.forward(requestToExpose, response);
         }
      从这段代码来看,prepareForRendering这个函数是来准备url的,也就是刚才的InternalResourceViewRoslver的解析的结果,从调试来看,这两个的配置的返回的路径一致。那问题应该出在 RequestDispatcher的fowward函数了,从这个地方来看,又回到了servlet里面,然后我写了个小例子。
     
    从小例子来看是完全一样的。
    
 10:55:58.283 [http-bio-8080-exec-4] DEBUG o.s.web.servlet.view.JstlView - Added model object 'org.springframework.validation.BindingResult.user' of type [org.springframework.validation.BeanPropertyBindingResult] to request in view with name 'index'
10:55:58.283 [http-bio-8080-exec-4] DEBUG o.s.web.servlet.view.JstlView - Added model object 'user' of type [microshield.com.cn.radius.admin.model.User] to request in view with name 'index'
10:55:58.284 [http-bio-8080-exec-4] DEBUG o.s.web.servlet.view.JstlView - Forwarding to resource [/WEB-INF/pages/index.jsp] in InternalResourceView 'index'
10:56:11.719 [http-bio-8080-exec-4] DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request

10:48:22.161 [http-bio-8080-exec-10] DEBUG o.s.web.servlet.view.JstlView - Forwarding to resource [/WEB-INF/pages/index.html] in InternalResourceView 'index'
10:48:22.178 [http-bio-8080-exec-10] DEBUG o.s.web.servlet.DispatcherServlet - DispatcherServlet with name 'Spring MVC Dispatcher Servlet' processing GET request for [/microshield-radius/WEB-INF/pages/index.html]
10:48:22.180 [http-bio-8080-exec-10] DEBUG o.s.w.s.m.a.DefaultAnnotationHandlerMapping - Looking for URL mappings in application context: WebApplicationContext for namespace 'Spring MVC Dispatcher Servlet-servlet': startup date [Mon Sep 15 10:47:54 CST 2014]; parent: Root WebApplicationContext
10:48:22.182 [http-bio-8080-exec-10] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'userAction'
   

 

 
       从调用的轨迹来看,jsp file直接在response流里面进行了处理,但是html file又发起了一次请求。
     但是我在普通的servlet里面运行工程是可以的,由于没有时间下载tomcat的源码进行调试,没有看到具体的代码走的分支,有熟悉的给帮我解答下。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值