弹簧靴:百里香叶不能正确渲染碎片

时间:2017-03-24 09:40:37

标签: spring spring-mvc spring-boot thymeleaf

我正在创建spring boot web应用程序。出于模板的目的,我正在使用百里香。我正在创建单独的html页面片段,我正在从这些片段创建两个不同的布局。但是,当我连接内容页面时,我没有得到正确的输出。

请检查代码段/

查看解析器

@Configuration
@EnableAutoConfiguration
@PropertySource("classpath:application.properties")
public class WebConfig extends WebMvcConfigurerAdapter {

@Bean
public TemplateResolver templateResolver() {
    ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver();
    templateResolver.setPrefix("/WEB-INF/views/");
    templateResolver.setSuffix(".html");
    templateResolver.setTemplateMode("html5");
    return templateResolver;
}

@Bean
public SpringTemplateEngine setTemplateEngine() {
    SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine();
    springTemplateEngine.setTemplateResolver(templateResolver());
    return springTemplateEngine;
}

@Bean
public ViewResolver viewResolver(){
    ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
    viewResolver.setTemplateEngine(setTemplateEngine());
    viewResolver.setOrder(1);
    return viewResolver;
}

目录结构

src/
  main/
    webapp/
        WEB-INF/
            views/
                fragments/
                         header.html
                         footer.html
                         navBar.html
                layouts/
                         appLayout.html
                         baseLayout.html
                 welcome.html

appLayout.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">

<head>
</head>
<body>

<div th:replace="/fragments/header :: header"></div>
<div th:replace="/fragments/navbar :: navbar"></div>
<div class="container">
    <div layout:fragment="content">
    <p>Content goes here...</p>
    </div>
    <footer>
    <div th:replace="/fragments/footer :: footer"></div>
    </footer>
</div>
</body>
</html>

页脚片段footer.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
</head>
<body>
    <div th:fragment="footer">
    Footer
    </div>
</body>
</html>

使用此方法创建不同的片段。

主要方法类aka启动

@ComponentScan(basePackages={"xyz.abc"})
@SpringBootApplication
public class AppApplication {

    public static void main(String[] args) {
        System.out.println("Started");
        SpringApplication.run(AppApplication.class, args);
    }
}

welcome.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layouts/appLayout}">

<head>
</head>

<body>
<th:block layout:fragment="content">
    <div class="hero-unit">
    <h1>My Content</h1>
    </div>
</th:block>
</body>
</html>

现在,当我访问服务器时,我只收到welcome.htmlappLayoutfragments

我错过了什么?
还有一个问题,我已经完成了很多项目,其中一些问题是将views保留在src/main/resource下,我将其保留在src/main/web/WEB-INF下这两种方法之间有什么区别?

2 个答案:

答案 0 :(得分:2)

这是一个完整的例子。

Gradle Dependency:

compile('org.springframework.boot:spring-boot-starter-thymeleaf')

如果你想使用spring-security方言[可选]加上这个:

  compile("org.thymeleaf.extras:thymeleaf-extras-springsecurity4:2.1.2.RELEASE")

在SpringBoot上你不需要视图配置你的所有视图应该去: src / resources / templates

enter image description here

这是否意味着模板dir下的所有视图都是公开的?
没有

我在哪里放置可公开访问的静态文件(js&amp; css)?
的src /资源/模板/静态

如何创建布局?

在Thymleaf中,处理垂直和水平视图片段关系很容易。

1。垂直布局关系:

假设您有一个母版页     包括所有常见的js和css文件,侧面导航,应用栏导航     ..等等。几乎所有人都会将这个视图垂直放置     观点所以在这种情况下你想以某种方式嵌入你的所有观点     在您的母版页内。假设你有employee_list页面;当用户请求employee_list页面时,employee_list页面将插入到您的主布局中,用户将看到employee_list页面+主页面元素。

母版页
在此页面上,您只需添加layout:fragment="content"即可。 content是将嵌入此页面的子视图片段的名称。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      xmlns:sec="http://www.w3.org/1999/xhtml">
<head>

