【JavaWeb】模板引擎Thymeleaf

  • Post author:
  • Post category:java



目录


1. 初识模板引擎


2. Thymleaf的使用流程


2.1 通过Maven引入依赖


2.2 创建HTML模板文件


2.3 编写Servlet代码


2.4 部署程序


2.5 小结


3. Thymeleaf的常用语法


3.1 设置标签文本


3.2 设置标签属性


3.3 条件判断


3.4 循环


4. 如何创建一个引擎实例?


4.1 什么是ServletContext


4.2 什么是监听器(Listener)


4.3 修改Thymeleaf引擎初始化代码


1. 初识模板引擎

什么是模板引擎?

模板引擎就是为了解决HTML代码和Java代码混合在一起这个问题的,我们可以把HTML内容提取出来单独的放在一个文件中,称为模板,对于一些动态的内容,可以将这些内容在模板中使用占位符占位,当服务器把这些动态的内容计算好了之后,就可以把模板中占位符替换成动态计算的结果,然后把组装好的HTML格式的字符串在返回给浏览器

模板引擎的作用

  • 通过组织网页模板和数据,就可以返回一个动态的网页
  • 可以分离Servlet Java代码和HTML网页代码(模板引擎的最大优点)

模板引擎的使用原理

2. Thymleaf的使用流程

2.1 通过Maven引入依赖

在Maven中央仓库搜索Thymeleaf

选择一个合适的版本,这里选择的是3.0.12

        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf</artifactId>
            <version>3.0.12.RELEASE</version>
        </dependency>

2.2 创建HTML模板文件

我们创建一个hello.html放到webapp/WEB-INF/templates目录中

注意:web.xml和templates是同级目录,都在WEB-INF目录下,hello.html在templates目录下

<body>
    <h3>模板技术学习</h3>
    <p th:text="${message}"></p>
</body>

说明:th:text是Thymeleaf的语法,后边介绍更多的Thymeleaf语法

2.3 编写Servlet代码

创建HelloServlet类,注解为@WebServlet(“/hello”),继承HttpServlet,重写doGet方法,在该类中先创建模板引擎和模板解析器,再设置数据和模板名称,最后再将渲染的html设置到响应正文

创建模板引擎和模板解析器

        //创建模板引擎,用于最终完成最终页面渲染工作
        TemplateEngine engine = new TemplateEngine();
        //创建渲染网页模板的解析器
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(getServletContext());
        resolver.setCharacterEncoding("utf-8");//设置渲染时编码
        resolver.setPrefix("/WEB-INF/templates/");//前缀
        resolver.setSuffix(".html");//后缀
        //将解析器绑定到模板引擎中
        engine.setTemplateResolver(resolver);

设置数据和模板名称

        //创建一个web上下文(里面有一个map结构,存放键值对)
        WebContext wc = new WebContext(req,resp,getServletContext());
        //设置一个键值对数据,键为message(模板中的变量),值为好好学习(要渲染的值),
        wc.setVariable("message","好好学习");

        //模板引擎渲染网页模板,第一个参数为模板名称,第二个参数为web上下文
        //根据模板解析器设置的前缀+模板名称+后缀为模板路径,查找到模板,再组织模板内容+数据
        //返回值就是渲染后的网页字符串
        String html = engine.process("hello",wc);

将渲染的html设置到响应正文

        resp.setContentType("text/html; charset=utf-8");//设置响应编码
        resp.getWriter().write(html);

2.4 部署程序

1. 点击启动tomcat

2. 输入路径hello

3. 观察结果

2.5 小结

  • resovler的setPefix和setSuffix方法指定了从那个目录下筛选哪些文件
  • engine.process方法第一个参数指定了要加载哪个模板文件
  • webContext中指定了模板变量名和变量值的对应关系(类似哈希表结构),setVariable中的第一个参数要和模板文件中写的 ${message} 匹配
  • engine.process方法会把刚才的webContext里的值替换到模板中,并把最终结果写到resp对象中

在上述代码中,有这三个关键类:

  • TemplateEngine,核心功能是通过process()方法完成渲染工作
  • ServletContextTemplateResolver,核心功能是加载模板文件,为后边的渲染做准备
  • webContext,核心功能是组织模板变量要替换为什么值

3. Thymeleaf的常用语法

命令 功能
th:text 设置标签文本
th:[HTML标签属性] 设置标签属性
th:if 当表达式的结果为真时则显示内容,否则不显示
th:each 循环访问元素

Thymeleaf语法很多,此处只介绍最常用的几个

3.1 设置标签文本

th:text功能就是设置标签文本

    <p th:text="${message}"></p>

3.2 设置标签属性

