JavaWeb-Thymeleaf/作用域

目录

一、引入

 二、视图

三、创建Servlet基类(使用框架前)

 四、基本语法-表达式语法

4.1 修改文本标签值 th:text

4.2 修改指定属性值

4.3 解析URL地址

五、基本语法-访问域对象

5.1 域对象

5.1.1 请求域

5.1.2 会话域

5.1.3 应用域

5.2 将数据存到域中

5.2.1 操作请求域

5.2.2 操作会话域

5.2.3 操作应用域

六、获取请求参数

 6.1 一个名字一个值

6.2 一个名字多个值

七、基本语法-内置对象

7.1 基本内置对象

7.2 公共内置对象

7.3 对象访问

八、分支与迭代结构

8.1 分支 th:if th:unless / th:switch th:case

8.1.1 if与unless/not

8.1.2 th:switch

8.2 迭代 th:each

九、包含其他模板文件

9.1 创建页面代码片段

9.2 包含到其他页面


一、引入

        MVC概念:

                M:Model模型

                V:View视图

                C:Controller控制器

        MVC是在表述层开发中运用的一种设计理念。主张把封装数据的『模型』、显示用户界面的『视图』、协调调度的『控制器』分开。

         服务器端渲染

        除了我们熟悉的JSP,还有Velocity、Freemarker、Thymeleaf等视图模板技术。虽然具体语法各不相同,但是它们都有一个共通的特点,就是在固定内容中可以穿插表达式等形式的动态内容。将视图模板中的动态内容转换为对应的Java代码并执行,然后使用计算得到的具体数据替换原来的动态部分。这样整个文件的动态内容就可以作为确定的响应结果返回给浏览器。

        如果我们直接访问index.html本身,那么index.html是不需要通过Servlet,当然也不经过模板引擎。通过Servlet访问index.html,这样就可以让模板引擎渲染页面,所有和业务功能相关的请求都能够确保它们通过Servlet来处理,这样就方便我们统一对这些请求进行特定规则的限定。

 二、视图

        在Servlet中,将请求转发到一个HTML页面文件时,使用的完整转发路径就是物理视图

         由于路径开头与结尾的部分通常比较固定,所以我们把开头的部分称之为视图前缀,路径结尾的部分我们称之为视图后缀

        物理视图=视图前缀+逻辑视图+视图后缀

         我们可以在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>

三、创建Servlet基类(使用框架前)

        使用框架后,这些代码都将被取代。复制粘贴即可:

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());
    }
}

        注:我们想使用Thymeleaf的话必须让自定义的Java类继承于刚才创建的基类

public class userServlet extends ViewBaseServlet{
    ... ...
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    ... ...
    // 调用ViewBaseServlet父类中的解析视图模板的方法
    super.processTemplate(tergetViewName, request, response);
    
}
}

        注:要在对应html文件中声明名称空间

<!-- 在html标签内加入Thymeleaf名称空间的声明 -->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
... ...

 四、基本语法-表达式语法

4.1 修改文本标签值 th:text

<p th:text="标签体新值">标签体原始值(写死的值)</p>

  th:text作用

  • 不经过服务器解析,直接用浏览器打开HTML文件,看到的是『标签体原始值
  • 经过服务器解析,Thymeleaf引擎根据th:text属性指定的『标签体新值』去替换『标签体原始值』
  • 我们在th:text属性中使用的就是『字面量』,它不指代任何其他值。

4.2 修改指定属性值

<input type="text" name="username" th:value="文本框新值" value="文本框旧值" />

        任何HTML标签原有的属性,前面加上『th:』就都可以通过Thymeleaf来设定新值

4.3 解析URL地址

<p th:text="@{/aaa/bbb/ccc}">标签体原始值</p>

         解析后得到:/view/aaa/bbb/ccc

        @{}的作用是在字符串前附加『上下文路径』

        这个语法的好处是:实际开发过程中,项目在不同环境部署时,Web应用的名字有可能发生变化。所以上下文路径不能写死。而通过@{}动态获取上下文路径 

<td th:href="@{/xxx}">       //也就是根目录/xxx
<form th:action="@{/xxx}">

        注:如果地址中想要拼接带 ${ }这样动态的内容,要使用 |  | 的格式,动态内容的$符号换成*,这会自动拼接:

<td img src="del.jpg" class="del" th:onclick="'delBtn(' +*{btnId}+ ')'"> //原始的格式
<td img src="del.jpg" class="del" th:onclick="|delBtn( *{btnId} )|">   // 推荐的格式

五、基本语法-访问域对象

5.1 域对象

5.1.1 请求域

        在请求转发的场景下,我们可以借助HttpServletRequest对象内部给我们提供的存储空间,帮助我们携带数据,把数据发送给转发目标资源

5.1.2 会话域

5.1.3 应用域

在我们使用的视图是JSP的时候,域对象有4个

  • pageContext
  • request:请求域          作用范围:一次请求的响应范围
  • session:会话域          作用范围:一次会话范围有效
  • application:应用域    作用范围:一次应用程序范围有效

所以在JSP的使用背景下,我们可以说域对象有4个,现在使用Thymeleaf了,没有pageContext。

5.2 将数据存到域中

5.2.1 操作请求域

        Servlet中代码:

String name=hello;
String value=521;
request.setAttribute(Name, Value);

        Thymeleaf表达式:

<div th:text="${name}">request field value</div>

5.2.2 操作会话域

        Servlet中代码:

// ①通过request对象获取session对象
HttpSession session = request.getSession();
// ②存入数据
session.setAttribute(name, value);

        Thymeleaf表达式:

