ThymeleafEngine模板引擎

目录

动态页面的渲染方式

服务器渲染

客户端渲染

字符串拼接HTML

使用模板引擎

模板引擎使用流程

Thymeleaf模板语法

只创建一个引擎实例

什么是ServletContext

什么是监听器Listener

修改Thymeleaf引擎初始化代码


动态页面的渲染方式

动态页面需要通过服务器根据客户端传来的参数, 动态计算得到一些结果, 并且把这些结果显示到页面上.

服务器渲染

数据和页面结合的工作, 通过服务器完成.

客户端渲染

服务器把数据返回给浏览器, 由浏览器把数据和页面结合起来.

浏览器和服务器之间的数据往往交互通过 ajax 进行, 数据的格式往往使用 JSON.

字符串拼接HTML

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/html")
public class HtmlServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        //请求传过来一个query string,里面有一个参数是name,返回的页面里,就有这个name的值,请求的name不同,返回的页面就不同
        String name = req.getParameter("name");
        resp.getWriter().write("<h3>"+name+"</h3");
    }
}

如果是返回一个简单的页面, 可以按照上述方式拼接字符串完成.

但是如果是一个复杂的页面, 就要写很复杂的代码了

使用模板引擎

模板引擎使用流程

通过maven引入依赖

选择3.0.12版本

创建HTML模板文件

hello.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>thymeleaf</title>
</head>
<body>
    <!--th就是thymeleaf的缩写,表示这个属性是thymeleaf类提供的,text表示类型为字符串-->
    <h3 th:text="${message}"></h3>
</body>
</html>

编写Servlet代码

helloThymeleafServlet.java

import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/helloThymeleaf")
public class HelloThymeleafServlet extends HttpServlet {
    //这是Thymeleaf中最核心的类 TemplateEngine模板引擎
    private TemplateEngine engine = new TemplateEngine();

    @Override
    public void init() throws ServletException {
        //创建一个模板解析器对象,搭配上下文来使用
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(this.getServletContext());
        //让模板解析器来加载模板文件,这里的前缀就表示模板文件所在的目录,正因为如此,模板文件就必须放在WEB-INF中
        //设置前缀后缀,让模板引擎知道要加载哪些文件到内存中,以备后用
        resolver.setPrefix("/WEB-INF/template/");
        resolver.setSuffix(".html");
        resolver.setCharacterEncoding("utf-8");
        //把解析器对象,设置到engine中
        engine.setTemplateResolver(resolver);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //初始化之后,就要执行模板渲染了
        //1.先从参数中读取出用户要传过来的message的值
        String message = req.getParameter("message");
        //2.把当前请求中读取出来的message的值和模板中的${message}关联起来
        WebContext webContext = new WebContext(req,resp,this.getServletContext());
        webContext.setVariable("message",message);
        //3.进行最终渲染,将webContext的内容替换到hello
        String html = engine.process("hello",webContext);
        System.out.println(html);
        resp.getWriter().write(html);
    }
}

部署程序

可以看到

Thymeleaf模板语法

设置标签文本

th:text 的功能就是能设置标签的文本内容.

设置标签属性

一些常用的需要设置的属性:href src class style ......

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

条件判断

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

<div th:if="${!newGame}">
    <div>已经猜了: <span th:text="${count}"></span> 次</div>
    <div>结果: <span th:text="${result}"></span> </div>
</div>

循环

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

在java代码中就是用类存储person,用list存储presons

<ul>
    <li th:each="person : ${persons}">
        <span th:text="${person.name}"></span>
        <span th:text="${person.phone}"></span>
    </li>
</ul>

查看模板语法的报错信息

通过形如下面的代码来渲染模板, 如果模板渲染出错, 能看到服务器返回了 500 状态码, 但是看不到异常调用栈.

engine.process("thymeleafEach", webContext, resp.getWriter());

原因是抛出的异常被 process 内部处理掉了.

可以使用以下代码代替, 即可看到异常调用栈.

String html = engine.process("thymeleafEach", webContext);
resp.getWriter().write(html);

只创建一个引擎实例

什么是ServletContext

是为了让webapp的多个Servlet之间能够共享数据

先访问writer,给message写数据

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

//负责像ServletContext里面写数据
//例如通过/writer?message=aaa访问到WriterServlet,就把message=aaa这个键值对存到ServletContext
@WebServlet("/writer")
public class WriterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        //1.从请求中获取到message参数
        String message = req.getParameter("message");
        //2.取出ServletContext对象(这个对象是Tomcat在加载webapp的时候自动创建的)
        ServletContext context = this.getServletContext();
        //3.往这里写入键值对
        context.setAttribute("message",message);
        //4.返回响应
        resp.getWriter().write("<h3>存储message成功</h3>");
    }
}

再访问reader,就能拿到message的数据

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

//使用Servlet从ServletContext中读取数据
//从WriterServlet里面存的数据中取出来
@WebServlet("/reader")
public class ReaderServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        //1.获取到同一个ServletContext对象
        ServletContext context = this.getServletContext();
        //2.从Context中获取到刚才存的值
        String message = (String) context.getAttribute("message");
        //3.把取出的数据显示出来
        resp.getWriter().write("message: " + message);
    }
}

什么是监听器Listener

可以看到,刚才的两个类中的ServletContext对象是同一个,所以我们需要使用ServletContext来存储一个TemplateEngine对象,达到让当前webapp的所有Servlet共同使用同一个TemplateEngine。

就可以再ServletContext创建好之后,第一时间给TemplateEngine进行初始化,为了达到这一目的,Servlet给我们提供了一个机制,Listener监听器,因此就可以使用Listener来监听ServletContext的初始化完毕操作

Servlet 中的监听器种类有很多:

监听 HttpSession 的创建销毁, 属性变化

监听 HttpServletRequest 的创建销毁, 属性变化

监听 ServletContext 的创建销毁, 属性变化

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

涉及到的接口: ServletContextListener

我们实现这个接口, 并重写其中的 servletContextInitialized 方法. 当 ServletContext 创建的时候就会自动执行到 servletContextInitialized 方法

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

//需要让Tomcat识别这个类,所以要加WebListener这个注解
@WebListener
public class MyListener implements ServletContextListener {
    //初始化完毕后会执行这个方法
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ServletContext初始化");
        //获取一下ServletContext对象,通过方法和参数获取到的
        ServletContext context = sce.getServletContext();
        context.setAttribute("message","初始化的消息");
    }
    //销毁之前执行这个方法
    @Override
    public void contextDestroyed(ServletContextEvent sce) {

    }
}

效果

修改Thymeleaf引擎初始化代码

import org.thymeleaf.TemplateEngine;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class ThymeleafConfig implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //初始化TemplateEngine
        ServletContext context = sce.getServletContext();
        //1.创建engine实例
        TemplateEngine engine = new TemplateEngine();
        //2.创建resolver实例
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(context);
        resolver.setPrefix("/WEB-INF/template/");
        resolver.setSuffix(".html");
        resolver.setCharacterEncoding("utf-8");
        engine.setTemplateResolver(resolver);
        //3.把创建好的engine实例放到ServletContext中
        context.setAttribute("engine",engine);
        System.out.println("TemplateEngine初始化");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {

    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值