Browse Source

1208 监听器和Thymeleaf

Demi 5 months ago
parent
commit
bee1c1ad1c

+ 6 - 0
tomcat-demo/pom.xml

@@ -46,6 +46,12 @@
             <version>8.0.33</version>
         </dependency>
 
+        <dependency>
+            <groupId>org.thymeleaf</groupId>
+            <artifactId>thymeleaf</artifactId>
+            <version>3.1.2.RELEASE</version>
+        </dependency>
+
         <dependency>
             <groupId>org.junit.jupiter</groupId>
             <artifactId>junit-jupiter-api</artifactId>

+ 42 - 0
tomcat-demo/src/main/java/com/sf/sysdemo/controller/IndexController.java

@@ -0,0 +1,42 @@
+package com.sf.sysdemo.controller;
+
+import jakarta.servlet.ServletContext;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.annotation.WebServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.thymeleaf.TemplateEngine;
+import org.thymeleaf.context.WebContext;
+import org.thymeleaf.web.servlet.IServletWebExchange;
+import org.thymeleaf.web.servlet.JakartaServletWebApplication;
+
+import java.io.IOException;
+import java.util.Random;
+
+@WebServlet("/index/*")
+public class IndexController extends BaseController {
+
+    // /index/welcome
+    public void welcome(HttpServletRequest req, HttpServletResponse resp)
+            throws ServletException, IOException {
+        ServletContext servletContext = req.getServletContext();
+        TemplateEngine engine = (TemplateEngine)servletContext.getAttribute("engine");
+        JakartaServletWebApplication application = (JakartaServletWebApplication)
+                servletContext.getAttribute("application");
+
+        resp.setCharacterEncoding("UTF-8");
+
+        Random random = new Random();
+        int nextInt = random.nextInt();
+        req.setAttribute("message", "Hello Thymeleaf " + nextInt);
+
+        // 使得这里的参数在页面中生效
+        // 交换器 也可以理解为一个处理器
+        IServletWebExchange webExchange = application.buildExchange(req, resp);
+        // 通过交换器 创建一个上下文环境
+        WebContext webContext = new WebContext(webExchange);
+        // 引擎可以帮助我们 将静态的页面和动态的数据 渲染成真正要返回的结果 写入到相应的输出流中
+//        engine.process("index.html", webContext, resp.getWriter());
+        engine.process("index", webContext, resp.getWriter());
+    }
+}

+ 35 - 0
tomcat-demo/src/main/java/com/sf/sysdemo/controller/ScheduleController.java

@@ -1,7 +1,42 @@
 package com.sf.sysdemo.controller;
 
+import jakarta.servlet.ServletContext;
+import jakarta.servlet.ServletException;
 import jakarta.servlet.annotation.WebServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpSession;
+import org.thymeleaf.TemplateEngine;
+import org.thymeleaf.context.WebContext;
+import org.thymeleaf.web.servlet.IServletWebExchange;
+import org.thymeleaf.web.servlet.JakartaServletWebApplication;
+
+import java.io.IOException;
+import java.util.Random;
 
 @WebServlet("/schedule/*")
 public class ScheduleController extends BaseController {
+
+    public void info(HttpServletRequest req, HttpServletResponse resp)
+            throws ServletException, IOException {
+        ServletContext servletContext = req.getServletContext();
+        TemplateEngine engine = (TemplateEngine)servletContext.getAttribute("engine");
+        JakartaServletWebApplication application = (JakartaServletWebApplication)
+                servletContext.getAttribute("application");
+
+        resp.setCharacterEncoding("UTF-8");
+
+        HttpSession session = req.getSession();
+        String username = (String)session.getAttribute("username");
+        req.setAttribute("message", "Hello " + username);
+
+        // 使得这里的参数在页面中生效
+        // 交换器 也可以理解为一个处理器
+        IServletWebExchange webExchange = application.buildExchange(req, resp);
+        // 通过交换器 创建一个上下文环境
+        WebContext webContext = new WebContext(webExchange);
+        // 引擎可以帮助我们 将静态的页面和动态的数据 渲染成真正要返回的结果 写入到相应的输出流中
+//        engine.process("index.html", webContext, resp.getWriter());
+        engine.process("index", webContext, resp.getWriter());
+    }
 }