常需要设置的属性:href src class style…

示例:设置a标签的href属性

    <a th:href="${url1}">百度</a>
    <a th:href="${url2}">搜狗</a>

对应后端代码:

        wc.setVariable("url1","http://www.baidu.com");
        wc.setVariable("url2","http://www.sogou.com");

运行程序,访问页面,点击就会跳转到对应的页面

3.3 条件判断

th:if功能就是根据条件决定该标签是否显示

    <P th:if="${isLogin}">已经登陆</P>
    <p th:if="${noLogin}">没有登陆</p>
        wc.setVariable("isLogin",true);
        wc.setVariable("noLogin",false);

结果:只显示已经登陆

3.4 循环

th:each的功能是可以循环的构造出多个元素

语法格式:th:each=”自定义变量元素名称 : ${集合变量名称}”

    <ul>
        <Li th:each="u : ${users}">
            姓名:<span th:text="${u.name}"></span>
            年龄:<span th:text="${u.age}"></span>
        </Li>
    </ul>
        wc.setVariable("users",Arrays.asList(
                new User("张三",21),
                new User("李四",23),
                new User("王五",28)
        ));
    private static class User{
        private String name;
        private int age;

        public User(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public int getAge() {
            return age;
        }
    }

注意:创建的User类需要提供getter方法

结果:

4. 如何创建一个引擎实例?

上述初始化引擎及解析器的代码,每个需要渲染页面的Servlet类都需要写一次,其实没有必要,一个完整的项目中,TemplateEngine和ServletContextTemplateResolver只需要创建一次并且初始化一次,为了完成这个目的,就需要使用Servlet中的ServletContext和ServletContextListener监听器

4.1 什么是ServletContext

ServletContext是一个Servlet程序中全局储存信息的空间,服务器启动就创建,服务器关闭就销毁

  • Tomcat在启动时,它会为每个webapp都创建一个对应的ServletContext
  • 一个Web应用的所有Servlet共享同一个ServletContext对象
  • 可以通过HttpServlet.getServletContext()或HttpServletRequest.getServletContext()获取到当前webapp的ServletContext对象

理解Context:上下文/环境,常用于设置一些信息到上下文环境中,上下文环境中的对象就可以相互引用对方的数据

多个Servlet之间无法传递数据,但可以通过共享的上下文环境来设置或使用一些数据(数据传递)

ServletContext对象的重要方法

方法 说明
void setAttribute(String name,Object obj) 设置属性(键值对)
Object getAttribute(String name) 根据name获取对应的值,如果name为不存在,返回null
void removeAttribute(String name) 删除对应的属性

ServletContext类似Map结构,存放键值对数据

4.2 什么是监听器(Listener)

监听器属于一种设计模式,在Servlet运行过程中,会有一些特殊的“时机”供我们执行一些我们自己定义的逻辑,“监听器”就是可以让程序员在这些特殊的时机插入代码

此处学习的ServletContextListener,也是类似一种监听器的设计,在事件发生的时候不用我们自己写代码做事情,而是先注册一个方法到监听器,在某个事件发生后就会自动执行

此处我们需要使用监听器监听ServletContext的创建即可

4.3 修改Thymeleaf引擎初始化代码

结合ServletContext和Listener,我们就可以对之前的Thymeleaf引擎初始化代码做出调整

  1. 创建监听器,监听ServletContext的创建
  2. 当ServletContext创建完后,在contextInitialized方法中创建TemplateEngine实例和ServletContextTemplateResolver实例,并完成初始化
  3. 把创建出来的TemplateEngine实例放到ServletContext中
  4. 后续Servlet如果要使用TemplateEngine,那么直接从ServletContext获取之前创建好的实例

创建监听器

@WebListener
public class TemplateEngineListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        TemplateEngine engine = new TemplateEngine();
        ServletContext sc = sce.getServletContext();
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(sc);
        resolver.setCharacterEncoding("utf-8");
        resolver.setPrefix("/WEB-INF/templates/");
        resolver.setSuffix(".html");
        engine.setTemplateResolver(resolver);
        sc.setAttribute("engine",engine);
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}

写前端test.html代码

<p th:text="${content}"></p>

写对应的后端代码

@WebServlet("/test")
public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext sc = req.getServletContext();
        WebContext wc = new WebContext(req,resp,sc);
        wc.setVariable("content","写一篇博客");
        TemplateEngine engine = (TemplateEngine) sc.getAttribute("engine");
        String html = engine.process("test",wc);
        resp.setContentType("text/html; charset=utf-8");
        resp.getWriter().write(html);
    }
}

启动Tomcat,输入url,观察结果



版权声明:本文为qq_58710208原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。