注意
这里存在一个问题,在以下两个html网页中,均设了使用thymeleaf去动态的获取上下文路径,使其可以被服务器将上下文路径渲染进base标签里。index网页中故意写错base标签中的href属性值(/day07_Thymeleaf_war_exploded123/),希望原来的错误href属性值可以被渲染为正确的路径(/day07_Thymeleaf_war_exploded/)
代码如下所示:
//index.html <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <base href="/day07_Thymeleaf_war_exploded123/" th:href="@{/}"> <meta charset="UTF-8"> <title>Title</title> </head> <body> <a href="hello">访问HelloServlet</a> </body> </html>
//admin.html <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <!-- 使用Themeleaf动态获取上下文路径 --> <base href="" th:href="@{/}"> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>admin页面</h1> <h2 th:text="${msg}">这是服务器传过来的msg</h2> 输入: <input type="text" value="这是原始值" th:value="${msg}"><br> <a href=-""th:href="${msg}">a标签</a><br/> 上下文路径:<h2 th:text="@{/}"></h2> <!-- 传递参数 --> <a href="root?id=101&name=jack">Rootservlet01</a> <a th:href="@{/root(id=101,name='jack',age=20)}">RootServlet02</a> </body> </html>
代码运行后测试结果显示渲染失败
原因分析:
index.html中的base标签写入的是错误的项目路径,即无法从正确的项目路径去访问HelloServlet,自然也就不会别Thymeleaf所渲染
结论:
如果你的网页想使用thymeleaf的渲染表达式的话,就必须经过Servlet然后在经过Thymeleaf进行渲染才可以,在实际开发中项目内所有的网页都需要thymeleaf渲染(都需要过Servlet在过Thymeleaf模板引擎)
解决方案:
让index.html去过一遍servlet,将index.html移动至本地动态web项目下web/pages里,这样它可以Thymeleaf所识别,新增一个ToindexServlet,并同时在web-xml中设置访问ToindexServlet的路径
代码演示如下:
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 ToindexServlet extends ViewBaseServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.processTemplate("index",request,response); } }
在浏览器地址栏里键入 “http://localhost:8080/day07_Thymeleaf_war_exploded/index”,以get形式访问ToindexServlet,调用其doGet方法对index.html进行渲染
附注:
在上述代码不变的前提下,你在web.xml中修改访问ToindexServlet的路径为"/index.abc" or “/index.html” 。这种写法在web.xml中没有语法问题,但是你在浏览器网址栏输入
http://localhost:8080/day07_Thymeleaf_war_exploded/index.html
时才可以访问到index.html,看似是在项目路径下直接找的index.html,实则不然,这是项目路径下键入访问ToindexServlet的路径,由它再过Thymeleaf渲染Index.html,然后再呈现在浏览器中供客户观看
7.5 获得域对象中的数据
7.5.1 获取应用域对象中的数据
语法:
ServletContext application(一般取别名为application)
${appliaction.应用域中的key值)
示例代码如下:
//在HelloServlet中设置应用域的数据 ServletContext application = request.getServletContext(); application.setAttribute("applicationMsg","这是应用域中的applicationMsg数据");
//在admin.html中设置 <!-- 从应用域中获取applicationMsg给admin渲染 --> <p th:text="${application.applicationMsg}"></p>
注意:
${appliaction.应用域中的key值)中的application和ServletContext对象的别名没有丝毫关系,它是写死的,无论ServletContext对象的别名叫什么。
7.5.2 获取会话域对象中的数据(Httpsession session)
语法:
${session.会话域中的key值}
7.5.3 获取请求域对象中的数据(HttpservletRequest request)
语法:
${请求域中的key}
ps:详细应用在上述的章节内容已有展示,故不作涉及
7.6 获得请求参数
语法:
${param.请求参数的key值)
7.6.1 根据一个参数名获取一个参数值
案例:根据在index.html里访问adminServlet的超链接添加i请求参数,由adminServlet传给thymeleaf渲染admin.html并响应给客户端,admin.html可以获取请求参数并显示
示例代码如下:
//在index.html中访问adminServlet的超链接中添加请求参数 <a href="admin?id=101&name=jack">访问adminServlet</a>
//在adminServlet中获取请求参数并让thymeleaf渲染admin.html,响应给浏览器 String id = request.getParameter("id"); System.out.println("id="+id); String name = request.getParameter("name"); System.out.println("name="+name); //调用Thymeleaf渲染admin.html并响应给客户端 this.processTemplate("admin",request,response);
<!-- admin.html获取请求参数 --> 获取请求参数: <p th:text="${param.id}"></p> <p th:text="${param.name}"></p>
7.6.2 根据一个参数名获取多个参数值
案例:根据在index.html里访问adminServlet的超链接添加i请求参数(同一个参数有多个残数值),由adminServlet传给thymeleaf渲染admin.html并响应给客户端,admin.html获取请求参数并显示
示例代码如下:
//在index.html中访问adminServlet的超链接中添加请求参数(同一个参数名有多个参数值) <a href="admin?hobbys=basketball&hobbys=run&hobbys=rap">访问adminServlet</a>
//在adminServlet中获取一个参数名获取多个参数值,让thymeleaf渲染admin.html,响应给浏览器看 String[] hobbys = request.getParameterValues("hobbys"); System.out.println(Arrays.toString(hobbys));
<!-- 在admin.html中获取一个参数名获取多个参数值 ---> <p th:text="${param.hobbys}"></p> <!-- 获取参数hobbys第一个参数值 --> <p th:text="${param.hobbys[0]}"></p> <!-- 获取参数hobbys第二个参数值 --> <p th:text="${param.hobbys[1]}"></p> <!-- 获取参数hobbys第三个参数值 --> <p th:text="${param.hobbys[2]}"></p>
7.7 内置对象
释义:
可以直接使用的对象
7.7.1 基本内置对象
常用基本内置对象:
#request
:就是Servlet中的HttpServletRequest对象
#response
: 就是Servlet中的HttpServletResponse对象
#session
:就是Servlet中的Httpsession对象
#servletContext
: 就是Servlet中的ServletContext对象
案例:获取基本内置对象request的主机名
代码示例如下:
<!-- 获取基本内置对象request的主机名 --> <p th:text="${#request.getServerName()}"></p> <!-- 获取request的上下文路径 --> <p th:text="${#request.getContextPath()}"></p> .....
7.7.2 公共内置对象
#strings
:提供了很多对字符串操作的方法
#arrays
:提供了操作数组的常用方法
#lists
:提供了操作List集合的捞用方法
#sets
:提供了操作set集合的常用方法
#maps
:提供了操作Map集合的常用方法
案例:演示#strings,#arrays,#lists等部分常用公共内置对象的部分常用方法
//在请求域中添加一个数据(数组) String[] names={"java","python","lua"}; request.setAttribute("names",names); //在请求域中添加一个数据(list集合) List<String> list=new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); request.setAttribute("list",list); //调用Thymeleaf渲染root.html并响应给客户端 this.processTemplate("root",request,response);
<!--Arrays中的方法:--> <p>Arrays中的方法:</p> <p th:text="${#arrays.length(names)}"></p> <p th:text="${#arrays.contains(names,'java')}"></p> <!--List中的方法:--> <p>list中的方法:</p> <p th:text="${#lists.size(list)}"></p> <p th:text="${#lists.isEmpty(list)}"></p>
7.8 OGNL( 对象-图导航语言)
对象-图的概念:
从根对象触发,通过特定的语法,逐层访问对象的各种属性。
简而言之:
就是将复杂的对象或者集合放在域对象内,Thymeleaf去获取这些数据在网页渲染
7.8.1 简单对象
案例:请求域内共享简单对象employee,rootServlet调用Thymeleaf渲染root.html并响应给客户端,root.html要显示动态数据(请求域内的简单对象employee)
代码示例如下:
//在rootServle中创建一个employee对象 Employee employee=new Employee(101,"张三",0,7800.0); //请求域内共享一个简单对象 request.setAttribute("emp",employee); //调用Thymeleaf渲染root.html并响应给客户端 this.processTemplate("root",request,response);
<p>简单对象:</p> //emp整个对象 <p th:text="${emp}"></p> //拿到对象emp内getId方法的返回值,下同 <p th:text="${emp.id}"></p> <p th:text="${emp,name}"></p> <p th:text="${emp.gender}"></p> <p th:text="${emp.salary}"></p> <p th:text="${emp.value}"></p>