+ 19 - 1
tomcat-demo/src/main/java/com/sf/sysdemo/controller/UserController.java

@@ -3,10 +3,13 @@ package com.sf.sysdemo.controller;
 import com.sf.sysdemo.entity.SysUser;
 import com.sf.sysdemo.service.SysUserService;
 import com.sf.sysdemo.service.impl.SysUserServiceImpl;
+import jakarta.servlet.RequestDispatcher;
 import jakarta.servlet.ServletException;
 import jakarta.servlet.annotation.WebServlet;
+import jakarta.servlet.http.Cookie;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpSession;
 
 import java.io.IOException;
 
@@ -54,7 +57,22 @@ public class UserController extends BaseController {
         } else if (!sysUser.getPassword().equals(password)) {
             resp.sendRedirect("/loginUserPwdError.html");
         } else {
-            resp.sendRedirect("/showSchedule.html");
+            // 在登录成功后 存入session 具体将什么数据存入session 取决于具体需求
+            HttpSession session = req.getSession();
+            session.setAttribute("username", username);
+//            session.setAttribute("user", sysUser);
+
+            // 在响应头中写入cookie
+            Cookie cookie = new Cookie("username", username);
+            // 增加了有效时间 生效路径
+            cookie.setMaxAge(60 * 60 * 24);
+            cookie.setPath("/showSchedule.html");
+            resp.addCookie(cookie);
+
+//            resp.sendRedirect("/showSchedule.html");
+            // 将原来的响应重定向 改成 请求转发
+            RequestDispatcher requestDispatcher = req.getRequestDispatcher("/schedule/info");
+            requestDispatcher.forward(req, resp);
         }
     }
 }

+ 49 - 0
tomcat-demo/src/main/java/com/sf/sysdemo/filter/LoginFilter.java

@@ -0,0 +1,49 @@
+package com.sf.sysdemo.filter;
+
+import jakarta.servlet.*;
+import jakarta.servlet.annotation.WebFilter;
+import jakarta.servlet.http.Cookie;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpSession;
+
+import java.io.IOException;
+
+// 当注解参数的类型 是数组时 可以只写一个元素 代表是唯一元素
+// 如果有多个元素 使用数组结构 {,,}
+@WebFilter(
+        urlPatterns = {"/schedule/*","/showSchedule.html"}
+)
+public class LoginFilter implements Filter {
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+        // 把ServletRequest 转为 Http
+        HttpServletRequest req = (HttpServletRequest) request;
+        HttpServletResponse resp = (HttpServletResponse) response;
+        // 如果登录成功 那么session中存在username  如果登录失败 那么session中没有username
+        HttpSession session = req.getSession();
+        String username = (String)session.getAttribute("username");
+        // 从cookie中取出username
+        Cookie[] cookies = req.getCookies();
+        String cookieValue = null;
+        if(cookies != null) {
+            for (Cookie cookie : cookies) {
+                if (cookie.getName().equals("username")) {
+                    cookieValue = cookie.getValue();
+                }
+            }
+        }
+
+        System.out.println("Session username: " + username);
+        System.out.println("Cookie username: " + cookieValue);
+        // 如果session中没有username 以及cookie中没有username 代表没有登录
+        if(username == null || cookieValue == null) {
+            // 此时跳转到登录页面中
+            resp.sendRedirect("/login.html");
+        }else{
+            // 如果已经登录 那么放行
+            chain.doFilter(request, response);
+        }
+    }
+}

+ 39 - 0
tomcat-demo/src/main/java/com/sf/sysdemo/listener/ThymeleafListener.java

