Java、Spring、Apache Tiles 错误:在名称为“dispatcher”的servlet中无法解析名称为“index”的视图。

5

我对Tiles和Spring MVC都很陌生(我查看了几个类似的问题,但没有找到解决“我的问题”的方法)

控制器:

@Controller
public class IndexController {

    @RequestMapping("/index")
    public String index(){
        return "index";
    }
}

我的“general.xml”包含Tiles定义:

<tiles-definitions>
<definition name="common" template="/WEB-INF/layout/classic.jsp">
    <put-attribute name="footer" value="/WEB-INF/layout/footer.jsp" />
</definition>

<definition name="index" extends="common">
    <put-attribute name="title" value="My First Application" />
    <put-attribute name="body" value="/WEB-INF/jsp/index.jsp" />
</definition>

异常:

javax.servlet.ServletException: Could not resolve view with name 'index' in servlet with name 'dispatcher'
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1208)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1012)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:738)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:551)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:586)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1111)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:478)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1045)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:261)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:101)
at org.eclipse.jetty.servlet.DefaultServlet.doGet(DefaultServlet.java:552)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:738)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:551)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:568)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1111)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:478)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1045)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:199)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:109)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:462)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:279)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:232)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:534)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:607)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:536)
at java.lang.Thread.run(Thread.java:744)

dispatcher-servlet.xml:

<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
    <property name="definitions">
        <list>
            <value>/WEB-INF/defs/general.xml</value>
        </list>
    </property>
</bean>

<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView"/>  
</bean>

web.xml

  <servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.html</url-pattern>
    <url-pattern>*.htm</url-pattern>
    <url-pattern>*.json</url-pattern>
    <url-pattern>*.xml</url-pattern>
</servlet-mapping>

你看过这个教程吗?http://richardbarabe.wordpress.com/2014/02/02/apache-tiles-3-integration-with-spring-mvc/ - geoand
不,我已经按照另一个教程进行了操作,但是不明白出了什么错误。 - flopec
你有在GitHub上的代码或其他什么东西吗,这样我就可以试一下了吗? - geoand
https://github.com/yuramitsyuk/my-first-app - flopec
非常感谢,这一定是某个愚蠢的错误,但我不知道它出在哪里。 - flopec
6个回答

7
问题出在项目位置上。
当位置中有空格时,jetty、apache tiles和spring的视图解析器的组合无法工作。
例如:项目位置为“D:\folder whitespace\your_project”,将会抛出以上错误——在名为“dispatcher”的servlet中无法解析名称为“index”的视图。
解决方法是将项目位置更改为没有空格的路径。

4
问题非常简单。请将您的web.xml文件替换为以下内容:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name>my-first-app</display-name>


  <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

我还在pom中添加了一个jstl依赖项

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

在进行这些更改后,对localhost:8080/index 的请求会正确地呈现相应的响应。

尝试在Maven中进行干净的编译。对我来说,这对Tomcat和嵌入式Jetty都有效。 - geoand
如果你按照我的更新答案,这段代码也应该可以在Jetty上运行。我已经验证了很多次。 - geoand
这很奇怪... 你是否更新了GitHub存储库中的最新更改,以便我可以再次查看它? - geoand
GitHub代码库已更新。正如我所说,我的(和你的)代码在Tomcat上运行良好,但是当我尝试在Jetty上运行时仍然出现错误。 - flopec
无论如何,感谢您的时间。当我找到这个问题的解决方案时,我会在这里写下来。 - flopec
显示剩余3条评论

3

今天我遇到了同样的问题。由于我刚开始学习Spring,所以不知从何处着手。经过一整天的努力,我终于找到了答案:

我的default.xml文件是错误的。我进行了一些手动重构,这导致了所有麻烦。以下是出错的示例:

<definition name="tos.base" template="/WEB-INF/templates/default.jsp">
<put-attribute name="includes" value="" ></put-attribute>
<put-attribute name="title" value="Title" ></put-attribute>
<put-attribute name="header" value="/WEB-INF/tiles/header.jsp"></put-attribute>
<put-attribute name="content" value="/WEB-INF/tiles/content.jsp"></put-attribute>
<put-attribute name="footer" value="/WEB-INF/tiles/footer.jsp"></put-attribute>
</definition>

<definition name="home" extends="tos.base">
<put-attribute name="title" value="Homepage" ></put-attribute>
<put-attribute name="content" value="/WEB-INF/tiles/home.jsp"></put-attribute>
</definition>

<definition name="current" extends="to.base">
<put-attribute name="title" value="Current" ></put-attribute>
<put-attribute name="content" value="/WEB-INF/tiles/current.jsp"></put-attribute>
</definition>

正如你所看到的,我在最后一个定义中 "extends" 的值是错误的。 我从 tiles3.TilesViewResolver 降级到 tiles2.TilesViewResolver,这提供了更有用的错误信息。


2
尝试将IndexController.index()的返回值从"/WEB-INF/jsp/index.jsp"更改为"index"。以下是我的解决方法:
@RequestMapping("/index")
public String index() {
    return "index";
}

1

1
这个解决方案实际上解决了我们遇到的问题。 - Sam Sokeye

1
我遇到了同样的问题。 尝试在tiles配置文件中使用正确版本的DTD。

https://stackoverflow.com/a/28854479

在您的瓷砖定义文件general.xml中,使用tile:insertAttribute代替tile:addAttribute
<tile:insertAttribute name="body"/>
     <br />
<tile:insertAttribute name="footer" />

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接