当前位置: 首页 > news >正文

JavaWeb之JSP 快递管理与过滤器详解

JavaWeb之JSP 快递管理与过滤器详解

第一章 JSP 基础

1. JSP 初识

JSP(Java Server Pages)是 Sun 公司提出的基于 Java 技术的 Web 页面制作技术,允许在 HTML 文件中嵌入 Java 代码,简化动态内容生成。

主要作用

  • 生成动态页面,支持数据库查询、表单数据处理等
  • 可与 Servlet 结合,实现复杂 Web 应用开发

核心特点

  1. 简单性:通过嵌入 Java 代码简化动态内容编写
  2. 高效性:首次运行转换为 Servlet 并编译为字节码,支持 JIT 编译
  3. 多样化:支持 JSTL、EL 等标准标签库,简化常见开发需求

2. EL 表达式

EL(Expression Language) 旨在简化 JSP 代码编写,灵感源自 ECMAScript 和 XPath,语法结构为:${expression}

数据获取方式

  • 基础语法:${username}(依次从 Page、Request、Session、Application 域查找)
  • 访问运算符:
    • . 操作符:访问对象属性(如 ${user.name}
    • [] 操作符:访问数组或集合元素(如 ${list[0]}

注意:EL 仅负责获取数据,无法循环遍历,且数据必须先存储到作用域中

案例代码

<%@ page import="com.atguigu.pojo.SysUser" %><%--Created by IntelliJ IDEA.User: yutaoDate: 2025/2/19Time: 21:54To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>EL表达式</title>
</head>
<body>
<%String name = "tom";int age = 18;SysUser sysUser = new SysUser();sysUser.setUsername("root");String[] strs = {"张三", "李四"};//将四个数据保存到请求域中request.setAttribute("sysname", name);request.setAttribute("sysage", age);request.setAttribute("sysuser", sysUser);request.setAttribute("strs", strs);//2.内置对象测试request.setAttribute("reqkey","request的数据");session.setAttribute("sessionkey","session的数据");application.setAttribute("applicationkey","application的数据");
%><h1>学生姓名:${sysname}</h1><h1>学生年龄:${sysage}</h1><h1>对象的姓名:${sysuser.username}</h1><h1>数组:${strs[0]},${strs[1]}</h1><h1>request:${reqkey}</h1><h1>session:${sessionkey}</h1><h1>application:${applicationkey}</h1>
</body>
</html>

3. JSTL 标签库

JSP 标准标签库(JSP Standard Tag Library,JSTL)提供了 Web 开发中常见的通用功能,包括迭代、条件判断、数据格式化等。

3.1 使用步骤
  1. 添加依赖包
    (依赖包版本因 tomcat 环境和配置有所差异)

  2. 引入核心标签库

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
  3. 常用标签

    • <c:forEach> 标签属性:

      属性描述是否必要默认值
      items要被循环的信息
      begin开始的元素(0=第一个元素)0
      end最后一个元素Last element
      step每一次迭代的步长1
      var代表当前条目的变量名称
      varStatus循环状态变量(index:索引;count:次数;first:是否首项;last:是否末项)
    • <c:if> 标签属性:

      属性描述是否必要默认值
      test条件表达式
      var存储条件结果的变量
      scopevar属性的作用域page

案例代码

<%@ page import="java.util.ArrayList" %><%--Created by IntelliJ IDEA.User: adminDate: 2025/2/25Time: 20:24To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>Title</title>
</head>
<body>
<%ArrayList<String> list = new ArrayList<>();list.add("张三");list.add("李四");list.add("王五");list.add("赵六");request.setAttribute("list", list);
%><table width="300px" border="1" cellspacing="0"><tr><td>序号</td><td>姓名</td></tr><c:if test="${list.size()>0}"><c:forEach items="${list}" var="element" varStatus="i"><tr ><td>${i.count}</td><td>${element}</td></tr></c:forEach></c:if></table>
</body>
</html>

JSP 四大域对象

  • PageContext:页面域,作用于当前页面
  • request:请求域,作用于一次请求
  • session:会话域,作用于一次会话
  • application:应用域,作用于整个 Web 应用

当四大域存在同名 key 时,EL 表达式遵循从小到大的查找顺序(PageContext → request → session → application)

第二章 案例开发 - 快递管理系统(第四期)

1. 动态展示快递记录信息

1.1 导入 JSTL 依赖

添加 JSTL 相关 jar 包到项目中(根据环境选择合适版本)

1.2 页面改造

将除 login.html 外的所有页面改为 JSP 动态页面,需包含:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
1.2.1 修改控制器跳转地址
@WebServlet("/deliverylist/list")
public class DeliveryListController extends HttpServlet {private DeliveryService deliveryService = new DeliveryServiceImpl();@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {try {//1.解决请求乱码问题request.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");/*2.获取登录的用户id我们需要用登录用户的id去查询对应的快递信息也就是哪个用户登录,就只查询哪个用户相关的快递信息*/SysUser user = (SysUser) request.getSession().getAttribute("user");Integer userId = user.getId();List<Delivery> list = deliveryService.findAllDeliveryByUserId(userId);//3.将查询出来的集合响应给页面request.setAttribute("deliverylist", list);//这里将list.html改成list.jsprequest.getRequestDispatcher("/list.jsp").forward(request, response);} catch (SQLException e) {e.printStackTrace();}}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
1.2.2 修改 list.jsp 页面展示快递信息
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>快递管理系统</title><meta name="Copyright" content="Douco Design." /><link href="css/public.css" rel="stylesheet" type="text/css"><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/global.js"></script><script type="text/javascript" src="js/jquery.autotextarea.js"></script></head><body><div id="dcWrap"><div id="dcHead"><div id="head"><div class="logo"><a href="index.html"><img width="100px"height="25px" src="images/dclogo.gif"alt="logo"></a></div><div class="nav"><ul class="navRight"><li class="M noLeft"><ahref="JavaScript:void(0);">${user.username}</a><div class="drop mUser"><a href="password.html">修改密码</a></div></li><li class="noRight"><ahref="login.html">退出</a></li></ul></div></div></div><!-- dcHead 结束 --> <div id="dcLeft"><div id="menu"><ul class="top"><li><a href="index.html"><iclass="home"></i><em>管理首页</em></a></li></ul><ul><li><a href="password.html"><iclass="system"></i><em>修改密码</em></a></li><li><a href="list.html"><iclass="nav"></i><em>快递管理</em></a></li></ul></div></div><div id="dcMain"><!-- 当前位置 --><div id="urHere">快递管理系统<b>></b><strong>快递列表</strong> </div><div class="mainBox"style="height:auto!important;height:550px;min-height:550px;"><h3><a href="add.html"class="actionBtn add">添加快递</a>快递列表</h3><!-- 本阶段不实现筛选功能 --><div id="list"><table width="100%" border="0" cellpadding="8"cellspacing="0" class="tableBasic"><tr><th width="40" align="center">编号</th><th width="80" align="center">物流公司</th><th width="80" align="center">收件人</th><th width="80" align="center">手机号</th><th width="80" align="center">送达日期</th><th align="center">地址</th><th width="80" align="center">签收状态</th><th width="80" align="center">操作</th></tr><c:forEach items="${deliveryList}" var="delivery"><tr><td align="center">${delivery.id}</td><td>${delivery.company.companyName}</td><td align="center">${delivery.deliveryName}</td><td align="center">${delivery.phone}</td><td align="center">${delivery.sendTime}</td><td align="center">${delivery.address}</td><td align="center">${delivery.state==0?'未签收':'已签收'}</td><td align="center"><a href="#">编辑</a> | <a href="#">删除</a></td></tr></c:forEach></table></div><div class="clear"></div><div class="pager"> <a href="article.php?page=1">第一页</a><a href="article.php?page=1"> 上一页</a> <ahref="article.php?page=1">下一页</a> <ahref="article.php?page=1">最末页</a></div> </div></div><div class="clear"></div><div id="dcFooter"><div id="footer"><div class="line"></div><ul>版权所有 © 2024-2025 尚硅谷教育,并保留所有权利。</ul></div></div><!-- dcFooter 结束 --><div class="clear"></div> </div><script type="text/javascript">onload = function(){document.forms['action'].reset();}function douAction(){var frm = document.forms['action'];frm.elements['new_cat_id'].style.display = frm.elements['action'].value == 'category_move' ? '' : 'none';}</script></body>
</html>

2. 展示用户信息

修改登录相关页面(index.jsp / list.jsp / add.jsp / edit.jsp / password.jsp)为动态页面,展示登录用户信息。

2.1 修改登录控制器跳转
@WebServlet("/user/login")
public class UserLoginController extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.设置请求参数编码格式req.setCharacterEncoding("UTF-8");resp.setContentType("text/html;charset=UTF-8");//2.获取请求参数String username = req.getParameter("username");String password = req.getParameter("password");System.out.println(username);//3.调用service层方法UserService userService = new UserServiceImpl();try {SysUser sysUser =userService.login(username,password);//System.out.println(sysUser);if (sysUser!=null){//保存登录的用户状态,用于查询登录快递信息以及登录的状态req.getSession().setAttribute("user",sysUser);req.getRequestDispatcher("/index.jsp").forward(req,resp);}else{req.getRequestDispatcher("/login.html").forward(req,resp);}} catch (SQLException e) {throw new RuntimeException(e);}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req,resp);}
}
2.2 页面展示用户信息
<li class="M noLeft"><a href="JavaScript:void(0);">您好,${user.nickname}</a>

第三章 修改密码功能

1. 通用页面抽取

1.1 创建资源文件
  • resource.jsp(CSS 和 JS 资源)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<link href="/delivery_system/css/public.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/delivery_system/js/jquery.min.js"></script>
<script type="text/javascript" src="/delivery_system/js/global.js"></script>
<script type="text/javascript" src="/delivery_system/js/jquery.autotextarea.js"></script>
  • head.jsp(头部和登录状态)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<div id="dcHead"><div id="head"><div class="logo"><a href="index.html"><img width="100px"height="25px" src="/delivery_system/images/dclogo.gif"alt="logo"></a></div><div class="nav"><ul class="navRight"><li class="M noLeft"><ahref="JavaScript:void(0);">您好,${user.nickname}</a><div class="drop mUser"><a href="password.jsp">修改密码</a></div></li><li class="noRight"><ahref="login.php?rec=logout">退出</a></li></ul></div></div>
</div>
  • menu.jsp(左侧菜单)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<div id="dcLeft"><div id="menu"><ul class="top"><li><a href="index.html"><iclass="home"></i><em>管理首页</em></a></li></ul><ul><li><a href="password.jsp"><iclass="system"></i><em>修改密码</em></a></li><li><a href="/delivery_system/delivery/list"><iclass="nav"></i><em>快递管理</em></a></li></ul></div>
</div>
1.2 页面引用
<head><jsp:include page="resource.jsp"></jsp:include>
</head>
<div id="dcWrap"><jsp:include page="head.jsp"></jsp:include><jsp:include page="menu.jsp"></jsp:include>

2. 密码修改功能实现

2.1 跳转密码修改页面
// 修改 menu.jsp 中的链接
<li><a href="/delivery_system/user/toPasswordPage"><iclass="system"></i><em>修改密码</em></a></li>     // 控制器代码
@WebServlet("/user/toPasswordPage")
public class UserToPasswordController extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.getRequestDispatcher("/password.jsp").forward(request,response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
2.2 密码修改控制器
@WebServlet("/user/changepassword")
public class UserChangePasswordController extends HttpServlet {private UserService userService = new UserServiceImpl();@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {try {request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");/*** 我们应该先根据当前登录的用户id查询对应的用户* 然后再service层拿出用户的密码,和我们在页面上* 填写的原始密码比较一样才能更新新密码*/SysUser sysUser = (SysUser) request.getSession().getAttribute("user");Integer uid = sysUser.getId();//获取页面上填写的原始密码和新密码String password = request.getParameter("password");String newpassword = request.getParameter("newpassword");//调用service层修改密码的方法,传递uid,和原始密码以及新密码boolean flag = userService.updateUserPassword(uid, password, newpassword);//判断将来如果flag为true,在页面展示"修改密码成功",否则展示"修改密码失败"if (flag == true) {request.setAttribute("message", "修改密码成功");request.getRequestDispatcher("/password.jsp").forward(request, response);} else {request.setAttribute("message", "修改密码失败");request.getRequestDispatcher("/password.jsp").forward(request, response);}} catch (SQLException e) {e.printStackTrace();}}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
2.3 Service 层实现
public interface UserService {/*** 用户登录* @param username* @param password* @return*/SysUser login(String username, String password) throws SQLException;/*** 修改用户密码* @param uid* @param password* @param newpassword* @return*/boolean updateUserPassword(Integer uid, String password, String newpassword) throws SQLException;
}public class UserServiceImpl implements UserService {private UserDao userDao = new UserDaoImpl();/*** 用户登录* @param username* @param password* @return*/@Overridepublic SysUser login(String username, String password) throws SQLException {//1.将password加密password = MD5Utils.encrypt(password);//2.将username和password传递到dao层SysUser sysUser = userDao.login(username,password);return sysUser;}@Overridepublic boolean updateUserPassword(Integer uid, String password, String newpassword) throws SQLException {//先根据当前登录的用户id查询对应的用户,以便拿出在数据库中用户的密码SysUser sysUser = userDao.findUserById(uid);String oldPassword = sysUser.getPassword();//将页面上获取的原始密码password加密然后和查询出来的密码比较password = MD5Utils.encrypt(password);if (oldPassword.equals(password)){userDao.updateUserPassword(uid,MD5Utils.encrypt(newpassword));return true;}return false;}
}
2.4 Dao 层实现
public interface UserDao {/*** 用户登录* @param username* @param password* @return*/SysUser login(String username, String password) throws SQLException;/*** 根据id查询用户* @param uid* @return*/SysUser findUserById(Integer uid) throws SQLException;/*** 修改用户密码* @param uid* @param newpassword*/void updateUserPassword(Integer uid, String newpassword) throws SQLException;
}public class UserDaoImpl implements UserDao {private QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());/*** 用户登录* @param username* @param password* @return*/@Overridepublic SysUser login(String username, String password) throws SQLException {String sql = "select id,username,password,nickname from sys_user where username = ? and password = ?";SysUser sysUser = qr.query(sql, new BeanHandler<SysUser>(SysUser.class), username, password);return sysUser;}/*** 根据用户id查询用户* @param uid* @return* @throws SQLException*/@Overridepublic SysUser findUserById(Integer uid) throws SQLException {String sql = "select id,username,password,nickname from sys_user where id = ?";SysUser sysUser = qr.query(sql, new BeanHandler<>(SysUser.class), uid);return sysUser;}/*** 修改用户密码* @param uid* @param newpassword*/@Overridepublic void updateUserPassword(Integer uid, String newpassword) throws SQLException {String sql = "update sys_user set password = ? where id = ?";qr.update(sql,newpassword,uid);}
}
2.5 页面展示结果
<tr><td></td><td><input type="submit" name="submit" class="btn" value="提交" /></td>
</tr>
</table>
<div>${message}</div>
</form>

3. 用户退出功能

3.1 修改退出链接
<li class="noRight"><a href="/delivery_system/user/logout">退出</a></li>
3.2 退出控制器
@WebServlet("/user/logout")
public class UserLogoutController extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.getSession().invalidate();response.sendRedirect(request.getContextPath()+"/login.html");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}

第四章 Filter 过滤器

1. Filter 过滤器介绍

  • 概述:过滤器是一个接口(Filter),实现该接口即可创建过滤器
  • 作用:在请求到达 Web 资源之前进行过滤,决定是否放行请求
  • 应用场景
    • 登录权限校验
    • 统一处理请求中文乱码
    • 敏感词过滤等

2. Filter 入门案例

2.1 单个过滤器实现
@WebServlet("/servlet1")
public class Servlet1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.getWriter().write("servlet1");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}public class Filter1 implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("filter1");/*放行方法不写不放行写了放行不是递归调用*///filterChain.doFilter(servletRequest, servletResponse);}
}

XML 配置

<filter><filter-name>filter1</filter-name><filter-class>com.atguigu.b_filter.Filter1</filter-class>
</filter>
<filter-mapping><filter-name>filter1</filter-name><!-- 访问该路径时触发过滤器 --><url-pattern>/servlet1</url-pattern>
</filter-mapping>
2.2 多个过滤器实现
@WebServlet("/servlet2")
public class Servlet2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.getWriter().write("servlet2");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}public class Filter2 implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("filter2");filterChain.doFilter(servletRequest, servletResponse);}
}public class Filter3 implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("filter3");filterChain.doFilter(servletRequest, servletResponse);}
}

