javaweb过滤器与监听器

一、过滤器程序的基本结构、web.xml文件的配置过程和过滤器的执行过程

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">

    <filter>
        <filter-name>FirstFilter</filter-name>
        <filter-class>filter.FirstFilter</filter-class>
        <init-param>
            <param-name>course</param-name>
            <param-value>Java EE</param-value>
        </init-param>
    </filter>

    <!-- 配置FirstFilter只拦截test.html  -->
    <filter-mapping>
        <filter-name>FirstFilter</filter-name>
        <url-pattern>/test.html</url-pattern>
    </filter-mapping>

</web-app>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Title</title>
</head>
<body>
    这是一个测试过滤器
</body>
</html>
package filter;

import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;

public class FirstFilter implements Filter { //实现Filter接口

    FilterConfig config = null;//定义一个FilterConfig对象为类的实例变量

    public void init(FilterConfig filterConfig) throws ServletException {
        config = filterConfig;//获取FilterConfig对象引用
    }

    public void destroy() {
        config = null;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        String str = config.getInitParameter("course");//获取过滤器初始参数

        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<font color=blue>前置程序块<br>");
        out.println("过滤器初始参数:course=" + str + "</font><br><br>");

        chain.doFilter(request, response);//调用"过滤器链"方法

        out.println("<br><font color=blue>后置程序块</font><br>");
    }
}

 过滤器需要实现Filter接口,并重写Filter的三个方法:init()、destory()、doFilter()

过滤器的执行顺序:多个过滤器的拦截路径相同时,首先按照<filter-mapping>标记在web.xml中出现的先后顺序执行过滤器,然后按照过滤器类名的字典顺序执行注解的过滤器。

二、注解配置过滤器:字符编码过滤器及权限验证过滤器的实现

package filter;

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.annotation.WebInitParam;
import jakarta.servlet.annotation.WebServlet;

import java.io.IOException;

@WebFilter(filterName = "EncodingFilter", urlPatterns = "/*",
        initParams = {@WebInitParam(name = "encode", value = "UTF-8")})
public class EncodingFilter implements Filter {
    private String encode = null;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        encode = filterConfig.getInitParameter("encode");

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding(encode);
        servletResponse.setContentType("text/html;charset="+encode);
        filterChain.doFilter(servletRequest, servletResponse);

    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
package filter;

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import java.io.IOException;

@WebFilter(filterName = "ValidationFilter", value = "/admin/*")
public class ValidationFilter implements Filter {
    @Override
    public void init(FilterConfig Config) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpSession session = ((HttpServletRequest) request).getSession();
        if(session.getAttribute("user") == null){
            ((HttpServletResponse) response).sendRedirect("login.jsp");
        }
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
<form action="loginServlet">
	<div id="table_div">
		<table align="center">
		    <tr>
				<td colspan="2"><h2>学生信息管理系统</h2></td>
			</tr>
			<tr>
				<td>账号:</td>
				<td><input class="inputinfo" type="text" name="account" placeholder="账号" /></td>
			</tr>
			<tr >
				<td>密码:</td>
				<td><input class="inputinfo" type="password" name="password" placeholder="密码" /></td>
			</tr>
			<tr>
				<td colspan="2"><input id="btn_submit" type="submit" value="登录" /></td>
			</tr>
		</table>
		</div>
	</form>
package 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 implementation class LoginServlet
 */
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String account = request.getParameter("account");
		String password = request.getParameter("password");
		if (account.equals("Sarah") && password.equals("123456")) {
			request.getSession().setAttribute("user", account);
			response.sendRedirect("admin/showAllBooks");
		} else {
			response.sendRedirect("login.jsp");
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

三、application、session两类对象的创建与销毁时间监听

package listener;

import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.ServletRequestEvent;
import jakarta.servlet.ServletRequestListener;
import jakarta.servlet.annotation.WebListener;
import jakarta.servlet.http.HttpSessionEvent;
import jakarta.servlet.http.HttpSessionListener;
//添加监听器注解
@WebListener
//由MyListener类实现ServletContext、HttpSession、ServletRequest三类对象创建、销毁事件的监听
public class MyListener implements ServletContextListener, HttpSessionListener, ServletRequestListener {
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("\n ServletContext对象被创建了");
    }

    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("\n ServletContext对象被销毁了");
    }

    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("\n HttpSession对象被创建了");
    }

    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("\n HttpSession对象被销毁了");
    }

    public void requestDestroyed(ServletRequestEvent sre) {
        System.out.println("\n servletRequest对象被销毁了");
    }

    public void requestInitialized(ServletRequestEvent sre) {
        System.out.println("\n servletRequest对象被创建了");
    }

}

package 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 jakarta.servlet.http.HttpSession;

import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(value="/test")
public class TestServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");

        HttpSession session = request.getSession();//得到会话:如果没有会话,就创建一个

        PrintWriter out = response.getWriter();
        out.println("<html>");
        out.println("<head>");
        out.println("<title>Servlet事件监听</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<h2>创建了一个会话!</h2>");
        out.println("</body>");
        out.println("</html>");
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}
<html>
	<head>
		<title>servlet事件监听器</title>
	</head>
	<body>
		<h2>
			用html文档测试servlet事件监听器
		</h2>
	</body>
</html>

(1)启动Tomcat服务器(如果Tomcat已启动,请先关闭),观察控制台输出的信息。这说明了什么?

答:服务器启动时执行contextInitialized(ServletContextEvent sce)方法。首先servletContext全局对象被创建

(2)打开浏览器,输入http://127.0.0.1:8080/lab6_3/index.html网址,观察控制台输出的信息。这又说明了什么?

