当前位置: 首页 > 知识库问答 >
问题:

Spring开机:thymeleaf未正确渲染片段

武卓
2023-03-14

我正在创建Spring boot web Application。出于模板目的,我使用了thymeleaf。我正在创建单独的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

应用布局。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 startup

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

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

欢迎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.html,而从appLayout片段中什么都没有

我错过了什么<还有一个问题,我经历了许多项目,其中一些项目将视图保存在src/main/resource下,我将其保存在src/main/web/web-INF下,这两种方法之间有什么区别?

共有2个答案

呼延学
2023-03-14

如果您使用Spring boot,则不需要定义视图解析器来呈现html页面。

@SpringBootApplication注释相当于使用@Configuration、@EnableAutoConfiguration和@ComponentScan。因此,您可能不需要定义@ComponentScan。

我还看到,如果使用spring boot,则不需要定义这些bean。资源下的模板目录可以直接访问,无需定义bean。因此,通过使用thymeleaf,您可以轻松地从控制器返回视图。

在spring mvc中,视图保存在src/main/web/web-INF下。但在spring启动时,视图保存在templates目录下,该目录可以从控制器返回,而无需进行任何视图解析器配置。

对于您的胸腺LEAF问题,您可以在github上看到这一点。

https://github.com/sagar1limbu/bookstore

姚才捷
2023-03-14

这是一个完整的例子。

Gradle依赖:

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

如果您想使用spring security方言[可选]添加以下内容:

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

在SpringBoot上,您不需要视图配置,所有视图都应该转到:src/资源/模板

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

我在哪里放置可公开访问的静态文件(js

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

假设你有一个母版页,其中包括所有常见的js和css文件、侧导航、应用程序栏导航。。等等。这个视图将被几乎所有的视图垂直嵌入,因此在这种情况下,您希望以某种方式将所有视图嵌入到母版页中。假设你有employee_列表页面;当用户请求employee_列表页面时,employee_列表页面将插入到主布局中,用户将看到employee_列表页面母版页元素。

母版页:
在此页面上,您只需添加布局:fragment=“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>

员工列表页面:要将员工列表页面放在母版中,只需将布局:decorator=“layouts/master”添加到页面的html标记。我把我所有的布局都放在src/resources/templates/layouts目录下,这就是为什么我使用layouts/master而不是说master。还要注意布局: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>

如果您想包括一个公共视图,而不是像上一个示例那样垂直继承它,该怎么办?假设在上面的例子中,您希望在employee_列表页面上包含分页视图;在这种情况下,关系变得水平。

分页片段:顺便说一句,这是一个工作示例;页面类是我自己创建的自定义类,用于包装分页的响应。这是一个非常简单的类,我所做的就是把响应列表和分页信息放进去。片段名称用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>
 类似资料:
  • 我正在学习这本Spring Security指南,我已经读到了“创建一个不安全的web应用程序”一节。在该节末尾,声明如下: 此时,您可以直接使应用程序可执行并运行应用程序,而无需登录任何内容。 创建基本的简单web应用程序后,您可以为其添加安全性。 我试图按照“使应用程序可执行”中描述的步骤,创建应用程序的不安全版本。但是,这些视图没有得到正确处理 例如,如果我导航到我得到了这个错误: 我发现这

  • 我看不到子组件内部的文本。子级呈现为大小为0x0且为空。 那是由路由器引起的吗? 这是我的代码: App.js: REPODetails.js: 这是child committersCard.js: 我用的是4号路由器。

  • 我面临一些渲染问题。试图建立一个2d平台游戏,我的计划是创建与搅拌机的演员。我是新手,搅拌机和libgdx,不知道错误在哪里。 在《搅拌机》中,演员看起来很好。由libgdx渲染,我只看到奇怪的形式,根本不像我的演员。 -----编辑好,我缩小了问题的范围。在blender中,我创建了一个简单的立方体。在我的libgdx应用程序中,如果只渲染多维数据集而不渲染其他内容,则可以很好地渲染此多维数据集

  • 在我的主类下面,我试图从搅拌机渲染一个obj. obj文件,在将其重新格式化为(据称)为我的渲染工作后,它会出现错误。我如何解决这个问题? 主要类: OBJLoader类: 类别模型: 类面: 对不起,如果这是过度的,我知道错误来自第85行,但我似乎不知道如何修复它。 OBJ文件示例(精简):

  • 对于使用Box2DDebugRenderer进行渲染Box2D调试,我有一些问题。我有两个正交摄像机,一个用于渲染世界(名为Cam),另一个用于HUD(healthBar,Armor,…)(名为hudCam)。 我试图渲染: > b2dr。渲染(世界,凸轮组合)- 我找不到一种方法来渲染Box2D完全像凸轮,看到所有机构的边缘。 如果有人理解我的问题,请帮助我! 谢谢。

  • 我有两个VBO,我试图渲染,它们在屏幕上应该有两个不同的位置。当我试图修改其中一个VBO的位置时,它会被转移到另一个VBOs。 示例-我更改了对象2的y位置,对象1和对象2现在都存在于该y位置。 我用于转换VBO的代码: 请注意位置,旋转,缩放都是Vector3fs,modelMatrix是well,模型矩阵。 此外,这是一个工具包。degToRad类似于数学。toRadians()类型的方法。