@@ -0,0 +1,39 @@
+package com.sf.sysdemo.listener;
+
+import jakarta.servlet.ServletContext;
+import jakarta.servlet.ServletContextEvent;
+import jakarta.servlet.ServletContextListener;
+import jakarta.servlet.annotation.WebListener;
+import org.thymeleaf.TemplateEngine;
+import org.thymeleaf.templatemode.TemplateMode;
+import org.thymeleaf.templateresolver.WebApplicationTemplateResolver;
+import org.thymeleaf.web.servlet.JakartaServletWebApplication;
+
+// 需要使得thymeleaf生效的监听器
+@WebListener
+public class ThymeleafListener implements ServletContextListener {
+
+    // 重写 应用初始化方法
+    @Override
+    public void contextInitialized(ServletContextEvent sce) {
+        ServletContext servletContext = sce.getServletContext();
+        // 通过上下文获取到应用
+        JakartaServletWebApplication application = JakartaServletWebApplication.buildApplication(servletContext);
+        // 通过应用获取解析器  是模板引擎渲染页面时使用的
+        WebApplicationTemplateResolver resolver = new WebApplicationTemplateResolver(application);
+        // 设置模板引擎使用的页面 所在的位置 以webapp为相对路径
+        resolver.setPrefix("/WEB-INF/templates/");
+        resolver.setSuffix(".html");
+        // 设置编码格式
+        resolver.setCharacterEncoding("UTF-8");
+        // 设置渲染模式
+        resolver.setTemplateMode(TemplateMode.HTML);
+
+        // 创建模板引擎 将解析器设置进去
+        TemplateEngine templateEngine = new TemplateEngine();
+        templateEngine.setTemplateResolver(resolver);
+        // 将引擎 存入应用域
+        servletContext.setAttribute("engine", templateEngine);
+        servletContext.setAttribute("application", application);
+    }
+}

+ 57 - 0
tomcat-demo/src/main/java/com/sf/tomcatdemo/listener/ApplicationListener.java

@@ -0,0 +1,57 @@
+package com.sf.tomcatdemo.listener;
+
+import jakarta.servlet.*;
+import jakarta.servlet.annotation.WebListener;
+
+// 定义一个应用域监听器
+// 需要实现 ServletContextListener和ServletContextAttributeListener
+// 需要使用注解证明 这是一个监听器@WebListener
+@WebListener
+public class ApplicationListener implements ServletContextListener, ServletContextAttributeListener {
+
+    // 重写 应用初始化方法 入参是应用相关事件
+    @Override
+    public void contextInitialized(ServletContextEvent sce) {
+//        ServletContextListener.super.contextInitialized(sce);
+        ServletContext servletContext = sce.getServletContext();
+        // 可以使用对象的hashcode验证唯一性
+        System.out.println("application contextInitialized " + servletContext.hashCode());
+    }
+
+    @Override
+    public void contextDestroyed(ServletContextEvent sce) {
+        ServletContext servletContext = sce.getServletContext();
+        System.out.println("application contextInitialized " + servletContext.hashCode());
+    }
+
+    // 实现来自ServletContextAttributeListener接口的三个方法
+    // 分别对应属性的 增加 移除 和 修改
+    // 入参是ServletContextAttributeEvent 也就是处理属性的事件
+    @Override
+    public void attributeAdded(ServletContextAttributeEvent event) {
+        String name = event.getName();
+        Object value = event.getValue();
+        ServletContext servletContext = event.getServletContext();
+        System.out.println("application: " + servletContext.hashCode()
+                + " attributeAdded " + name + " " + value);
+    }
+
+    @Override
+    public void attributeRemoved(ServletContextAttributeEvent event) {
+        String name = event.getName();
+        Object value = event.getValue();
+        ServletContext servletContext = event.getServletContext();
+        System.out.println("application: " + servletContext.hashCode()
+                + " attributeRemoved " + name + " " + value);
+    }
+
+    @Override
+    public void attributeReplaced(ServletContextAttributeEvent event) {
+        String name = event.getName();
+        Object value = event.getValue();
+        ServletContext servletContext = event.getServletContext();
+        Object newValue = servletContext.getAttribute(name);
+        System.out.println("application: " + servletContext.hashCode()
+                + " attributeReplaced " + name + " " + value + " to " + newValue);
+    }
+}

