持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第24天,点击查看活动详情
Thymeleaf
Thymeleaf视图模板技术
物理视图
在Servlet中,将请求转发到一个HTML页面文件时,使用的完整的转发路径就是物理视图。
/pages/user/login_success.html
如果我们把所有的HTML页面都放在某个统一的目录下,那么转发地址就会呈现出明显的规律:
/pages/user/login.html
/pages/user/login_success.html
/pages/user/regist.html
/pages/user/regist_success.html
……
路径的开头都是:/pages/user/
路径的结尾都是:.html
所以,路径开头的部分我们称之为视图前缀,路径结尾的部分我们称之为视图后缀。
逻辑视图
物理视图=视图前缀+逻辑视图+视图后缀
上面的例子中:
| 视图前缀 | 逻辑视图 | 视图后缀 | 物理视图 |
|---|---|---|---|
| /pages/user/ | login | .html | /pages/user/login.html |
| /pages/user/ | login_success | .html | /pages/user/login_success.html |
服务端引入Thymeleaf
- 引入jar包
2、新建一个Servlet类ViewBaseServlet
package com.sentiment.myssm.myspringmvc;
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配置文件设置物理逻辑视图
<!-- 在上下文参数中配置视图前缀和视图后缀 -->
<context-param>
<param-name>view-prefix</param-name>
<param-value>/</param-value>
</context-param>
<context-param>
<param-name>view-suffix</param-name>
<param-value>.html</param-value>
</context-param>
4、将我们使用的Servlet继承与ViewBaseServlet
@WebServlet("/index")
public class IndexServlet extends ViewBaseServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
FruitDao fruitDao = new FruitDaoImpl();
List<Fruit> fruitList = fruitDao.getFruitList();
HttpSession session = req.getSession();
session.setAttribute("fruitList",fruitList);
super.processTemplate("index",req,resp);
}
}
5、super.processTemplate("index",req,resp);
此时访问index目录,则会回显index.html的信息
Servlet保存作用域
原始情况下,保存作用域我们可以认为有四个:
- page(页面级别,现在几乎不用)
- request(一次请求响应范围)
- session(一次会话范围有效)
- application(一次应用范围有效)
request
demo01
// 演示request保存作用域(demo01和demo02)
@WebServlet("/demo01")
public class ServletDemo01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1、向request保存作用域 保存数据
req.setAttribute("uname","Sentiment");
//2、客户端重定向
//resp.sendRedirect("demo02");
//3、服务端转发
req.getRequestDispatcher("demo02").forward(req,resp);
}
}
demo02
@WebServlet("/demo02")
public class ServletDemo02 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object uname = req.getAttribute("uname");
System.out.println(uname);
}
}
由于是request方式,只有在一次响应范围内才能获取到相应的数据,所以当时用重定向时就相当于访问了demo01,之后重定向到了demo02,此时就相当于页面再次请求到了demo02,所以在ServletDemo02输出的uname值为null
而当使用服务端转发的方式,其实就是通过一次demo01的请求,在内部转发到了demo02,所以一次请求内有效输出Sentiment
session
demo03
// 演示session保存作用域(demo03和demo04)
@WebServlet("/demo03")
public class ServletDemo03 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1、向request保存作用域 保存数据
req.getSession().setAttribute("uname","Sentiment");
//2、客户端重定向
resp.sendRedirect("demo04");
//3、服务端转发
//req.getRequestDispatcher("demo04").forward(req,resp);
}
}
demo04
@WebServlet("/demo04")
public class ServletDemo04 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object uname = req.getSession().getAttribute("uname");
System.out.println(uname);
}
}
Seesion方式是一次会话内有效,所以不论是客户端重定向还是端口转发都是在一次会话内,所以当访问demo03,便会输出Sentiment
但此时如果换浏览器之后,再去访问demo04,则会返回null,因为不在同一会话内
application
demo05
// 演示application保存作用域(demo05和demo06)
@WebServlet("/demo05")
public class ServletDemo05 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1、向application保存作用域 保存数据
//ServletContext:Servlet上下文
ServletContext applicatioin = req.getServletContext();
applicatioin.setAttribute("uname","Sentiemnt");
//2、客户端重定向
resp.sendRedirect("demo06");
//3、服务端转发
//req.getRequestDispatcher("demo06").forward(req,resp);
}
}
demo06
@WebServlet("/demo06")
public class ServletDemo06 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object uname = req.getSession().getServletContext().getAttribute("uname");
System.out.println(uname);
}
}
application一次应用范围有效,所以无论何种方式,只要不重启服务,则都会获取到uname