JavaWeb:过滤器 Filter、监听器 Listener

JavaWeb - 04

一、Filter

1. 概述

Filter:过滤器,可以用来过滤网站的数据,例如:处理中文乱码、登陆验证等。

注意

  • 在 Web 浏览器传入的请求中可能有一些垃圾请求,此时可以用 Filter 过滤器用来过滤网站的数据
  • Filter 过滤器可以应用在客户端和 Servlet 之间、Servlet 和 Servlet/JSP 之间,并且可以通过配置信息,灵活使用过滤器
  • 必须要让过滤器继续前行,调用 doFilter 方法:filterChain.doFilter(servletRequest, servletResponse);

2. 实现步骤

实现 Filter 过滤器的步骤有三步:导入依赖、编写过滤器、在 web.xml 中进行配置。

测试:编写一个处理中文乱码的过滤器,对过滤前后的输出进行对比。

  • 创建一个普通 Maven 项目(不创建模块了),然后转换为 Web 项目(右键项目,选择 Add Framework Support...

  • pom.xml 中添加依赖

<!-- Servlet 依赖 -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
</dependency>

<!-- JSP 依赖 -->
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.1</version>
</dependency>

<!-- JSTL 表达式依赖 -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

<!-- standard 标签库 -->
<dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
</dependency>

<!-- mysql 数据库驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.16</version>
</dependency>
  • 编写过滤器,实现 Filter 接口(注意是:javax.servlet.Filter),重写对应的方法

  • 编写一个 Servlet,用来测试

  • web.xml 中进行配置,对过滤器 Filter 的配置与普通 Servlet 的配置类似,只要是 /filter/ 都可以经过过滤
<!-- 用于对比 -->
<servlet>
    <servlet-name>TestServlet</servlet-name>
    <servlet-class>com.Sun3285.servlet.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>TestServlet</servlet-name>
    <url-pattern>/test</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>TestServlet</servlet-name>
    <url-pattern>/filter/test</url-pattern>
</servlet-mapping>

<!-- 对过滤器的配置 -->
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>com.Sun3285.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/filter/*</url-pattern>
</filter-mapping>
  • 配置 Tomcat

3. 运行结果

通过运行结果还可以看到:

  • Web 服务器启动时,过滤器就已经初始化 init 了,随时等待过滤对象出现;

  • Web 服务器关闭的时候,过滤销毁 destroy


二、Filter 应用:实现权限拦截

举例:实现用户登录,用户登陆后才能进入主页,用户注销后就不能进入主页。

思路

  1. 用户登录之后,向 Session 中存放用户的数据,相反,用户注销后,在 Session 中移除用户的数据;
  2. 可能会出现的问题:直接在地址栏中输入成功登录的 url,就可以直接访问成功登录的界面;
  3. 解决上述问题:使用过滤器:在登录之后,跳转成功页面之前走这个过滤器,判断是否有登录的这个过程,如果进行了登录,并且信息正确(此时 Session 中存放了用户的数据),就可以访问成功页面;如果直接在地址栏中输入成功登录的 url(Session 中没有用户的数据),没有权限进入。

1. 登录步骤

  • 三个 JSP 页面:登录页面、登录成功页面、登录失败页面
<%-- login.jsp:登录页面 --%>
<h1>登录</h1>
<form action="${pageContext.request.contextPath}/servlet/login" method="post">
    用户名:<input type="text" name="username"> <br>
    密码:<input type="password" name="password"> <br>
    <input type="submit">
</form>


<%-- success.jsp:登录成功页面 --%>
<h1>登录成功,这是主页</h1>
<h2>
    <a href="${pageContext.request.contextPath}/servlet/logout">注销</a>
</h2>


<%-- error.jsp:登录失败页面 --%>
<h1>登录失败</h1>
<h2>用户名或密码错误,也可能没有权限</h2>
<h3>
    <a href="${pageContext.request.contextPath}/servlet/logout">返回重新登录</a>
</h3>

注意form表单href超链接${pageContext.request.contextPath} 表示当前项目路径

  • 登录LoginServlet.java

  • 注销(退出登录):LogoutServlet.java

  • web.xml 配置
<!-- 登录配置 -->
<servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>com.Sun3285.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/servlet/login</url-pattern>
</servlet-mapping>

<!-- 注销配置 -->
<servlet>
    <servlet-name>LogoutServlet</servlet-name>
    <servlet-class>com.Sun3285.servlet.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>LogoutServlet</servlet-name>
    <url-pattern>/servlet/logout</url-pattern>
</servlet-mapping>

2. 添加的过滤器部分

为了解决用户直接在地址栏中输入成功登录的 url 就可以进入主页的问题,在登录之后,跳转成功页面之前走过滤器

  • 过滤器:LoginFilter.java

  • web.xml 可以配置使用过滤器的时间:只要路径经过 sys ,过滤器就会发生作用,进行过滤
<!-- 过滤器 -->
<filter>
    <filter-name>LoginFilter</filter-name>
    <filter-class>com.Sun3285.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>LoginFilter</filter-name>
    <url-pattern>/sys/*</url-pattern>
</filter-mapping>

3. 运行结果

  • 用户名或密码错误时,跳转到登录错误页面;用户名或密码正确时,跳转到成功页面

  • 当用户不登陆,直接输入成功页面的 url 时,会通过过滤器过滤,跳转到登录错误页面

4. 总结

  • 不同的代码放入不同的包中,如可以分为 filterservletutils 包等,然后分别编写对应的代码;
  • 在编写过滤器时,需要注意,参数类型为 ServletRequest,此时需要强制转换为它的子类 HttpServletRequest,因为现在的 request 不能得到 Session;
  • 过滤时需要加一层,将需要经过过滤的代码或页面放入这一层中,通过 web.xml 配置可以保证这一层的代码或页面都会经过过滤,而其他代码或页面不会受影响。如这里加了 sys 这一层,所有经过 sys 的才都会经过过滤,其他页面不受影响;
  • 项目名是在配置 Tomcat 时设置的,对应了 web 文件夹;
  • 可以把经常使用的变量或常量单独放在一个类中,使用时通过类来调用,这样在修改时,只需要修改一次即可,如这里的常量 USER_SESSION 单独放在了 Constant 类中,使用时通过类直接调用;
  • 通过过滤器的执行过程:先通过过滤器,过滤后放行 chain.doFilter(req, resp),执行 Servlet 或 JSP 后,返回时会再次通过过滤器,此时会从 chain.doFilter(req, resp) 后开始执行,如果没有代码则不执行;
  • 出现重定向次数过多的原因:由于设置或代码问题,导致重定向循环
  • 路径问题
    • 重定向时:路径从项目名开始,即带有项目名的 url 路径
    • 请求转发时:路径是不带有项目名的 url 路径
    • JSP 页面时:路径是带有项目名的 url 路径,获取当前项目路径为:${pageContext.request.contextPath}

注意:这里的 url 路径既可以是在 web.xml 配置好的路径,也可以是 JSP 页面所在位置的路径,项目名对应了 web 文件夹。


三、监听器

步骤:编写监听器、在 web.xml 中进行配置

  • 编写监听器,实现接口(接口有很多),重写方法
// 举例
public class OnlineCountListener implements HttpSessionListener {
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {}

    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {}
}
  • web.xml 中进行配置
<!-- 注册监听器 -->
<listener>
    <listener-class>com.Sun3285.listener.OnlineCountListener</listener-class>
</listener>

注意:

  1. int 类型的数据不能赋值为 null,Integer 类型的数据为引用类型,可以为 null。Integer 类型的数据转换为 int 类型,可以对象调用 intValue 方法。
  2. 每一个请求都对应一个 servlet,每一个 servlet 都需要进行配置
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sun 3285

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值