+ 37 - 0
tomcat-demo/src/main/java/com/sf/tomcatdemo/listener/RequestListener.java

@@ -0,0 +1,37 @@
+package com.sf.tomcatdemo.listener;
+
+import jakarta.servlet.*;
+import jakarta.servlet.annotation.WebListener;
+
+@WebListener
+public class RequestListener implements ServletRequestListener, ServletRequestAttributeListener {
+
+    @Override
+    public void attributeAdded(ServletRequestAttributeEvent srae) {
+        String name = srae.getName();
+        Object value = srae.getValue();
+        ServletRequest servletRequest = srae.getServletRequest();
+//        ServletRequestAttributeListener.super.attributeAdded(srae);
+    }
+
+    @Override
+    public void attributeRemoved(ServletRequestAttributeEvent srae) {
+//        ServletRequestAttributeListener.super.attributeRemoved(srae);
+    }
+
+    @Override
+    public void attributeReplaced(ServletRequestAttributeEvent srae) {
+//        ServletRequestAttributeListener.super.attributeReplaced(srae);
+    }
+
+    @Override
+    public void requestDestroyed(ServletRequestEvent sre) {
+        ServletRequest servletRequest = sre.getServletRequest();
+//        ServletRequestListener.super.requestDestroyed(sre);
+    }
+
+    @Override
+    public void requestInitialized(ServletRequestEvent sre) {
+//        ServletRequestListener.super.requestInitialized(sre);
+    }
+}

+ 38 - 0
tomcat-demo/src/main/java/com/sf/tomcatdemo/listener/SessionListener.java

@@ -0,0 +1,38 @@
+package com.sf.tomcatdemo.listener;
+
+import jakarta.servlet.annotation.WebListener;
+import jakarta.servlet.http.*;
+
+// 定义会话域监听器
+@WebListener
+public class SessionListener implements HttpSessionListener, HttpSessionAttributeListener {
+
+    @Override
+    public void attributeAdded(HttpSessionBindingEvent event) {
+        String name = event.getName();
+        Object value = event.getValue();
+        HttpSession session = event.getSession();
+        HttpSessionAttributeListener.super.attributeAdded(event);
+    }
+
+    @Override
+    public void attributeRemoved(HttpSessionBindingEvent event) {
+        HttpSessionAttributeListener.super.attributeRemoved(event);
+    }
+
+    @Override
+    public void attributeReplaced(HttpSessionBindingEvent event) {
+        HttpSessionAttributeListener.super.attributeReplaced(event);
+    }
+
+    @Override
+    public void sessionCreated(HttpSessionEvent se) {
+        HttpSession session = se.getSession();
+        HttpSessionListener.super.sessionCreated(se);
+    }
+
+    @Override
+    public void sessionDestroyed(HttpSessionEvent se) {
+        HttpSessionListener.super.sessionDestroyed(se);
+    }
+}

+ 2 - 0
tomcat-demo/src/main/java/com/sf/tomcatdemo/startup/MyServlet2.java

@@ -18,6 +18,8 @@ public class MyServlet2 extends HttpServlet {
         // 通过key获取value  直接得到Object类型 强转String类型
         String value = (String)servletContext.getAttribute("name");
         System.out.println(value);
+        // 第一次set是新增 第二次set是修改
+        servletContext.setAttribute("name", "other-name");
     }
 
     @Override

+ 13 - 0
tomcat-demo/src/main/webapp/WEB-INF/templates/index.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<!-- 通过xml命名空间 来支持thymeleaf标签的使用 -->
+<html lang="en" xmlns:th="http://www.thymeleaf.org">
+<head>
+  <meta charset="UTF-8">
+  <title>Title</title>
+</head>
+<body>
+  <!-- Hello Thymeleaf -->
+  <!-- 这里的用法是 thymeleaf的语法 p标签的文本内容是不固定的 通过传入的动态数据进行渲染  -->
+  <p th:text="${message}"></p>
+</body>
+</html>