1. ホーム
  2. spring

[解決済み] ResourceBundleViewResolverでviews.propertiesが必要な理由

2022-02-03 10:38:51

質問

これは、インターネットから恥ずかしげもなく例をコピーしているときに遭遇する、奇妙な質問の一種です。 私はSpring MVC 4、Apache Tiles 3、Java 8、およびTomcat 8を使用しています。

views.properties ファイルは絶対に必要です。 しかし 実際のマッピングが含まれている必要はありません。 つまり、なぜ必要なのか、というよりも、なぜ必要ないのか、ということなのです。

views.properties ファイルを見ればわかるように、userList とは全く関係のない項目が一つあります。 もし、このファイルが完全に見つからない場合、DispatcherServletはExceptionを投げます。 しかし、この哀れなエントリでは、すべてが正常に動作します。 確かに、TilesViewクラスはリストアップされていますし、JSPがどこにあるかという一般的なアイデアも提供されています。 しかし すべて 各JSPはviews.propertiesファイルに綿密にリストアップされなければならないと書いてあるのを読んだことがあります。 それは単に真実ではありません。

一方では、これはメンテナンスの手間が減るので良いことだと思います。 しかし、もう一方では、何か重要なことを見逃しているような気がするのです。免責事項: 私はまだ静的リソースリゾルバをクラックしていません、それは非常に不屈の証明である。 これは、Springが私のリソースを見つけるための一般的な問題であることを除けば、この件とは全く関係ないように思われます。

悪名高い views.properties (ENTIRE FILE)

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

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 は、読み込み/起動に失敗します。

あなたが説明した動作と、Tilesを使用していることから判断して TilesViewResolver . タイルの場合、返されたビューの名前は、ここで userList は、タイルビューの定義に対応する必要があります。

Spring MVCを使用する場合、設定されたすべての ViewResolver が参照され、ビューの名前を実際の View を実装しています。あなたの場合 ResourceBundleViewResolver が返されます。 null という名前のビューしか扱えないので、ビューの解決には messages の次に TilesViewResolver に対するタイルビュー定義があるので、ビューを返します。 userList .