XML 配置

<filter><filter-name>filter2</filter-name><filter-class>com.atguigu.b_filter.Filter2</filter-class>
</filter>
<filter-mapping><filter-name>filter2</filter-name><url-pattern>/servlet2</url-pattern>
</filter-mapping><filter><filter-name>filter3</filter-name><filter-class>com.atguigu.b_filter.Filter3</filter-class>
</filter>
<filter-mapping><filter-name>filter3</filter-name><url-pattern>/servlet2</url-pattern>
</filter-mapping>
2.3 选择性拦截
@WebServlet("/servlet3")
public class Servlet3 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.getWriter().write("servlet3");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}public class Filter4 implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("filter4");// 根据条件决定是否放行// filterChain.doFilter(servletRequest, servletResponse);}
}

过滤器执行顺序:多个过滤器的执行顺序由 web.xml 中 filter-mapping 的配置顺序决定,先配置的先执行

    // 假设这里添加一个判断条件,满足条件才放行String value = servletRequest.getParameter("key");if ("allow".equals(value)) {filterChain.doFilter(servletRequest, servletResponse);} else {servletResponse.getWriter().write("Access denied");}
}

}


```xml
<filter><filter-name>filter4</filter-name><filter-class>com.atguigu.b_filter.Filter4</filter-class>
</filter>
<filter-mapping><filter-name>filter4</filter-name><url-pattern>/servlet3</url-pattern>
</filter-mapping>

5.Filter的生命周期

public class FilterLifeCycle implements Filter {// 1.初始化方法:服务器启动时执行,只执行一次@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("FilterLifeCycle初始化方法执行了");// 可以获取过滤器的初始化参数String encoding = filterConfig.getInitParameter("encoding");System.out.println("初始化参数encoding:" + encoding);}// 2.过滤方法:每次请求被过滤时执行,可执行多次@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("FilterLifeCycle过滤方法执行了");filterChain.doFilter(servletRequest, servletResponse);}// 3.销毁方法:服务器关闭时执行,只执行一次@Overridepublic void destroy() {System.out.println("FilterLifeCycle销毁方法执行了");}
}
<filter><filter-name>filterLifeCycle</filter-name><filter-class>com.atguigu.b_filter.FilterLifeCycle</filter-class><!-- 配置初始化参数 --><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param>
</filter>
<filter-mapping><filter-name>filterLifeCycle</filter-name><url-pattern>/*</url-pattern> <!-- 拦截所有请求 -->
</filter-mapping>

6.Filter的拦截路径配置

  1. 精确匹配/servlet1 只拦截访问 /servlet1 的请求
  2. 目录匹配/user/* 拦截所有以 /user 开头的请求(如 /user/login/user/logout
  3. 扩展名匹配*.jsp 拦截所有 JSP 页面请求;*.html 拦截所有 HTML 页面请求
  4. 拦截所有/* 拦截所有请求

7.Filter的应用场景1_登录权限校验

/*** 登录权限校验过滤器:未登录用户不能访问除登录页之外的资源*/
public class LoginFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// 1.将ServletRequest转为HttpServletRequest(获取session需要)HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;// 2.获取请求路径String requestURI = request.getRequestURI();System.out.println("请求路径:" + requestURI);// 3.排除不需要拦截的资源(登录页、登录请求、静态资源等)if (requestURI.contains("/login.html") || requestURI.contains("/user/login") || requestURI.contains("/css/") || requestURI.contains("/js/") || requestURI.contains("/images/")) {// 放行filterChain.doFilter(request, response);return;}// 4.判断用户是否登录(从session中获取用户信息)SysUser user = (SysUser) request.getSession().getAttribute("user");if (user != null) {// 已登录,放行filterChain.doFilter(request, response);} else {// 未登录,重定向到登录页response.sendRedirect(request.getContextPath() + "/login.html");}}
}
<filter><filter-name>loginFilter</filter-name><filter-class>com.atguigu.c_filter.LoginFilter</filter-class>
</filter>
<filter-mapping><filter-name>loginFilter</filter-name><url-pattern>/*</url-pattern> <!-- 拦截所有请求 -->
</filter-mapping>

8.Filter的应用场景2_统一处理中文乱码

/*** 统一处理请求和响应的中文乱码过滤器*/
public class EncodingFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// 1.转为HttpServletRequest和HttpServletResponseHttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;// 2.处理POST请求的中文乱码request.setCharacterEncoding("UTF-8");// 3.处理响应的中文乱码response.setContentType("text/html;charset=UTF-8");// 4.放行filterChain.doFilter(request, response);}
}
<filter><filter-name>encodingFilter</filter-name><filter-class>com.atguigu.c_filter.EncodingFilter</filter-class>
</filter>
<filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern> <!-- 拦截所有请求 -->
</filter-mapping>

注意:对于GET请求的中文乱码,Tomcat 8及以上版本已经默认处理(使用UTF-8编码),如果是低版本Tomcat,需要在Server.xml中配置URIEncoding="UTF-8"

9.Filter链的执行顺序

当多个过滤器同时拦截同一个资源时,执行顺序由web.xmlfilter-mapping的配置顺序决定:先配置的先执行

例如:

<!-- 先执行FilterA -->
<filter-mapping><filter-name>filterA</filter-name><url-pattern>/servlet</url-pattern>
</filter-mapping><!-- 后执行FilterB -->
<filter-mapping><filter-name>filterB</filter-name><url-pattern>/servlet</url-pattern>
</filter-mapping>

执行流程:FilterA.doFilter()FilterB.doFilter()ServletFilterB.doFilter()之后的代码 → FilterA.doFilter()之后的代码

10.使用注解配置Filter

除了在web.xml中配置Filter,还可以使用@WebFilter注解进行配置:

@WebFilter(urlPatterns = "/*", initParams = {@WebInitParam(name = "encoding", value = "UTF-8")})
public class AnnotationFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("注解配置的过滤器执行了");filterChain.doFilter(servletRequest, servletResponse);}
}

注意:使用注解配置多个Filter时,执行顺序由类名的字母顺序决定(不推荐,建议使用web.xml控制顺序)。

第五章.总结

  1. JSP:动态网页开发技术,可嵌入Java代码,最终会被转换为Servlet执行。
  2. EL表达式:简化JSP中数据的获取,语法${表达式},从四大域中获取数据。
  3. JSTL标签库:提供通用功能标签(如c:forEach循环、c:if条件判断),需导入依赖并在JSP中声明。
  4. Filter过滤器
    • 实现Filter接口,重写doFilter方法。
    • 作用:登录权限校验、统一编码处理等。
    • 配置方式:web.xml@WebFilter注解。
    • 执行顺序:由filter-mapping的配置顺序决定。

通过JSP、EL、JSTL和Filter的结合使用,可构建功能完善、代码清晰的Java Web应用程序,尤其是在权限控制和请求处理方面,Filter发挥着重要作用。

http://www.dtcms.com/a/395856.html

相关文章:

  • 《MedChat智能医疗问答系统》项目介绍
  • 使用FastAPI和Docker部署机器学习模型:从开发到生产的最佳实践
  • Per-Tensor 量化和Per-Channel 量化
  • 执行bat任务栏有图标显示,执行pycharm64.exe就没有是什么原因
  • 【Docker项目实战】使用Docker部署wealth-tracker个人资产分析工具
  • LeapMotion_Demo演示
  • 智慧图书管理|基于SprinBoot+vue的智慧图书管理系统(源码+数据库+文档)
  • 面试技巧第四篇:嵌入式通信机制考点:消息队列、信号量与互斥锁
  • 面试八股:C语言的预处理和类型定义
  • 强化学习1.3 深度学习交叉熵方法
  • 用PowerBI的思想解决QuickBI文本无法动态配色问题
  • 逆向解析 1688 商品详情接口:自主构建 Sign 签名算法实战
  • SpringCloud项目阶段六:feign服务降级处理以及基于DFA算法的自管理敏感词审核和tess4j图片文字识别集成
  • 跨行业安全合规文档协同平台:重塑制造企业的质量管理与合规运营新范式
  • 线性代数 · SVD | 奇异值分解命名来历与直观理解
  • Qt 控件与布局
  • TDengine 聚合函数 SPREAD 用户手册
  • 4090 云服务器租赁:高性能与灵活性的算力融合方案​
  • 阿里云服务器ECS上安装anaconda(jupyter)和OpenCV教程
  • CVE-2025–3246 本地提权
  • Chat API和Chat SDK
  • 爱奇艺技术实践:基于 StarRocks 释放天玑买量数据价值
  • 突破传统文本切分桎梏!基于语义理解的智能文档处理革命——AntSK-FileChunk深度技术解析
  • Git常用的使用方法
  • IDEA集成Claude Code (win系统)
  • MySQL执行计划:索引为何失效?如何避免?
  • 【附源码】基于SpringBoot的校园防汛物资管理平台的设计与实现
  • PyTorch 核心工具与模型搭建
  • ARM--时钟管理单元与定时器
  • Unity-动画基础