Thymeleaf入门

在HTML页面上,加载Java内存中的数据的过程我们称为渲染(render);thymeleaf是用来帮助视图渲染的技术。

使用步骤

添加thymeleaf的jar包

<img src="assets/image-20230415132407185.png" alt="image-20230415132407185" style="zoom:50%;" />

配置web.xml

    <context-param>
        <param-name>view-prefix</param-name><!--前缀-->
        <param-value>/WEB-INF/view/</param-value><!---->
    </context-param>
    <context-param>
        <param-name>view-suffix</param-name><!--后缀-->
        <param-value>.html</param-value>
    </context-param>

新建ViewBaseServlet类

package cn.yanqi.web;

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

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

public class ViewBaseServlet extends HttpServlet {
 
    private TemplateEngine templateEngine;
 
    @Override
    public void init() throws ServletException {
 
        // 1.获取ServletContext对象
        ServletContext servletContext = this.getServletContext();
 
        // 2.创建Thymeleaf解析器对象
        ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);
 
        // 3.给解析器对象设置参数
        // ①HTML是默认模式,明确设置是为了代码更容易理解
        templateResolver.setTemplateMode(TemplateMode.HTML);
 
        // ②设置前缀
        String viewPrefix = servletContext.getInitParameter("view-prefix");
 
        templateResolver.setPrefix(viewPrefix);
 
        // ③设置后缀
        String viewSuffix = servletContext.getInitParameter("view-suffix");
 
        templateResolver.setSuffix(viewSuffix);
 
        // ④设置缓存过期时间(毫秒)
        templateResolver.setCacheTTLMs(60000L);
 
        // ⑤设置是否缓存
        templateResolver.setCacheable(true);
 
        // ⑥设置服务器端编码方式
        templateResolver.setCharacterEncoding("utf-8");
 
        // 4.创建模板引擎对象
        templateEngine = new TemplateEngine();
 
        // 5.给模板引擎对象设置模板解析器
        templateEngine.setTemplateResolver(templateResolver);
 
    }
 
    protected void processTemplate(String templateName, HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 1.设置响应体内容类型和字符集
        resp.setContentType("text/html;charset=UTF-8");
 
        // 2.创建WebContext对象
        WebContext webContext = new WebContext(req,resp,getServletContext());

        // 3.处理模板数据
        templateEngine.process(templateName, webContext, resp.getWriter());
    }
}

ViewBaseServlet类的init方法会读取view-prefix和view-suffix

processTemplate(String templateName,HttpServletRequest request,HttpServletRespond respond)方法会将逻辑视图名称对应到物理视图名称上去,并且完成渲染和跳转。

逻辑视图名称:index

物理视图名称:前缀+逻辑视图名称+后缀

测引入连接

变量

@WebServlet("/listuser")
public class IndexServlet extends ViewBaseServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        req.setAttribute("name","jack");
        super.processTemplate("index",req,resp);     //将thymeleaf渲染到/index.html
    }
}
<!--引入thymeleaf,避免编辑器校验出现的错误,并非必须的,不引入也是正常运行的  -->
<html xmlns:th = "http://www.thymeleaf.org">
    
<span th:text="${name}"></span>
    
<!-- 拼接取值 jack你好啊  -->
<span th:text="${name}+你好啊"></span>
<span th:text="|${name}你好啊|"></span>

IDEA对thymeleaf有严格的校验,写完后会报红线,我们通过IDEA设置取消校验即可

image-20230505093224047

对象变量

@WebServlet("/listuser")
public class IndexServlet extends ViewBaseServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        User user = new User();
        user.setId(11);
        user.setUsername("jakc");
        user.setNickname("杰克");
        user.setPassworld("123");
        req.setAttribute("user",user);
        super.processTemplate("index",req,resp);     //将thymeleaf渲染到/index.html
    }
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>
id: <span th:text="${user.id}"></span>
name: <span th:text="${user.username}"></span>
nickname: <span th:text="${user.nickname}"></span>
nickname: <span th:text="${user.nickname}"></span>

</body>
</html>

集合变量

