记录实验3过程及代码。
注意Tomcat10 -> jakarta.servlet-api
,Tomcat9以下 -> javax.servlet-api
。
要求:编写登录和注销 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);
}
}
}
效果:
ApiFox的Cookie管理位置在右下角。
要求:编 写 两 个 实 现 javax.servlet.ServletContextListener
和 javax.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配置修改位置:
新增一个环境变量(该环境变量不是Windows的那个环境变量,仅适用于这次运行),键为CATALINA_BASE,值为Tomcat的安装目录。
提示
这个环境变量目的在于指定配置文件。默认情况下,IDEA会在另一个地方存储运行Tomcat的运行配置文件和log文件。在我的电脑上,这个IDEA专用的配置文件位置在C:\Users\Misaka19327\AppData\Local\JetBrains\IntelliJIdea2024.1\tomcat\3b6ae244-5a4a-4ef7-a2f8-aeddfd556f34
里。
默认情况下,这些文件会在IDEA启动Tomcat时被IDEA自动覆盖,所有对配置文件的修改都会失效,所以如果想要使用自定义配置的话需要在运行配置中指定一个新的CATALINA_BASE。
之后再修改server.xml文件,该文件位置在Tomcat安装目录下的conf文件夹下。
修改shutdown port从-1变为8005。
提示
该配置的作用在于确实地停止Tomcat。如果不修改的话,每次通过IDEA停止Tomcat时,它只是和Tomcat断开连接而已,后台的Tomcat还存在:
修改之后,能看到IDEA确实地停止了Tomcat:
另外,这个端口不建议开,如果暴露给外部一个能随时停止服务的端口还是危险的。
提示
如果想要通过System.out.println()
记录日志的话,需要修改web.xml文件的debug属性,从0修改为1:
该文件位置在Tomcat安装目录下的conf文件夹下:
效果:
运行Tomcat服务器,访问LoginServlet成功后再关闭Tomcat服务器,再去Tomcat安装目录下的logs文件夹下的localhost.(运行Tomcat服务器的日期).log文件中寻找log信息,可以看到Context和Session创建和销毁的log:
如果是使用System.out.println()
记录日志的话,从IDEA中也能看到输出信息:
本文作者:御坂19327号
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!