2024-05-03
大学课程
00

目录

1 Servlet 过滤器实践
2 监听器实践

记录实验3过程及代码。

注意Tomcat10 -> jakarta.servlet-api,Tomcat9以下 -> javax.servlet-api

1 Servlet 过滤器实践

要求:编写登录和注销 Servlet 类,分别实现用户登录和注销功能。再编写一个实现javax.servlet.Filter接口的类,实现 doFilter 方法进行请求预处理和后处理操作。

java
// LoginServlet.java package org.example.webstructure.experiment3; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; import java.util.Objects; @WebServlet(value = "/LoginServlet") public class LoginServlet extends HttpServlet { Map<String, String> userInfo = new HashMap<String, String>(); @Override public void init() throws ServletException { this.userInfo.put("user1", "123456"); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { log("LoginServlet is queried once"); String name = req.getParameter("userName"); String password = req.getParameter("userPassword"); log(name); log(password); PrintWriter out = resp.getWriter(); if (Objects.equals(this.userInfo.get(name), password)) { resp.addCookie(new Cookie("isLogin", "true")); resp.addCookie(new Cookie("userName", name)); resp.sendRedirect("/WebStructure/MainServlet"); } else { out.println("Login Failed!"); } } } // MainServlet.java package org.example.webstructure.experiment3; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet(value = "/MainServlet") public class MainServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); // Hello PrintWriter out = resp.getWriter(); if (req.getCookies() == null) { out.println("<html><body>"); out.println("<h1>" + "Hello!, " + "you are not login" + "</h1>"); out.println("</body></html>"); return; } out.println("<html><body>"); out.println("<h1>" + "Hello!, " + req.getCookies()[1].getValue() + "</h1>"); out.println("</body></html>"); } } // LoginFilter.java package org.example.webstructure.experiment3; import jakarta.servlet.*; import jakarta.servlet.annotation.WebFilter; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Objects; import java.util.logging.Logger; @WebFilter(urlPatterns = "/LoginServlet") public class LoginFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; if (req.getCookies() != null && Objects.equals(req.getCookies()[0].getValue(), "true")) { HttpServletResponse resp = (HttpServletResponse) response; resp.sendRedirect("/WebStructure/MainServlet"); } else { chain.doFilter(request, response); } } }

效果:

image.png

image.png

ApiFox的Cookie管理位置在右下角。

2 监听器实践

要求:编 写 两 个 实 现 javax.servlet.ServletContextListenerjavax.servlet.http. HttpSessionListener接口的类。分别在 contextInitialized 和 contextDestroyed 方法中添加日志记录,用于监控应用上下文的启动和停止。在 sessionCreated 和 sessionDestroyed 方法中添加相应逻辑,跟踪会话的创建和销毁事件。

java
// LoginServletContextListener.java package org.example.webstructure.experiment3; import jakarta.servlet.ServletContextEvent; import jakarta.servlet.ServletContextListener; import jakarta.servlet.annotation.WebListener; @WebListener public class LoginServletContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { sce.getServletContext().log("Login Servlet Context Initialized"); ServletContextListener.super.contextInitialized(sce); } @Override public void contextDestroyed(ServletContextEvent sce) { sce.getServletContext().log("Login Servlet Context Destroyed"); System.out.println("Login Servlet Context Destroyed"); ServletContextListener.super.contextDestroyed(sce); } } // LoginSessionListener.java package org.example.webstructure.experiment3; import jakarta.servlet.annotation.WebListener; import jakarta.servlet.http.HttpSessionEvent; import jakarta.servlet.http.HttpSessionListener; @WebListener public class LoginSessionListener implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent se) { se.getSession().getServletContext().log("Login Session Created"); HttpSessionListener.super.sessionCreated(se); } @Override public void sessionDestroyed(HttpSessionEvent se) { se.getSession().getServletContext().log("Login Session Destroyed"); HttpSessionListener.super.sessionDestroyed(se); } } // 修改LoginServlet.java package org.example.webstructure.experiment3; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; import java.util.Objects; @WebServlet(value = "/LoginServlet") public class LoginServlet extends HttpServlet { Map<String, String> userInfo = new HashMap<String, String>(); @Override public void init() throws ServletException { this.userInfo.put("user1", "123456"); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.getSession(); // 新增语句 log("LoginServlet is queried once"); String name = req.getParameter("userName"); String password = req.getParameter("userPassword"); PrintWriter out = resp.getWriter(); if (Objects.equals(this.userInfo.get(name), password)) { resp.addCookie(new Cookie("isLogin", "true")); resp.addCookie(new Cookie("userName", name)); resp.sendRedirect("/WebStructure/MainServlet"); } else { out.println("Login Failed!"); } } }

IDEA运行Tomcat配置修改位置:

image.png

新增一个环境变量(该环境变量不是Windows的那个环境变量,仅适用于这次运行),键为CATALINA_BASE,值为Tomcat的安装目录。

提示

这个环境变量目的在于指定配置文件。默认情况下,IDEA会在另一个地方存储运行Tomcat的运行配置文件和log文件。在我的电脑上,这个IDEA专用的配置文件位置在C:\Users\Misaka19327\AppData\Local\JetBrains\IntelliJIdea2024.1\tomcat\3b6ae244-5a4a-4ef7-a2f8-aeddfd556f34里。

image.png

默认情况下,这些文件会在IDEA启动Tomcat时被IDEA自动覆盖,所有对配置文件的修改都会失效,所以如果想要使用自定义配置的话需要在运行配置中指定一个新的CATALINA_BASE。

之后再修改server.xml文件,该文件位置在Tomcat安装目录下的conf文件夹下。

image.png

修改shutdown port从-1变为8005。

提示

该配置的作用在于确实地停止Tomcat。如果不修改的话,每次通过IDEA停止Tomcat时,它只是和Tomcat断开连接而已,后台的Tomcat还存在:

image.png

image.png

修改之后,能看到IDEA确实地停止了Tomcat:

image.png

另外,这个端口不建议开,如果暴露给外部一个能随时停止服务的端口还是危险的。

提示

如果想要通过System.out.println()记录日志的话,需要修改web.xml文件的debug属性,从0修改为1:

image.png

该文件位置在Tomcat安装目录下的conf文件夹下:

image.png

效果:

运行Tomcat服务器,访问LoginServlet成功后再关闭Tomcat服务器,再去Tomcat安装目录下的logs文件夹下的localhost.(运行Tomcat服务器的日期).log文件中寻找log信息,可以看到Context和Session创建和销毁的log:

image.png

如果是使用System.out.println()记录日志的话,从IDEA中也能看到输出信息:

image.png

本文作者:御坂19327号

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!