zoukankan      html  css  js  c++  java
  • (二)springboot整合thymeleaf模板

    在我们平时的开发中,用了很久的jsp作view显示层,但是标签库和JSP缺乏良好格式的一个副作用就是它很少能够与其产生的HTML类似。所以,在Web浏览器或HTML编辑器中查看未经渲染的JSP模板是非常令人困惑的,而且得到的结果看上去也非常丑陋(也就是不放到服务器,直接本地打开)。

    但是Thymeleaf模板是原生的,不依赖于标签库。它能在接受原始HTML的地方进行编辑和渲染(也就是说我们通过thymeleaf写一个页面,如果不放到服务器进行渲染,也是可以看到效果的,跟后端打开基本相同)

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

    配置springbean视图

    首先我们需要让springboot(springmvc通用)知道我们的页面是通过什么来渲染的(jsp,freemarker,thymeleaf等等,以及模板的位置等信息)

    /**
     * 设置视图解析器
     * @param templateEngine
     * @return
     */
    @Bean
    public ViewResolver viewResolver(SpringTemplateEngine templateEngine){
        ThymeleafViewResolver resolver = new ThymeleafViewResolver();
        resolver.setTemplateEngine(templateEngine);
        return resolver;
    }
    
    /**
     * 设置模板引擎
     * @param templateResolver
     * @return
     */
    @Bean
    public SpringTemplateEngine templateEngine(TemplateResolver templateResolver){
        SpringTemplateEngine engine = new SpringTemplateEngine();
        engine.setTemplateResolver(templateResolver);
        return engine;
    }
    
    /**
     * 模板解析引擎
     * @return
     */
    @Bean
    public TemplateResolver templateResolver(){
        TemplateResolver resolver = new SpringResourceTemplateResolver();
        resolver.setPrefix("/WEB-INF/template/");//设置地址前缀
        resolver.setSuffix(".html");//设置后缀
        resolver.setCacheable(false);//设置不缓存
        resolver.setTemplateMode("HTML5");
        return resolver;
        
    }

    ThymeleafViewResolver是Spring MVC中ViewResolver的一个实现类。像其他的视图解析器一样,它会接受一个逻辑视图名称,并将其解析为视图

    TemplateResolver会最终定位和查找模板。与之前配置InternalResourceViewResolver类似,它使用了prefix和suffix属性。前缀和后缀将会与逻辑视图名组合使用,进而定位Thymeleaf引擎。它的templateMode属性被设置成了HTML 5,这表明我们预期要解析的模板会渲染成HTML 5输出

    到这里我们就基本配置完了 。


    接下来我们在WEB-INF/template下建立home.html,头部加入thymeleaf的命令空间

    <html xmlns:th="http://www.thymeleaf.org">

    建立一个controller,写我们的第一个controller,打开访问localhost:8080/home就会转发到/WEB-INF/template/home.html

        @RequestMapping("/home")
        public String hello(Map<String,Object> map){
            User user = new User("1", "fei", 22, "爱好:篮球","admin");
            map.put("user",user);
            
            List<User> list = new ArrayList<>();
            for(int i =0;i<5;i++){
                User u = new User(""+(i+2), "fei"+(i+2), 22+(i+2), "爱好:篮球"+(i+2),"user"+i);
                list.add(u);
            }
            map.put("userList",list);
            
            return "home";
        }

    thymeleaf语法

    文本显示

    ${}的使用和jsp的el表达式很类似,我们在后台绑定了一个user对象那么我们可以通过${user.name}获取用户名,相当于user.getName();但是注意这个只能放到th表达式里面

    th:text就相当于把里面的渲染主来的值放到aaa的位置上,如果th:text里面的值只有${user.name},并且为null,那么就会显示aaa

    <span th:text="'用户名:' +${user.name}">aaa</span>
    #或者下面的这种方式,|…|中只能包含变量表达式${…},不能包含其他常量、条件表达式等
    <span th:text="|用户名:${user.name}|"></span>

     运算符

    在表达式中可以使用各类算术运算符,例如+, -, *, /, %

    <span th:text="'年龄*2='+ ${user.age}*2 "></span>

    逻辑运算符

    在表达式中可以使用逻辑运算符,但是除了==其他的要使用转义字符

    >, <, >=, <= != 对应(gt, lt, ge, le, ne)

    <span th:text="(${user.age} eq 22)">aaa</span>  //输出true
    #可以使用二元表达式
    <span th:text="(${user.age} ge 23?'超过年纪':'ok')"></span>

    条件判断

    th:if条件成立才会显示
    th:unless条件不成立才会显示

    <span th:if="(${user.age} gt 21)">年龄超过21才会显示</span>
    <a th:href="@{/login}" th:unless=${session.user != null}>Login</a>

    Switch

    * 代表default,其他都没匹配到会显示带*的

    <div th:switch="${user.role}">
      <p th:case="'admin'">用户是管理员</p>
      <p th:case="*">用户是普通人员</p>
    </div>

    循环

    第二个参数称作状态变量,属性有
    - index:当前迭代对象的index(从0开始计算)
    - count: 当前迭代对象的index(从1开始计算)
    - size:被迭代对象的大小
    - current:当前迭代变量
    - even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算)
    - first:布尔值,当前循环是否是第一个
    - last:布尔值,当前循环是否是最后一个

    <table>
      <tr>
           <th>index</th>
            <th>id</th>
            <th>name</th>
           <th>age</th>
      </tr>
      <tr th:each="user,iterStat: ${userList}" >
          <td th:text="${iterStat.index}">1</td>
            <td th:text="${user.id}">1</td>
            <td th:text="${user.name}">王五</td>
            <td th:text="${user.age}">55</td>
      </tr>
    </table>

    * 号和$符号共用

    *{}里面的值就是上层th:object对象里面对应的属性

     <div th:object="${user}">
       <p>Name: <span th:text="*{name}">wangwu</span>.</p>
       <p>AGE: <span th:text="*{age}">22</span>.</p>
     </div>

    Utilities

    Utilities为了模板更加易用,Thymeleaf还提供了一系列Utility对象(内置于Context中),可以通过#直接访问

    - dates : java.util.Date的功能方法类。
    - calendars : 类似#dates,面向java.util.Calendar
    - numbers : 格式化数字的功能方法类
    - strings : 字符串对象的功能类,contains,startWiths,prepending/appending等等。
    - objects: 对objects的功能类操作。
    - bools: 对布尔值求值的功能方法。
    - arrays:对数组的功能类方法。
    - lists: 对lists功能类方法
    - sets
    - maps

    表达式基本对象
    - #ctx: 上下文对象.
    - #vars: context中的变量们.
    - #locale: context中的locale.
    - #httpServletRequest: (只在web context中) HttpServletRequest对象.
    - #httpSession: (只在web context中) HttpSession对象.

    将date渲染成后面的格式
    ${#dates.format(date, 'dd/MMM/yyyy HH:mm')}
    得到当前时间
    ${#dates.createNow()}
    得到当前时间并显示
    <span th:text=" ${#dates.format(new java.util.Date().getTime(), 'yyyy-MM-dd hh:mm:ss')} "></span>

     utilities其他使用链接,很详细

    内联

    Text inlining

    后面[[]]里面的值是从域中获取的text文本,跟使用th:text效果类似

    <span th:inline="text">[[${user.name}]]</span>

    JavaScript inlining

    <script th:inline="javascript">
        var name = [[${user.name}]];
    </script>

    下面这个意思是如果没有跑在服务器,name就会是我们的lisi,如果在服务器上,会取出user.name的值,忽略lisi

    var name = /*[[${user.name}]]*/"lisi";

    CSS inlining

    <style th:inline="css">
        .[[${classname}]] {
          text-align: [[${align}]];
        }
    </style>

    none inlining

    但是如果我么就要显示[[${user.name}]]不需要他转换呢,就会用到none inlining

    <span th:inline="none">[[${user.name}]]</span>

    嵌套

    在当前home.html路径下有个footer.html,内容如下

    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
      <body>
        <footer th:fragment="copy">
          &copy; 2011 The Good Thymes Virtual Grocery
        </footer>
      </body>
    </html>

    在home.html引用这个footer,footer代表html的名称,copy代表fragmen的值

    <div th:replace="footer:: copy"></div>
    <div th:include="footer:: copy"></div>

    展现的源码:

    <footer>
        &copy; 2011 The Good Thymes Virtual Grocery
    </footer>
    <div>
        &copy; 2011 The Good Thymes Virtual Grocery
    </div>

    得出结论:
     - th:replace会将当前div整个替换成foot的元素
     - th:include只是将footer里面的内容拷贝进来


    链接

    链接一般用th:href="@{地址}",“@{}”表达式,用来计算相对于URL的路径,在html ==<a  href="/register"></a>

    <a th:href="@{/register}">register</a>

    常用标签


    springboot简化配置

    当然在springboot中,上面的视图解析器等注册都不需要我们做了,因为springboot都默认帮我们做了,(只要我们将Thymeleaf maven依赖添加到项目的pom文件下,就启用了Spring Boot的自动配置。当应用运行时,Spring Boot将会探测到类路径中的Thymeleaf,然后会自动配置视图解析器、模板解析器以及模板引擎)

    如果什么都不配置,springboot会默认查找类跟目录下的templates文件夹下的模板,home.html放到src/main/ resources/templates目录下

    如果我们要在home的html中引入一些静态资源怎么办呢,这点springboot也帮我们考虑到了

    springboot它会将“/**”映射到几个资源路径中

    • META-INF/resources/
    • resources
    • static
    • public

    也就是说我们在有一个static/css/home.css

    那么我们这样引入就可以了。

    <link type="text/css" rel="stylesheet" th:href="@{/css/home.css}"></link>

    当然,我们还是可以配置前缀后缀,以及是否缓存等,只需要一个简单的配置即可

    #配置前缀
    #spring.thymeleaf.prefix=classpath:/templates/  
    #配置后缀
    #spring.thymeleaf.suffix=.html
    #spring.thymeleaf.mode=HTML5 
    #spring.thymeleaf.encoding=UTF-8 
    #spring.thymeleaf.content-type=text/html 
    #是否开启缓存
    spring.thymeleaf.cache=false 

    github代码地址

  • 相关阅读:
    BZOJ2243: [SDOI2011]染色
    BZOJ1036: [ZJOI2008]树的统计Count
    转自 x_x_的百度空间 搞ACM的你伤不起
    wcf test client
    wcf test client
    log4net编译后命名空间找不到的问题
    log4net编译后命名空间找不到的问题
    Hive Getting Started
    Hive Getting Started
    刚听完CSDN总裁蒋涛先生的学术报告
  • 原文地址:https://www.cnblogs.com/nfcm/p/7843935.html
Copyright © 2011-2022 走看看