【问题标题】:spring 2.5 jstl view errorspring 2.5 jstl视图错误
【发布时间】:2010-01-11 20:57:51
【问题描述】:

我有以下控制器


@Controller
@RequestMapping("/project/view.html")
public class ProjectViewController {

 private static final String viewName = "projectView";


 @RequestMapping(method = RequestMethod.GET)
 public String showPage(Model model,
   @RequestParam(value="id",required=false) Long id) {

  //code.....

  return viewName;
 }

}

我的views.properties 包含


projectView.(class)=org.springframework.web.servlet.view.JstlView
projectView.url=/WEB-INF/jsp/project/view.jsp

一切都按预期进行。

但我需要更改返回 View() 的方法,因为如果出现故障,我必须将 RedirectView() 返回到某个错误页面。所以我将方法更改为:


@Controller
@RequestMapping("/project/view.html")
public class ProjectViewController {

 private static final String viewName = "projectView";


 @RequestMapping(method = RequestMethod.GET)
 public View showPage(Model model,
   @RequestParam(value="id",required=false) Long id) {

  //code.....

  return new JstlView(viewName);
 }

}

但在这种情况下,我得到了一个 NPE:


java.lang.NullPointerException
 at org.springframework.web.context.support.WebApplicationObjectSupport.getServletContext(WebApplicationObjectSupport.java:121)
 at org.springframework.web.servlet.view.JstlView.exposeHelpers(JstlView.java:133)
 at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:209)
 at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:257)
 at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1183)
 at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:902)
 at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
 at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
 at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:129)
 at com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:77)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
 at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
 at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
 at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
 at java.lang.Thread.run(Thread.java:619)

我已经调试过了,似乎 getWebApplicationContext() 返回 null。

任何帮助表示赞赏。

谢谢。

【问题讨论】:

  • 如果我将方法更改为返回 ModelAndView() 而不是仅返回 View(),它会起作用
  • 这是什么版本的 Spring?

标签: java spring frameworks


【解决方案1】:

您的异常的原因是JstlView 的实例需要注入某些东西才能使用它们,例如当前的WebApplicationContext。通常,这对您来说是透明的,因为 Spring 会为您实例化并准备 JstlView。只有当您自己动手时,您才能看到其中的内容。

现在,您可以在您实例化的JstlView 上调用setApplicationContext,但您不希望您的控制器参与此类事情。你真的希望让 Spring 继续工作。

现在,由于您使用的是views.properties,因此您也使用ResourceBundleViewResolver 来解决您的视图。这里的诀窍是要意识到 Spring 可以在同一上下文中处理 多个 视图解析器,它只会一个接一个地询问它们,直到其中一个解析视图名称。

所以我的建议是在您的上下文中添加另一个解析器,这次是 InternalResourceViewResolver(这实际上是默认解析器,但是当您指定 ResourceBundleViewResolver 时,默认会被抑制)。

现在,当您返回 ResourceBundleViewResolver 无法解析的视图名称时,将咨询 InternalResourceViewResolver

InternalResourceViewResolver 只是将视图名称作为实际的 JSP 路径(例如,直接从您的控制器方法返回 /WEB-INF/page.jsp)。它还允许您使用 redirect:/path/to/my/url 之类的语法。

因此,您的其他控制器可以继续返回 views.properties 中指定的视图名称,但现在您还可以返回动态组装的 redirect:x/y/ 视图名称,这些名称将由 InternalResourceViewResolver 转换为 RedirectView。无需自己构建这些视图。

最后一点要注意:视图解析器按照它们在 bean 文件中出现的顺序进行查询,InternalResourceViewResolver 必须在该列表中排在最后。

【讨论】:

    【解决方案2】:

    JstlView 实现了ApplicationContextAwareServletContextAware,所以如果你想手动实例化它,你应该调用setApplicationContextsetServletContext(可能还有其他一些初始化)。

    但是您可以在您的views.properties 中定义一个RedirectView,这样您就不必自己返回一个View 对象:

    someRedirectView.(class)=org.springframework.web.servlet.view.RedirectView
    someRedirectView.url=/redirectHere 
    

    【讨论】:

    • 谢谢,在views.properties 中定义重定向视图看起来像是一个优雅的解决方案。但是如果我需要在请求时构建重定向 url,比如 "/redirectHere?id=" + id;是否仍然可以在views.properties中以某种方式定义它,并对其进行参数化?
    • 默认情况下,RedirectView 将模型属性公开为 URL 参数,因此您可以将您的 id 添加到模型中。
    【解决方案3】:

    未测试,但这应该可以工作

    > projectView.url=redirect:/WEB-INF/jsp/project/view.jsp
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-31
      • 2022-12-14
      • 2016-08-10
      相关资源
      最近更新 更多