一、什么是模板引擎?
jdbc预编译的操作命令对象,类似模板引擎:
select * from emp where id=?
这里的?就是占位符 这整个就相当于模板
preparedStatement.setInt(1,123)
1表示第几个占位符 123表示替换的值 模板和替换的值一起就组织为一个拼接的数据库可以执行的sql select * from emp where id=123
作用:
- 通过组织网页模板和数据,就可以返回一个动态的网页
- 可以分离Servlet Java代码和HTML网页代码(相对于Servlet直接返回动态网页来说,模板引擎的优点)
网页模板引擎产品有很多:freemarker、velocity、thymeleaf(springboot官方默认的模板技术)
二、流程
三、Thymeleaf使用流程
1.通过maven引入依赖
在maven中央仓库搜索Thymeleaf 选择一个合适的版本,例如3.0.12:
<!-- https:
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.12.RELEASE</version>
</dependency>
2.创建html版本文件
创建hello.html, 放到 webapps/WEB-INF/templates 目录中
<h3>网页模板技术学习</h3>
<p th:text="${message}"></p>
th:text 是 Thymeleaf 的语法. 浏览器不能直接识别 th:text 属性.
3.编写Servlet代码
先创建模板引擎和模板解析器
TemplateEngine engine = new TemplateEngine();
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(getServletContext());
resolver.setCharacterEncoding("utf-8");
resolver.setPrefix("/WEB-INF/templates/");
resolver.setSuffix(".html");
engine.setTemplateResolver(resolver);
再设置数据和模板名称
WebContext webContext = new WebContext(req,resp,getServletContext());
webContext.setVariable("message",req.getParameter("msg"));
String html = engine.process("hello",webContext);
最后把渲染的html设置到响应正文
resp.getWriter().write(html);
四、Thymeleaf模板语法
命令 | 功能 |
---|
th:text | 在标签中展示表达式求值结果的文本内容 | th:[HTML]标签属性 | 设置任意的HTML标签属性的值 | th:if | 当表达式的结果为真时则显示内容,否则不显示 | th:each | 循环访问元素 |
$ {变量名}来引用Java代码中,设置的键值对数据(${键}就是值)
最终是把webContext设置的键值对数据中,键为message的值,设置到标签内容中
1.设置标签属性
一些常用的需要设置的属性
1.设置a标签的href属性:
前端代码:
<a th:href="${a1}">搜狗</a> <!-- 渲染为<a href="键为a1的值" -->
<a th:href="${a2}">百度</a>
后端代码:
webContext.setVariable("a1","http://www.sogou.com");
webContext.setVariable("a2","http://www.baidu.com");
2.条件判断:
前端代码:
<p th:if="${isLogin}">已经登录了</p>
后端代码:
webContext.setVariable("isLogin",true);
true时,html中会包含< p > false时,html中不包含< p >
3.循环:
th:each的功能就是可以循环的构造出多个元素 语法格式为:
th:each=“自定义的元素变量名称:${集合变量名称}”
简单直接遍历 前端代码: 后端代码:
webContext.setVariable("names", Arrays.asList("张三","李四","王五"));
对User类进行访问:
五、只创建一个引擎实例
关于创建模板引擎和模板解析器 整个web应用,只需要初始化一次(代码中的对象engine、resolver,只需要创建一次)
原因:对象及属性不会改变 改造:放在Servlet的init方法
Servlet有三个生命周期方法:
- init:初始化方法,只执行一次。tomcat在某个时间会创建Servlet对象,然后调用init方法
- service:请求路径如果匹配到某个Servlet,就调用一次该Servlet的service方法
- destory:销毁方法,只执行一次
还存在问题:每个Servlet都需要在init方法中创建(一个webapp中,还是有多个engine,resolver对象) 解决这个问题:ServletContext、ServletContextListener
1.什么是ServletContext?
上下文/环境,常用于设置一些数据到上下文环境中 上下文环境中的对象,就可以互相引用对方的数据
很多地方都有Context这样的概念,他是一个语义上的概念 多个servlet间,无法直接传递数据,但可以通过共享的一个上下文环境,来设置/使用一些数据(数据传递)
ServletContext对象的重要方法:
方法 | 描述 |
---|
void setAttribute(String name,Object obj) | 设置属性(键值对) | Object getAttribute(String name) | 根据属性名获取属性值,如果name不存在,返回null | Object removeAttribute(String name) | 删除对应的属性 |
ServletContext类似Map结构,存放多组键值对的数据
代码示例:多个Servlet共享数据
@WebServlet("/write")
public class ContextWriteServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String data = req.getParameter("data");
ServletContext sc = getServletContext();
sc.setAttribute("d",data);
resp.setContentType("text/html; charset=utf-8");
resp.getWriter().write("写入Context成功");
}
}
@WebServlet("/read")
public class ContextReadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext sc = getServletContext();
Object data = sc.getAttribute("d");
resp.setContentType("text/html; charset=utf-8");
resp.getWriter().write("读取Context:"+data);
}
}
2.什么是监听器(Listener)
监听器,属于一种设计模式 如html中,标签中的事件——如< button onclick > 这个事件,其实就是监听器的设计模式
在html或js中,为一个dom元素,绑定一个事件(事件注册),不需要手动调用该事件的函数,而是在事件发生的时候,由浏览器来调用事件绑定的函数 这样事件发生需要执行的代码,和事件发生,两个就解耦
ServletContextListener,也是类似的一种监听器的设计。不要在事件发生的时候,自己写代码做事情,而是先注册一个函数/方法到监听器中,在某个事件发生后,就会自动执行
代码示例:监听ServletContext的创建
@WebListener
public class MyListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext 创建");
ServletContext context = sce.getServletContext();
context.setAttribute("message", "message 的初始值");
}
public void contextDestroyed(ServletContextEvent sce) {
}
}
|