</head>

<body>

    <div id = "page_wrapper">

        <div id="side_menu">
            <!--side menu content-->
        </div>


        <div id="content_wrapper">

            <!--page content-->
            <div layout:fragment="content">

            </div>

        </div>

        <script type="text/javascript" th:inline="javascript">

           //common js here

            /* ]]> */

        </script>

    </div>

</body>

</html>

enter image description here

员工列表页面
要将employee_list页面放在master中,您需要做的就是将layout:decorator="layouts/master"添加到页面的html标记中。我已将所有布局放在 src / resources / templates / layouts 目录下,为什么我使用 layouts / master 而不只是说 master 。还要注意layout:fragment="content"属性;此属性表示此视图中的任何内容都将嵌入母版页。

 <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org"
          xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
          layout:decorator="layouts/master">

    <body>

        <div id = "content" class = "content layout-list" layout:fragment="content">

            <div>

               <table>

              </table>

            </div>

        </div>

    </body>

    </html>

enter image description here
结果:

enter image description here

水平布局关系:

如果您想要包含一个公共视图而不是像我们在前一个示例中那样垂直继承它,该怎么办?比如上面的例子,你想在employee_list页面上包含一个分页视图;在这种情况下,关系变为水平。

分页片段:
这是一个工作的例子顺便说一句; Page类是我自己创建的自定义类,用于包装分页响应。这是非常简单的类我所做的就是将响应列表和分页信息放入其中。 片段名称使用th:fragment="pagination"

表示
<div th:if = "${page.totalNumberOfItems > 0 and page.numberOfItems > 0}" class = "pagination-wrapper" th:fragment="pagination" xmlns:th="http://www.thymeleaf.org">

    <div class = "valign-wrapper right">

        <div id = "items_per_page_wrapper">

            <div class="valign-wrapper">

                <span  th:text="#{ui.pagination.rows.per.page.label}" style="padding-right: 10px">Rows per page:</span>

                <select  id="items_per_page_select" name = "itemsPerPage">
                    <option th:each="items_per_page : ${page.ITEMS_PER_PAGE_OPTIONS_LIST}" th:text="${items_per_page}" th:value = "${items_per_page}" th:selected="${items_per_page} == ${page.itemsPerPage}">10</option>
                </select>

            </div>

        </div>

        <label  class="current_page_info"
                th:text="#{ui.pagination.current.page.info(${page.currentPageFirstItemNumber}, ${page.currentPageLastItemNumber}, ${page.totalNumberOfItems})}"></label>

        <ul class="pagination right">

            <li th:classappend="${page.pageNumber > 0 } ? '' : 'disabled'">
                <a id="previous_page_link" href="javascript:void(0)">
                    <i class="material-icons">navigate_before</i>
                </a>
            </li>

            <li th:classappend="${page.currentPageLastItemNumber == page.totalNumberOfItems} ? 'disabled' : ''">
                <a id="next_page_link"  href="javascript:void(0)">
                    <i class="material-icons">navigate_next</i>
                </a>
            </li>
        </ul>

    </div>

</div>

员工列表页面
在表标记下添加此代码段。

  <div th:replace="common/pagination :: pagination">
        <!--pagination content-->
    </div>

结果:
enter image description here

答案 1 :(得分:0)

如果您使用的是spring boot,则无需定义视图解析器来呈现html页面。

@SpringBootApplication注释等同于使用@Configuration,@ EnableAutoConfiguration和@ComponentScan。所以你可能不需要定义@ComponentScan。

如果使用spring boot,我也发现你不需要定义那些bean。资源下的模板目录可以直接访问,无需定义bean。因此,通过使用百里香叶,您可以轻松地从控制器返回视图。

视图保存在spring mvc中的src / main / web / WEB-INF下。但是在spring引导视图下保存在templates目录下,可以从控制器返回,而不进行任何视图解析器配置。

你的百里香问题你可以在github上看到。

https://github.com/sagar1limbu/bookstore