3. Filter
3.1 过滤器
参考资料:Java中的Filter过滤器 - 菜鸟-传奇 - 博客园 (cnblogs.com)
过滤器开发(2步):
- 编写java类实现Filter接口,并实现其doFilter方法。
- 在web.xml文件中对编写的filter类进行注册,并设置它所能拦截的资源。
过滤器的生命周期:
public void init(FilterConfig filterConfig) throws ServletException;//初始化
和我们编写的Servlet程序一样,Filter的创建和销毁由WEB服务器负责。 web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次)。开发人员通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;//拦截请求
这个方法完成实际的过滤操作。当客户请求访问与过滤器关联的URL的时候,Servlet过滤器将先执行doFilter方法。FilterChain参数用于访问后续过滤器。
public void destroy();//销毁
Filter对象创建后会驻留在内存,当web应用移除或服务器停止时才销毁。在Web容器卸载 Filter 对象之前被调用。该方法在Filter的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源。
3.2 实例
页面中文字符编码的过滤器(防止中文乱码)
文件结构
依赖包配置(pom.xml)
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
</dependency>
<!--JSTL表达式的依赖-->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl-api -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!--standard标签库-->
<!-- https://mvnrepository.com/artifact/org.apache.taglibs/taglibs-standard-impl -->
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-impl</artifactId>
<version>1.2.5</version>
<scope>runtime</scope>
</dependency>
</dependencies>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>ServletDemo01</servlet-name>
<servlet-class>com.mystudy.servlet.ServletDemo01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo01</servlet-name>
<url-pattern>/servlet/d1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ServletDemo01</servlet-name>
<url-pattern>/d1</url-pattern>
</servlet-mapping>
<!--过滤器配置-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.mystudy.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
</web-app>
过滤器:CharacterEncodingFilter.java
注意:filterChain.doFilter(servletRequest,servletResponse);
public class CharacterEncodingFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterEncodingFilter初始化");
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletResponse.setContentType("text/html;charset=UTF-8");
servletResponse.setCharacterEncoding("UTF-8");
servletRequest.setCharacterEncoding("UTF-8");
System.out.println("CharacterEncodingFilter执行前...");
filterChain.doFilter(servletRequest,servletResponse); //如果不写,程序到此处将会被拦截停止
System.out.println("CharacterEncodingFilter执行后...");
}
public void destroy() {
System.out.println("CharacterEncodingFilter销毁");
}
}
应用:ServletDemo01.java
public class ServletDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("中文乱码过滤器测试!!");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
4. Listen监听
监听器:GUI编程中经常使用
实例
统计在线人数
web.xml
<!--监听配置-->
<listener>
<listener-class>com.mystudy.listen.SessionCountListen</listener-class>
</listener>
SessionCountListen.java
public class SessionCountListen implements HttpSessionListener {
//session创建
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
ServletContext ctx = httpSessionEvent.getSession().getServletContext();
Integer onlienCount = (Integer) ctx.getAttribute("OnlienCount");
if (onlienCount==null){
onlienCount = new Integer(1);
}else {
int count = onlienCount.intValue();
onlienCount = new Integer(count+1);
}
ctx.setAttribute("OnlienCount",onlienCount);
}
//session销毁
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
ServletContext ctx = httpSessionEvent.getSession().getServletContext();
Integer onlienCount = (Integer) ctx.getAttribute("OnlienCount");
if (onlienCount==null){
onlienCount = new Integer(0);
}else {
int count = onlienCount.intValue();
onlienCount = new Integer(count-1);
}
ctx.setAttribute("OnlienCount",onlienCount);
}
}
index.jsp
前端显示servlet值的两种方法:
- <%=xxx.xxx.xxx.getAttribute("参数名")%>
- el表达式:$
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<h1>当前有: <span>
${applicationScope.OnlienCount}
</span> 人在线</h1>
<hr>
<h1>当前有: <span>
<%=this.getServletConfig().getServletContext().getAttribute("OnlienCount")%>
</span> 人在线</h1>
</body>
</html>
5. 过滤、监听的常见应用
filter实现权限拦截:用户登录之后才能进入主页,用户注销后就不能进入主页了。
- 用户登录后,向Session放入用户的数据;
- 进入主页时需判断用户是否已经登录;要求:在过滤器中实现。(若直接通过地址栏进入主页,需要经过Filter判断是否登录)
5.1 实例
将session存在一个常量里:
Constant.java
public class Constant {
public static String USER_SESSION = "USER_SESSION";
}
文件结构
登录:ServletLogin.java
如果登陆成功,往session放一个信息,并且跳转到成功页面
public class ServletLogin extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
if ("admin".equals(username)){// 登陆成功
// 如果登陆成功,往session放一个信息,并且跳转到成功页面
req.getSession().setAttribute(Constant.USER_SESSION,req.getSession().getId());
resp.sendRedirect("/sys/success.jsp");
}else {// 登陆失败
resp.sendRedirect("/error.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
登录页:login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>login</title>
</head>
<body>
<form action="/servlet/login" method="post">
用户名: <input type="text" name="username">
<input type="submit" value="登录">
</form>
</body>
</html>
action="/servlet/login"需要和web.xml里注册的一致
登录失败页:error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登陆失败</title>
</head>
<body>
<h1>登陆失败</h1>
<h2>无权限或用户名错误</h2>
<p><a href="login.jsp">返回登录页面</a> </p>
</body>
</html>
注销:ServletLogout.java
注销页
public class ServletLogout extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 注销登录:判断session是否存在,若存在则移除,并重定向到登录页面
Object user_session = req.getSession().getAttribute(Constant.USER_SESSION);
if (user_session!=null){
req.getSession().removeAttribute(Constant.USER_SESSION); // 移除该session
resp.sendRedirect("/login.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
过滤器:SysFilter.java
public class SysFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// ServletRequest --> HttpServletRequest
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 获取Session,如果为空,则跳转到未登录(登陆错误)页
if (request.getSession().getAttribute(Constant.USER_SESSION)==null){
response.sendRedirect("/error.jsp");
}
filterChain.doFilter(request,response);
}
public void destroy() {
}
}
web.xml
<servlet>
<servlet-name>ServletLogin</servlet-name>
<servlet-class>com.mystudy.servlet.ServletLogin</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletLogin</servlet-name>
<url-pattern>/servlet/login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ServletLogout</servlet-name>
<servlet-class>com.mystudy.servlet.ServletLogout</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletLogout</servlet-name>
<url-pattern>/servlet/logout</url-pattern>
</servlet-mapping>
<!--过滤器配置-->
<filter>
<filter-name>SysFilter</filter-name>
<filter-class>com.mystudy.filter.SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SysFilter</filter-name>
<url-pattern>/sys/*</url-pattern>
</filter-mapping>
分类:
学习笔记
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