<div th:text="${session.name}">这里显示会话域数据</div>

5.2.3 操作应用域

        Servlet中代码:

// ①通过调用父类的方法获取ServletContext对象
ServletContext servletContext = getServletContext();
// ②存入数据
servletContext.setAttribute(name, value);

        Thymeleaf表达式:

<div th:text="${application.name}">这里显示应用域数据</div>

六、获取请求参数

 6.1 一个名字一个值

        页面代码:

<p th:text="${param.username}">这里替换为请求参数的值</p>

        页面显示效果:

6.2 一个名字多个值

        页面代码:

<p th:text="${param.team}">这里替换为请求参数的值</p>

        页面显示效果:

        注:这个例子传入的类似于数组,我们可以用 team[i] 更精确地取单个值 

七、基本语法-内置对象

        所谓内置对象其实就是在表达式中可以直接使用对象

7.1 基本内置对象

#request

#response

#sesion

#servletContext

用法举例:

<h3>表达式的基本内置对象</h3>
<p th:text="${#request.getClass().getName()}">这里显示#request对象的全类名</p>
<p th:text="${#request.getContextPath()}">调用#request对象的getContextPath()方法</p>
<p th:text="${#request.getAttribute('hello')}">调用#request对象的getAttribute()方法

7.2 公共内置对象

#dates

#calenders

#numbers

#strings

#objects

#bools

#arrays

#lists

#sets

#maps

#ids

        Servlet中将List集合数据存入请求域:

request.setAttribute("NotEmptyList", Arrays.asList("aaa","bbb","ccc"));
request.setAttribute("EmptyList", new ArrayList<>());

        页面代码:

<p>#list对象isEmpty方法判断集合整体是否为空NotEmptyList:
<span th:text="${#lists.isEmpty(NotEmptyList)}">测试#lists</span>
</p>

<p>#list对象isEmpty方法判断集合整体是否为空EmptyList:
<span th:text="${#lists.isEmpty(EmptyList)}">测试#lists</span>
</p>

7.3 对象访问

  • 访问对象属性:使用getXxx()setXxx()方法定义的属性
    • 对象.属性名
  • 访问List集合数组
    • 集合或数组[下标]
  • 访问Map集合
    • Map集合.key
    • Map集合['key']

八、分支与迭代结构

8.1 分支 th:if th:unless / th:switch th:case

8.1.1 if与unless/not

        让标记了th:ifth:unless/not标签根据条件决定是否显示,not unless 效果一样。

        示例的实体类:

public class Employee {
    private Integer empId;
    private String empName;
    private Double empSalary;
}

        示例的Servlet代码:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    // 1.创建ArrayList对象并填充
    List<Employee> employeeList = new ArrayList<>();

    employeeList.add(new Employee(1, "tom", 500.00));
    employeeList.add(new Employee(2, "jerry", 600.00));
    employeeList.add(new Employee(3, "harry", 700.00));

    // 2.将集合数据存入请求域
    request.setAttribute("employeeList", employeeList);

    // 3.调用父类方法渲染视图
    super.processTemplate("list", request, response);
}

        示例的HTML代码:

<table>
    <tr>
        <th>员工编号</th>
        <th>员工姓名</th>
        <th>员工工资</th>
    </tr>
    <tr th:if="${#lists.isEmpty(employeeList)}">
        <td colspan="3">抱歉!没有查询到你搜索的数据!</td>
    </tr>
    <tr th:unless="${not #lists.isEmpty(employeeList)}">
        <td colspan="3">有数据!</td>
    </tr>
 
</table>

8.1.2 th:switch

<h3>测试switch</h3>
<div th:switch="${user.memberLevel}">
    <p th:case="level-1">银牌会员</p>
    <p th:case="level-2">金牌会员</p>
    <p th:case="level-3">白金会员</p>
    <p th:case="level-4">钻石会员</p>
</div>

8.2 迭代 th:each

<h3>测试each</h3>
<table>
    <thead>
        <tr>
            <th>员工编号</th>
            <th>员工姓名</th>
            <th>员工工资</th>
            <th>迭代状态</th>
        </tr>
    </thead>
    <tbody th:if="${#lists.isEmpty(employeeList)}">
        <tr>
            <td colspan="3">抱歉!没有查询到你搜索的数据!</td>
        </tr>
    </tbody>
    <tbody th:if="${not #lists.isEmpty(employeeList)}">
        <!-- 遍历出来的每一个元素的名字 : ${要遍历的集合} -->

        <tr th:each="employee,empStatus : ${employeeList}">
            
            <td th:text="${employee.empId}">empId</td>
            <td th:text="${employee.empName}">empName</td>
            <td th:text="${employee.empSalary}">empSalary</td>
            <td th:text="${empStatus.count}">count</td>
        </tr>
    </tbody>
</table>

        类似于Java的增强for循环  for(Object e  :list) / for(Object e1,Object e2  :list)

九、包含其他模板文件

9.1 创建页面代码片段

        使用 th:fragment 来给这个片段命名:

<div th:fragment="header">
    <p>被抽取出来的头部内容</p>
</div>

9.2 包含到其他页面

        页面代码举例:

<!-- 代码片段所在页面的逻辑视图 :: 代码片段的名称 -->
<div id="badBoy" th:insert="segment :: header">
    div标签的原始内容
</div>

<div id="worseBoy" th:replace="segment :: header">
    div标签的原始内容
</div>

<div id="worstBoy" th:include="segment :: header">
    div标签的原始内容
</div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值