2

这是从互联网上无耻地复制示例时遇到的那种奇怪的问题。我正在使用 Spring MVC 4、Apache Tiles 3、Java 8 和 Tomcat 8。

我绝对必须有一个views.properties 文件。 它不需要任何实际的映射。所以问题不是我为什么需要它,而是我为什么不需要它。

正如您从views.properties 文件中看到的那样,它有一个与userList 完全无关的条目。如果文件完全丢失,DispatcherServlet 会抛出异常。但是有了这个可怜的条目,一切都很好。当然,它确实列出了 TilesView 类,并提供了一个可以在哪里寻找 JSP 的大致概念。但是我读到的所有内容都说每个 JSP 都必须在views.properties 文件中仔细列出。这根本不是真的。

一方面,这很好,因为维护起来要少得多。但另一方面,它让我觉得我真的错过了一些重要的东西。免责声明:我还没有破解静态资源解析器,这被证明是相当顽固的。这似乎与此完全无关,除了两者都是 Spring 寻找我的资源的一般问题。

臭名昭著的views.properties(整个文件)

messages.(class)=org.springframework.web.servlet.view.tiles3.TilesView
messages.url=/WEB-INF/xxxx/messages.jsp (for example)

强制性代码示例:

@配置类

...
@Bean
TilesConfigurer tilesConfigurer() {
    TilesConfigurer tilesConfigurer = new TilesConfigurer();
    tilesConfigurer.setDefinitions("WEB-INF/tiles/tiles.xml"); 
    return tilesConfigurer;
}

@Bean
ResourceBundleViewResolver viewResolver() {
    ResourceBundleViewResolver resourceBundleViewResolver = new ResourceBundleViewResolver();
    resourceBundleViewResolver.setBasename("views");
    return resourceBundleViewResolver;
}

@Bean
TilesViewResolver tilesVewResolver() {
    return new TilesViewResolver();
}
...

瓷砖.xml

<tiles-definitions>
<definition name="baseLayout" template="/WEB-INF/tiles/maintemplate.jspx">
    <put-attribute name="header" value="/WEB-INF/tiles/header.jspx" />
    <put-attribute name="menu" value="/WEB-INF/tiles/menu.jspx" />
    <put-attribute name="body" value="" />
    <put-attribute name="footer" value="/WEB-INF/tiles/footer.jspx" />
</definition>

<!-- USERS -->
<definition name="userEdit" extends="baseLayout">
    <put-attribute name="title" value="Edit User" />
    <put-attribute name="body" value="/WEB-INF/views/users/edit.jspx" />
</definition>
<definition name="userList" extends="baseLayout">
    <put-attribute name="title" value="List Users" />
    <put-attribute name="body" value="/WEB-INF/views/users/list.jspx" />
</definition>
...

用户控制器.java

...
@PreAuthorize("isAuthenticated()")
@RequestMapping(method = RequestMethod.GET)
public String list(Locale locale, HttpServletRequest request, HttpServletResponse response, Model uiModel) {

    themeResolver.setThemeName(request, response, "defaultTheme");

    List<User> users = userRepository.findAll();
    uiModel.addAttribute("users", users);
    return "userList";
}
...
4

1 回答 1

1

ResourceBundleViewResolver需要一个额外的配置文件,其中包含它可以处理的每个视图的配置。默认情况下,views使用基本名称。如果此文件不存在,ResourceBundleViewResolver将无法加载/启动。

从你描述的行为和你使用 Tiles 的事实来看,我怀疑你也有一个TilesViewResolver. 对于瓦片,返回的视图名称,此处userList,必须对应于瓦片视图定义。

使用 Spring MVC 时ViewResolver,会咨询所有配置的 s 以将视图名称解析为实际View实现。在您的情况下,ResourceBundleViewResolver将返回null视图分辨率,因为它只能处理名为 的视图messages,接下来TilesViewResolver会咨询将返回一个视图,因为有一个切片视图定义userList

于 2015-05-02T16:57:46.813 回答