为什么 ResourceBundleViewResolver 需要 views.properties
Why is views.properties required for ResourceBundleViewResolver
这种莫名其妙的问题就是无耻的从网上抄例子。我正在使用 Spring MVC 4、Apache Tiles 3、Java 8 和 Tomcat 8。
我绝对必须有一个 views.properties 文件。 但是 它不需要有任何实际的映射。所以问题不是我为什么需要它,而是我为什么不需要它。
正如您从 views.properties 文件中看到的那样,它有一个与 userList 完全无关的条目。如果文件完全丢失,DispatcherServlet 将抛出异常。但是有了这个可怜的条目,一切正常。当然,它确实列出了 TilesView class,并提供了一个关于在哪里可以寻找 JSP 的大致概念。但是 everything 我读到说每个 JSP 都必须在 views.properties 文件中仔细列出。那根本不是真的。
一方面,这很好,因为它的维护工作要少得多。但另一方面,它让我觉得我真的错过了一些重要的东西。免责声明:我还没有破解静态资源解析器,这被证明是非常顽固的。这似乎与此完全无关,除了都是 Spring 寻找我的资源的一般问题。
臭名昭著的 views.properties(整个文件)
messages.(class)=org.springframework.web.servlet.view.tiles3.TilesView
messages.url=/WEB-INF/xxxx/messages.jsp (for example)
强制性代码示例:
@配置Class
...
@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>
...
UserController.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";
}
...
ResourceBundleViewResolver
需要一个额外的配置文件,其中包含它可以处理的每个视图的配置。默认情况下使用 views
的基本名称。如果此文件不存在,ResourceBundleViewResolver
将无法 load/start。
根据您描述的行为和您使用 Tiles 的事实来判断,我怀疑您也有 TilesViewResolver
。对于图块,视图的名称 returned,此处 userList
,必须对应于图块视图定义。
当使用 Spring MVC 时,所有配置的 ViewResolver
都会被查询以将视图名称解析为实际的 View
实现。在您的情况下,ResourceBundleViewResolver
将 return null
用于视图分辨率,因为它只能处理名为 messages
的视图,接下来咨询 TilesViewResolver
将 return 一个视图,因为 userList
有一个平铺视图定义。
这种莫名其妙的问题就是无耻的从网上抄例子。我正在使用 Spring MVC 4、Apache Tiles 3、Java 8 和 Tomcat 8。
我绝对必须有一个 views.properties 文件。 但是 它不需要有任何实际的映射。所以问题不是我为什么需要它,而是我为什么不需要它。
正如您从 views.properties 文件中看到的那样,它有一个与 userList 完全无关的条目。如果文件完全丢失,DispatcherServlet 将抛出异常。但是有了这个可怜的条目,一切正常。当然,它确实列出了 TilesView class,并提供了一个关于在哪里可以寻找 JSP 的大致概念。但是 everything 我读到说每个 JSP 都必须在 views.properties 文件中仔细列出。那根本不是真的。
一方面,这很好,因为它的维护工作要少得多。但另一方面,它让我觉得我真的错过了一些重要的东西。免责声明:我还没有破解静态资源解析器,这被证明是非常顽固的。这似乎与此完全无关,除了都是 Spring 寻找我的资源的一般问题。
臭名昭著的 views.properties(整个文件)
messages.(class)=org.springframework.web.servlet.view.tiles3.TilesView
messages.url=/WEB-INF/xxxx/messages.jsp (for example)
强制性代码示例:
@配置Class
...
@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>
...
UserController.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";
}
...
ResourceBundleViewResolver
需要一个额外的配置文件,其中包含它可以处理的每个视图的配置。默认情况下使用 views
的基本名称。如果此文件不存在,ResourceBundleViewResolver
将无法 load/start。
根据您描述的行为和您使用 Tiles 的事实来判断,我怀疑您也有 TilesViewResolver
。对于图块,视图的名称 returned,此处 userList
,必须对应于图块视图定义。
当使用 Spring MVC 时,所有配置的 ViewResolver
都会被查询以将视图名称解析为实际的 View
实现。在您的情况下,ResourceBundleViewResolver
将 return null
用于视图分辨率,因为它只能处理名为 messages
的视图,接下来咨询 TilesViewResolver
将 return 一个视图,因为 userList
有一个平铺视图定义。