@WebServlet("/listuser")
public class IndexServlet extends ViewBaseServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        User user = new User();
        user.setId(11);
        user.setUsername("jakc");
        user.setNickname("杰克");
        user.setPassworld("123");

        User user2 = new User();
        user2.setId(22);
        user2.setUsername("jakc2");
        user2.setNickname("杰克2");
        user2.setPassworld("1232");

        List<User> list = new ArrayList<>();
        list.add(user);
        list.add(user2);

        req.setAttribute("list",list);
        super.processTemplate("index",req,resp);     //将thymeleaf渲染到/index.html
    }
}
<!--th:each="user:" 表示一个变量-->
<tr th:each="user:${list}">
    <td th:text="${user.id}"></td>
    <td th:text="${user.username}"></td>
    <td th:text="${user.nickname}"></td>
    <td th:text="${user.passworld}"></td>
</tr>

获取value值

@WebServlet("/listuser")
public class IndexServlet extends ViewBaseServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        User user = new User();
        user.setUsername("rose");
        user.setNickname("肉丝");

        req.setAttribute("user",user);
        super.processTemplate("index",req,resp);     //将thymeleaf渲染到/index.html
    }
}
<form action="#" method="post">
    <input type="text" name="username" th:value="${user.username}">
    <input type="text" name="nickname" th:value="${user.nickname}">
    <input type="submit">
</form>

获取session值

@WebServlet("/listuser")
public class IndexServlet extends ViewBaseServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        HttpSession session = req.getSession();
        session.setAttribute("str","jack");
        req.setAttribute("sex","男");

        super.processTemplate("index",req,resp);     //将thymeleaf渲染到/index.html
    }
}
<!--#对象.方法(参数)-->
<span th:text="${session.str}"></span>
<span th:text="${sex}"></span>

IF判断

@WebServlet("/listuser")
public class IndexServlet extends ViewBaseServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        User user = new User();
        user.setUsername("b");

        req.setAttribute("user",user);
        super.processTemplate("index",req,resp);     //将thymeleaf渲染到/index.html
    }
}
<div th:if="${user.username}=='a'">
    管理员
</div>
<div th:unless="${user.username}=='a'">
    普通用户
</div>

引入连接

<img src="assets/image-20230414191107729.png" alt="image-20230414191107729" style="zoom:50%;" />

@WebServlet("/listuser")
public class IndexServlet extends ViewBaseServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        super.processTemplate("index",req,resp);     //将thymeleaf渲染到/index.html
    }
}
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <!--th:href="@{/css/101.css} 引入连接-->
    <link rel="stylesheet" type="text/css" media="all" th:href="@{/css/101.css}" />
</head>
<body>

<div></div>

</body>
div{
    width: 300px;
    height: 300px;
    background-color: green;
}

内联表达式

@WebServlet("/listuser")
public class IndexServlet extends ViewBaseServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setAttribute("msg","小可爱");

        super.processTemplate("index",req,resp);     //将thymeleaf渲染到/index.html
    }
}
<span th:text="${msg}"></span>   <!--小可爱-->   
<span>[[${msg}]]</span>   <!--小可爱-->
<!--以上两种方式一样,直接取value值 -->

<!--[(${value})] 按照 html标签取值 -->
<span>[(${msg})]</span> 

传参数

@WebServlet("/TestHello4")
public class TestHello4 extends  ViewBaseServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        User user = new User();
        user.setId(22);
        user.setUsername("jack");

        req.setAttribute("user",user);

        super.processTemplate("hello4",req,resp);
    }
}

<body>
      <a rel="nofollow" th:href="@{/updateUser(id=${user.id},name=${user.username})}">更新</a>
</body>
@WebServlet("/updateUser")
public class updateUser extends  ViewBaseServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String id = req.getParameter("id");
        String name = req.getParameter("name");

        System.out.println(id);
        System.out.println(name);
    }
}

获取map集合值

@WebServlet("/listuser")
public class IndexServlet extends ViewBaseServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        Map<String, String> map = new HashMap<>();
        map.put("name", "jack");
        map.put("age", "23");

        req.setAttribute("map",map);

        super.processTemplate("index",req,resp);     //将thymeleaf渲染到/index.html
    }

}
<body>

    <tr th:each="entry : ${map}">
        <td th:text="${entry.key}"></td>
        <td th:text="${entry.value}"></td>
    </tr>

</body>

如果value是数组用:${map.get('key')[index]} 表示取的key的第index个value值

@WebServlet("/listuser")
public class IndexServlet extends ViewBaseServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        Map<String, String[]> map = new HashMap<>();
        String[] value = {"jack","rose"};
        map.put("name", value);

        req.setAttribute("m",map);

        super.processTemplate("index",req,resp);     //将thymeleaf渲染到/index.html
    }

}
<body>

    <p th:text="${m.get('name')[0]}"></p>

</body>