答:执行requestInitialized(ServletRequestEvent sre)方法,servletRequest对象被创建,随后自动执行requestDestory(ServletRequestEvent sre)方法,servletRequest对象被销毁了

(3)打开浏览器,输入http://127.0.0.1:8080/lab6_3/test网址,观察控制台输出的信息。这又说明了什么?

答:执行requestInitialized(ServletRequestEvent sre)方法,servletRequest对象被创建,紧接着执行了sessionCreated(HttpSessionEvent se)方法,HttpSession对象被创建,最后自动执行requestDestroyed(ServletRequestEvent sre)方法,servletRequest对象被销毁

问题:web.xml中的如下标记实现什么功能?

    <session-config>

        <session-timeout>1</session-timeout>

    </session-config>

(4)过1分钟之后,再次观察控制台输出的信息。这又说明了什么?

答:实现了1分钟后执行sessionDestoryed(HttpSessionEvent se)方法

请总结applicationsession两类对象创建、销毁事件监听的方法与步骤。注意:不同监听接口、事件、方法的差异。

答:首先要实现ServletContextListener、HttpSessionListener、ServletRequestListener。重写三类对象创建和销毁的事件以便监听。当触发相应的Servlet对象就可以实现相应的监听。

  • ServletContextListener:监听application的产生与销毁
  • HttpSessionListener:监听session的产生与销毁
  • ServletRequestListener:监听request的产生与销毁

四、application、session两类对象属性变化事件监听

package listener;
import jakarta.servlet.*;
import jakarta.servlet.http.*;

//由MySttributeListener类实现application、session两类对象属性变化事件的监听
public class MyAttributeListener implements ServletContextAttributeListener, HttpSessionAttributeListener {
    public void attributeAdded(ServletContextAttributeEvent scae) {
        System.out.println("\n application对象中增加了一个名为" + scae.getName()
                + "的属性,该属性值为" + scae.getValue());
    }

    public void attributeRemoved(ServletContextAttributeEvent scae) {
        System.out.println("\n application对象中的" + scae.getName() + "属性被删除了\n");
    }

    public void attributeReplaced(ServletContextAttributeEvent scae) {
        System.out.println("\n application对象中" + scae.getName() + "的属性值被替换成了"
                + scae.getServletContext().getAttribute(scae.getName()));
    }

    public void attributeAdded(HttpSessionBindingEvent hbe) {
        System.out.println("\n session对象中增加了一个名为" + hbe.getName()
                + "的属性,该属性值为" + hbe.getValue());
    }

    public void attributeRemoved(HttpSessionBindingEvent hbe) {
        System.out.println("\n session对象中的" + hbe.getName() + "属性被删除了\n");
    }

    public void attributeReplaced(HttpSessionBindingEvent hbe) {
        System.out.println("\n session对象中" + hbe.getName() + "的属性值被替换成了"
                + hbe.getSession().getAttribute(hbe.getName()));
    }

}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">

<!--    <session-config>-->
<!--        <session-timeout>1</session-timeout>-->
<!--    </session-config>-->

    <!-- 把MyAttributeListener类设置事件为监听器 -->
    <listener>
        <listener-class>listener.MyAttributeListener</listener-class>
    </listener>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>
<html>
	<head>
		<title>测试session对象属性变化</title>
	</head>
	<body>
		<%@ page contentType="text/html;charset=gb2312"%>
		<H4>
			这是一个测试session对象属性变化的页面
		</H4>
		<%
			session.setAttribute("width", "98.7654");
			session.setAttribute("width", "9876.54");
			session.removeAttribute("width");
		%>
	</body>
</html>
<html>
	<head>
		<title>测试application对象属性变化</title>
	</head>
	<body>
		<%@ page contentType="text/html;charset=gb2312"%>
		<H4>
			这是一个测试application对象属性变化的页面
		</H4>
		<%
			application.setAttribute("length", "123.45");
			application.setAttribute("length", "1234.5");
			application.removeAttribute("length");
		%>
	</body>
</html>

applicationsession两种事件对象的getName()getValue()的功能是什么?如何获得变化过的属性值?

答:getName()获取application或session的属性名;getValue()获取application或session的属性值。

application对象获得变化过的属性值:getServletContext().getAttribute(getName())

session对象获得变化过的属性值:getSession().getAttribute(getName());

(1)打开浏览器,输入http://127.0.0.1:8080/lab6_4/ServletContextAttributeTest.jsp网址,观察控制台输出的信息。这说明了什么? 

答:application对象设置属性时调用attributeAdded(ServletContextAttributeEvent scae)方法,重新更改属性时调用attributeReplaced(ServletContextAttributeEvent scae)方法,删除属性时调用attributeRemoved(ServletContextAttributeEvent scae)方法

(2)在浏览器输入http://127.0.0.1:8080/lab6_4/HttpSessionAttributeTest.jsp网址,观察控制台输出的信息。这又说明了什么?

答:session对象设置属性时调用attributeAdded(HttpSessionBindingEvent hbe)方法,重新更改属性时调用attributeReplaced(HttpSessionBindingEvent hbe)方法,删除属性时调用attributeRemoved(HttpSessionBindingEvent hbe)方法

请总结applicationsession两类对象属性变化事件监听的方法与步骤。注意:不同监听接口、事件差异,在方法名上有什么相似之处?

答:session对象和application对象都是设置属性时调用attributeAdded()方法,重新更改属性时调用attributeReplaced()方法,删除属性时调用attributeRemoved()方法。

ServletContextAttributeListener和HttpSessionAttributeListener包含的方法名称相同,只是参数不同。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值