2015-05-01 22 views
2

这是当无耻地从Internet上复制示例时遇到的那种奇怪的问题。我使用Spring MVC 4,Apache Tiles 3,Java 8和Tomcat 8.为什么ResourceBundleViewResolver需要views.properties

我绝对必须有一个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) 

强制性代码实例:

@Configuration类

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

tiles.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> 
... 

用户控件ler.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"; 
} 
... 
+1

您正在使用与使用常规JSP文件完全不同的图块。你说什么只适用于如果你不使用瓷砖的东西。因此,如果您使用通用的'InternalResourceView'或'JstlView',您将不得不列出每一个。瓷砖是不同的,因为有一个来源包含所有的视图,瓷砖配置。这里的视图名称引用了一个tile定义。另外我强烈怀疑你有多个视图解析器,而不仅仅是一个'ResourceBundleViewResolver'。我甚至认为你的'ResourceBundleViewResolver'甚至没有被使用。 –

+0

谢谢,这非常有启发性。我评论了ResourceViewResolver并删除了views.properties,该应用程序仍然正常工作。我确实有一个TilesViewResolver,正如你猜到的(我在上面添加了它)。 – Terry

回答

1

ResourceBundleViewResolver需要其包含用于每个查看它可以处理一个配置的附加配置文件。默认使用views的基本名称。如果此文件不存在,ResourceBundleViewResolver将无法​​加载/启动。

根据您所描述的行为和您使用瓷砖的事实判断,我怀疑您也有TilesViewResolver。对于拼贴,返回视图的名称(此处为userList)必须对应于拼贴视图定义。

当使用Spring MVC时,将查询所有配置的ViewResolver以将视图的名称解析为实际的View实现。在你的情况下,ResourceBundleViewResolver将返回null作为视图分辨率,因为它只能处理名为messages的视图,接下来TilesViewResolver被查询,由于存在userList的视图定义,将返回视图。