Servlet保存作用域

115 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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

  1. 引入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