Web资源访问的流程

由此可见 客户访问JAVA开发的应用时 会先通过 监听器(Listener)和 过滤器(Filter) 今天简单的了解下这两个模块的开发过程
监听器(Listener)
主要是监听 我们触发了什么行为 并进行反应 下面是一个监听Session的例子
正常创建项目后 目录文件如下

CSession代码
import jakarta.servlet.http.*;
import java.io.IOException;
@WebServlet("/CS") // 映射到路径 "/CS"
public class CSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 控制台输出,表示正在创建 Session
System.out.println("creat Session");
// 调用 req.getSession() 方法获取或创建 Session
// 如果请求中没有 Session,则自动创建新 Session
req.getSession();
}
}
DSession代码
package com.example.listendemo1.Servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;
import java.io.IOException;
@WebServlet("/DS") // 映射到路径 "/DS"
public class DSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 控制台输出日志,表示正在销毁 Session
System.out.println("kill Session");
// 获取当前 Session 并立即使其失效
// invalidate() 方法会销毁 Session,清除所有存储的属性
req.getSession().invalidate();
}
}
以上两个代码操作为 访问路径(/CS|/DS)后对Session进行创建(删除)操作
ListenSession代码
package com.example.listendemo1.Listener;
import jakarta.servlet.annotation.WebListener;
import jakarta.servlet.http.HttpSessionEvent;
import jakarta.servlet.http.HttpSessionListener;
@WebListener
public class ListenSession implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
// 输出 Session 创建日志(控制台)
System.out.println("Session created in Listen Session");
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
// 输出 Session 销毁日志(控制台)
System.out.println("Session destroyed in Listen Session");
}
}
监听器(Listener)运行情况
在没有操作时就会产生默认操作

创建Session

删除Session 监听器监听到了该动作

过滤器(Filter)
路径如下

TextServlet代码
package com.example.filterdemo1.Servlet;
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("/text") // 定义Servlet访问路径
public class TextServlet extends HttpServlet {
//处理HTTP GET请求
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 从请求中获取名为"code"的参数值
String code = req.getParameter("code");
// 获取响应输出流(自动设置text/html内容类型)
PrintWriter out = resp.getWriter();
// 将参数值写入响应
out.println(code);
// 刷新并关闭输出流
out.flush();
out.close();
}
}
XssFilter代码
package com.example.filterdemo1.filter;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;
@WebFilter("/text") // 只过滤/text路径的请求
public class XssFilter implements Filter {
// 过滤器初始化方法(容器启动时执行一次)
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("XssFilter first"); // 初始化日志
}
// 过滤器销毁方法(容器关闭时执行)
@Override
public void destroy() {
System.out.println("XssFilter end"); // 销毁日志
}
// 过滤处理方法(每次请求时执行)
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
System.out.println("XssFilter now"); // 处理请求日志
// 类型转换获取HttpServletRequest
HttpServletRequest requset = (HttpServletRequest) servletRequest;
// 获取请求参数code的值
String code = requset.getParameter("code");
// 检查是否不包含<script>标签
if (!code.contains("<script>")) {
// 安全请求,放行
filterChain.doFilter(servletRequest, servletResponse);
} else {
// 检测到潜在XSS攻击
System.out.println("XssFilter fight!!"); // 攻击日志
// 注意:这里只是记录日志,实际应该阻止请求继续处理
}
}
}
测试代码运行如下:
预启动

添加代码--text?code=<script>alert(1)</script> 正常执行可以在页面弹出1
显示受到了攻击

正常情况是这个样子--text?code=123
第二个例子:/admin
AdminServlet代码
package com.example.filterdemo1.Servlet;
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;
//管理员后台Servlet
@WebServlet("/admin") // 定义Servlet访问路径为/admin
public class AdminServlet extends HttpServlet {
// 处理HTTP GET请求
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 控制台输出欢迎信息
System.out.println("Welcome to Admin Servlet");
}
}
AdminFiler代码
package com.example.filterdemo1.filter;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;
// 管理员权限过滤器
// 作用路径:/admin
@WebFilter("/admin") // 过滤所有访问/admin路径的请求
public class AdminFilter implements Filter {
// 过滤器初始化方法(容器启动时执行一次)
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("XssFilter first"); // 初始化日志
}
// 过滤器销毁方法(容器关闭时执行)
@Override
public void destroy() {
System.out.println("XssFilter end"); // 销毁日志
}
/**
* 过滤处理方法(每次访问/admin时执行)
* 通过检查Cookie验证管理员权限
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
// 转换请求对象以获取Cookie
HttpServletRequest requset = (HttpServletRequest) servletRequest;
// 获取请求中的所有Cookie
Cookie[] cookies = requset.getCookies();
// 遍历所有Cookie
for (Cookie c : cookies) {
String cName = c.getName(); // 获取Cookie名称
String cValue = c.getValue(); // 获取Cookie值
// 打印Cookie信息(调试用)
System.out.println(cName);
System.out.println(cValue);
// 检查是否为管理员Cookie
if (cName.equals("username") && cValue.equals("admin")) {
// 验证通过,放行请求
filterChain.doFilter(servletRequest, servletResponse);
return; // 找到有效Cookie后立即返回
} else {
// 非管理员Cookie
System.out.println("NO ADMIN");
}
}
}
}
实验结果如下:
会打印出Cookie值 因为是循环输出 Cookie都会被输出 admin认证成功 第二个password也会输出 但是没有对password进行判断 所有会输出NO ADMIN
