1、添加thymeleaf的jar包:
attoparser-2.0.5.RELEASE.jar
javassist-3.20.0-GA.jar
log4j-1.2.15.jar
ognl-3.1.26.jar
slf4j-api-1.7.25.jar
slf4j-log4j12-1.7.25.jar
thymeleaf-3.0.12.RELEASE.jar
unbescape-1.1.6.RELEASE.jar
2、 新建一个Servlet类 例如:ViewBaseServlet
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());
}
}
3、 在web.xml文件中添加配置
配置前缀 view-prefix
<context-param>
<param-name>view-prefix</param-name>
<param-value>/</param-value>
</context-param>
置后缀 view-suffix
<context-param>
<param-name>view-suffix</param-name>
<param-value>.html</param-value>
</context-param>
4、 使得我们的Servlet继承ViewBaseServlet
5、根据逻辑视图名称 得到 物理视图名称
//此处的视图名称是 index
//那么thymeleaf会将这个 逻辑视图名称 对应到 物理视图 名称上去
//逻辑视图名称 : index
//物理视图名称 : view-prefix + 逻辑视图名称 + view-suffix
//所以真实的视图名称是: / index .html
super.processTemplate("index",request,response);
6、在html文件中使用thymeleaf的标签
1)操作请求域
request:作用一次请求范围
session:作用于一次会话范围
application:作用于一次应用程序范围
2)操作会话域
th:if , th:unless , 类似于if-else
<tr th:if="${#lists.isEmpty(session.fruitList)}">
语句中的lists是thymeleaf中判断集合相关的对象,isEmoty(object)判断object是否为空,为空则执行;session表示从session作用域取出集合数据fruitList,配合下面的代码
//保存到session作用域
HttpSession session = request.getSession() ;
session.setAttribute("fruitList",fruitList);
下面语句中th:unless="${#lists.isEmpty(session.fruitList)}表示如果不为空则th:each迭代lists集合(session.fruitList),fruit是遍历集合(session.fruitList)的临时变量
<tr th:unless="${#lists.isEmpty(session.fruitList)}" th:each="fruit : ${session.fruitList}">
下面代码中 th:text="${fruit.fname}"中text设置td语句中的文本(替换苹果)
<td th:text="${fruit.fname}">苹果</td>
2)添加超链接
下面代码给fruit.fname添加超链接,点击fruit.fname(如苹果)时,向与'/deit.do'对应的servlet(class类)发送请求,同时页面进行跳转,进入与servlett(class类)对应的html页面
<!--方式一:拼接字符串 -->:
<td><a th:text="${fruit.fname}" href="@{'/edit.do?fid='+${fruit.fid}}">苹果</a></td>
<!--方式二:用括号给键值对赋值-->
<td><a th:text="${fruit.fname}" href="@{/edit.do(fid=${fruit.fid})}">苹果</a></td>
3)路径问题
方式一:相对路径
<link href="../文件名/" >
上述代码中href表示路径,其中..表示返回上级目录。
方式二:绝对路径
< base href="http://localhost:8080/" />
<!-- 等级于 -->
<link th:href="@{/路径}" >
上述代码表示当前页面的所有路径都以这个为基础,其中@{}相当于http://localhost:8080/
4)自定义变量解决前缀问题
当数据量比较多的时候,频繁的写变量名.(例如fruit.)就会非常麻烦。
Thymeleaf提供了自定义变量来解决:
<h2 th:object="${fruit}">
<p>Name: <span th:text="*{fname}">J苹果</span>.</p>
<p>price: <span th:text="*{price}">5</span>.</p>
<p>fcount: <span th:text="*{fcount}">20</span>.</p>
</h2>
上述代码中h2上 用 th:object="${fruit}"获取fruit的值,并且保存,然后,在h2内部的任意元素上,可以通过‘ *{属性名}’的方式,来获取fruit中的属性,这样就省去了大量的fruit.
前缀了
5)隐藏域
<!-- 隐藏域 : 功能类似于文本框 , 它的值会随着表单的发送也会发送给服务器,但是界面上用户看不到 -->
<input type="hidden" name="fid" th:value="*{fid}"/>
上述代码可以用于把不让用户看到的信息通过表单发送给servlet,要将这段代码写在form表单内才有效,例如:
<form th:action="@{/update.do}" method="post" th:object="${fruit}">
<input type="hidden" name="fid" th:value="*{fid}"/>
</form>
6)onclick鼠标点击事件执行脚本
<td><img src="imgs/del.jpg" class="delImg" th:onclick="|delFruit(${fruit.fid})|"/></td>
上述代码的作用是,当鼠标点击del.jpg图片时,执行js文件中的delFruit(number)函数(如下),当检测到${fruit.fid}时,自动获取fruit的id填充delFruit(number)中的变量。
function delFruit(fid){
if(confirm('是否确认删除?')){
window.location.href='del.do?fid='+fid;
}
}
上述代码中,该函数表示发送请求‘/del.do’对应的servlet(class类),window表示当前的网页,location表示地址栏的对象(如http://localhost:8080/index),href表示给地址栏的对象附上/del.do?fid=变量(如http://localhost:8080/index/del.do?fid=2)
7)disabled:禁用
<input type="button" value="上一页" class="btn" th:onclick="|page(${session.pageNo -1})|" th:disabled="${session.pageNo==1}"/>
上述代码中,th:disabled="${session.pageNo==1}"是一个判断语句,当ession.pageNo等于1的时候(disabled='true'),按钮‘上一页’禁用。
8)前端获取不到数据库数据问题(前提代码逻辑等正确):
public void doGet(HttpServletRequest request , HttpServletResponse response)throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");//从前端页面传递过来的数据是乱码,从数据库查询不到,所以要设置编码
}
long类型强转为int型
((Long)super.executeComplexQuery("select count(*) from t_fruit")[0]).intValue();