JavaWeb之过滤器&监听器

过滤器(Filter)

它会在一组资源(jsp、servlet、.css、.html等等)的前面执行

它可以让请求得到目标资源,也可以不让请求达到

过滤器有拦截请求的能力

  • 用来拦截传入的请求和传出的响应
  • 修改或以某种方式处理正在客户端和服务端之间交换的数据流
public class CharacterFilter implements Filter {
    @Override    
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, 
   		 FilterChain filterChain) throws IOException, ServletException { 
    
    	servletRequest.setCharacterEncoding("UTF-8");
    	
        filterChain.doFilter(servletRequest,servletResponse);    
    }
}


<filter>  
	<filter-name>charcater</filter-name>  
	<filter-class>my.filter.CharacterFilter</filter-class> 
</filter>
<filter-mapping>  
	<filter-name>charcater</filter-name>  
	<url-pattern>/login</url-pattern>  
	<url-pattern>/test</url-pattern> 
</filter-mapping>

注意: dofilter方法中处理完业务逻辑之后,必须添加filterChain.doFilter(servletRequest,servletResponse);否则请求或者响应无法向后传递。一直停留在过滤器中。

过滤器的创建和配置

  1. 写一个类实现Filter接口

    Filter接口

    ​ void init(FilterConfig)

    • 创建之后,马上执行;Filter会在服务器启动时就创建!
      void destory()

    • 销毁之前执行!在服务器关闭时销毁

      void doFilter(ServletRequest,ServletResponse,FilterChain)

    • 每次过滤时都会执行

    Filter是单例的

    FilterChain

    • doFilter(ServletRequest, ServletResponse):放行
      放行,就相当于调用了目标Servlet的service()方法
    public class CharsetFilter implements Filter{
    	private String charset;
    	@Override
    	public void destroy() {
    		System.out.println("=======destroy==========");
    	}
    
    	@Override
    	public void init(FilterConfig conf) throws ServletException {
    		System.out.println("=======init=====CharsetFilter=====");
    		charset = conf.getInitParameter("charset"); 
    	}
    
    	@Override
    	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    			throws IOException, ServletException {
    		//处理的
    		request.setCharacterEncoding(charset);
    		response.setContentType("text/html;charset=utf-8");
    		System.out.println("======CharsetFilter======="+charset);
    		
    		
    		//"放行" 调用后续的过滤器或资源
    		chain.doFilter(request, response);
    //		response.setCharacterEncoding("utf-8");
    	}
    
    }
  2. 在web.xml中进行配置

      <filter>
        <filter-name>timer</filter-name>
        <filter-class>filter.TimerFilter</filter-class>
      </filter>
      <filter>
        <filter-name>charsetFilter</filter-name>
        <filter-class>filter.CharsetFilter</filter-class>
        <init-param>
          <param-name>charset</param-name>
          <param-value>utf-8</param-value>
        </init-param>
      </filter>
      <filter-mapping>
        <filter-name>timer</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>
      <filter-mapping>
        <filter-name>charsetFilter</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>

生命周期***:

  • 构造方法(加载和实例化) :创建过滤器对象的时候调用。在加载当前项目的时候加载过滤器,只调用1次。单实例的多线程。

  • init方法(初始化) :在创建完过滤器对象之后调用。只调用1次。

  • doFilter方法(过滤): 过滤任务方法。会调用n次。每次访问目标资源的时候,doFilter就会被调用。

  • destory方法:(销毁):在销毁过滤器对象的时候调用。在web项目重新部署或tomcat服务器停止的时候销毁过滤器对象。只调用1次。

加载时间:默认在服务器启动时加载,实例化初始化

问题:Servlet和Filter,谁先启动 ?Filter

同时配置多个Filter,Filter的调用顺序是由web.xml中的配置顺序来决定的,写在上面的配置先调用。

<filter>  
	<filter-name>charcater</filter-name>  
	<filter-class>my.filter.CharacterFilter</filter-class> 
</filter>
<filter-mapping>  
	<filter-name>charcater</filter-name>  
	<url-pattern>/login</url-pattern>  
	<url-pattern>/test</url-pattern> 
</filter-mapping>

注解配置

@WebFilter("/login") 
public class MyFilter implements Filter {

}

什么是过滤器链?

​ chain.doFilter(req,resp); //放行,执行目标资源,或是执行下一个过滤器!如果没有下一个过滤器那么执行的是目标资源,如果有,那么就执行下一个过滤器

过滤器链中过滤器有先后顺序
过滤器在链中的顺序与它在web.xml中配置的顺序有关

初始化配置参数

初始化参数问题:<init-param>

FilterConfig–>与ServletConfig相似

​ Filter接口中的init()方法的参数类型为FilterConfig类型,与web.xml文件中的配置信息对应

  • ServletContext getServletContext():获取ServletContext的方法;

  • String getFilterName():获取Filter的配置名称;与元素对应;

  • String getInitParameter(String name):获取Filter的初始化配置,与元素对应;

  • Enumeration getInitParameterNames():获取所有初始化参数的名称。

  <filter>
    <filter-name>charsetFilter</filter-name>
    <filter-class>filter.CharsetFilter</filter-class>
    <init-param>
      <param-name>charset</param-name>
      <param-value>utf-8</param-value>
    </init-param>
  </filter>

过滤器应用:

​ 登录权限验证、资源访问权限控制、敏感词汇过滤、字符编码转换…

乱码问题:区分请求乱码和响应乱码

request.setCharacterEncoding(charset);

response.setContentType("text/html;charset=utf-8");
请求乱码:
  • get请求:

  • ​ new String(msg.getBytes(“iso-8859-1”),“utf-8”);

  • ​ 修改tomcat配置/conf/server.xml

  • post请求:

    • ​ 过滤器中request.setCharacterEncoding(charset);

路径问题:

//转发  斜杠(工程目录)相对工程的目录
request.getRequestDispatcher("/login.jsp").forward(request, response);
			
//相对路径   相对当前访问的路径
resp.sendRedirect("login.jsp");  //
//绝对路径(IP目录)  /表示ip地址,从ip开始找路径资源
resp.sendRedirect("/login.jsp");  //
			
// http://127.0.0.1:8080/webfilter/login.jsp
resp.sendRedirect("/webfilter/login.jsp");  //

为什么在过滤器中resp.sendReidrect("login.jsp");死循环

		http://ip:8080/webfilter/admin/emp.jsp
	resp.sendRedirect("login.jsp"); 
	等价于
	resp.sendRedirect("http://ip:8080/webfilter/admin/login.jsp")
转发的绝对路径,是工程目录
重定向的绝对路径,是IP服务器目录
相对路径:不是斜杠开头,相对当前访问的目录

监听器(Listener)

​ 监听器用于监听web应用中某些对象、信息的创建、销毁、增加,修改,删除等动作的发生,然后作出相应

的响应处理。当范围对象的状态发生变化的时候,服务器自动调用监听器对象中的方法。

​ 常用于统计在线人数和在线用户,系统加载时进行信息初始化,统计网站的访问量等等。

JavaWeb中的监听器

在JavaWeb被监听的事件源为:ServletContext、HttpSession、ServletRequest,即三大域对象。

  • 监听域对象“创建”与“销毁”的监听器;

  • 监听域对象“操作域属性”的监听器;

  • 监听HttpSession的监听器。

事件源:三大域

  • ServletContext

    生命周期监听:ServletContextListener,它有两个方法,一个在出生时调用,一个在死亡时调用;

    • void contextInitialized(ServletContextEvent sce):创建Servletcontext时

    • void contextDestroyed(ServletContextEvent sce):销毁Servletcontext时

    属性监听:ServletContextAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。

    • void attributeAdded(ServletContextAttributeEvent event):添加属性时;

    • void attributeReplaced(ServletContextAttributeEvent event):替换属性时;

    • void attributeRemoved(ServletContextAttributeEvent event):移除属性时;

  • HttpSession

    生命周期监听:HttpSessionListener,它有两个方法,一个在出生时调用,一个在死亡时调用;

    • void sessionCreated(HttpSessionEvent se):创建session时
    • void sessionDestroyed(HttpSessionEvent se):销毁session时

    属性监听:HttpSessioniAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。

    • void attributeAdded(HttpSessionBindingEvent event):添加属性时;

    • void attributeReplaced(HttpSessionBindingEvent event):替换属性时

    • void attributeRemoved(HttpSessionBindingEvent event):移除属性时

  • ServletRequest

    生命周期监听:ServletRequestListener,它有两个方法,一个在出生时调用,一个在死亡时调用;

    • void requestInitialized(ServletRequestEvent sre):创建request时
    • void requestDestroyed(ServletRequestEvent sre):销毁request时

    属性监听:ServletRequestAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。

    • void attributeAdded(ServletRequestAttributeEvent srae):添加属性时
    • void attributeReplaced(ServletRequestAttributeEvent srae):替换属性时
    • void attributeRemoved(ServletRequestAttributeEvent srae):移除属性时

事件对象:

  • ServletContextEvent:ServletContext getServletContext()

  • HttpSessionEvent:HttpSession getSession()

  • ServletRequest:

    ​ ServletContext getServletContext();

    ​ ServletReques getServletRequest();

  • ServletContextAttributeEvent:

    ​ ServletContext getServletContext();

    ​ String getName():获取属性名

    ​ Object getValue():获取属性值

  • HttpSessionBindingEvent

  • ServletRequestAttributeEvent

分类:

ServletContext对象监听器

HttpSession对象监听器

ServletRequest对象监听器

在这里插入图片描述

public class MyListener implements HttpSessionListener,
		HttpSessionAttributeListener {
 
	public void sessionCreated(HttpSessionEvent e) {
		System.out.println("session创建");
		System.out.println(e.getSession());
	}
 
	public void sessionDestroyed(HttpSessionEvent arg0) {
		System.out.println("session销毁");
	}
 
	public void attributeAdded(HttpSessionBindingEvent arg0) {
		System.out.println("向session添加数据");
	}
 
	public void attributeRemoved(HttpSessionBindingEvent arg0) {
		
	}
 
	public void attributeReplaced(HttpSessionBindingEvent arg0) {
		
	}
 
}


 <listener>
  	<listener-class>web.MyListener</listener-class>
 </listener>

web.xml配置

<!-- 监听器配置 -->
<listener>
	<listener-class>listener.OnlineCountListener</listener-class>
</listener>

注解配置

@WebListener
public class ListenerClass implements ListenerInterface{
    
}

例子

如何统计session个数? session生命周期,tomcat控制的
需要使用Session监听器
如何创建监听器?
实现监听器接口
如何配置监听器?
web.xml中配置监听器,或 使用注解

/**
 * session生命周期监听器
 * 	在线人数统计
 * 	把人数放入application上下文
 *
 */
@WebListener   //注册监听器,告知容器
public class OnlineCountListener implements HttpSessionListener {

	/**
	 * session被创建时执行这里
	 */
    public void sessionCreated(HttpSessionEvent se)  { 
    	HttpSession session = se.getSession();
    	System.out.println("============session创建了======="+session.getId());
         //先获取上下文件对象
    	ServletContext application =  session.getServletContext();
    	Integer count =  (Integer)application.getAttribute("onlineCount");
    	if(count == null) {
    		count = 0;
    	}
    	// 一定不是null
    	count++;
    	application.setAttribute("onlineCount", count);
    
    }

	/**
	 * session被销毁时执行这里
	 */
    public void sessionDestroyed(HttpSessionEvent se)  { 
    	HttpSession session = se.getSession();
    	System.out.println("*************session销毁了======="+session.getId());
    	ServletContext application =  session.getServletContext();
    	Integer count =  (Integer)application.getAttribute("onlineCount");
    	if(count != null) {
    		count--;
    	}
    	application.setAttribute("onlineCount", count);
    }
	
}

两小一大

子类返回类型小于等于父类方法返回类型,
子类抛出异常小于等于父类方法抛出异常,
子类访问权限大于等于父类方法访问权限。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的示例代码,用于演示如何在Java Web项目中使用过滤器监听器来完成用户权限验证功能。请注意,这只是一个演示代码,具体实现方式可能因项目需求和环境而异。 1. 首先,创建一个Java Web项目,并添加一个过滤器(Filter)用于验证用户权限: ``` public class AuthFilter implements Filter { public void init(FilterConfig config) throws ServletException { // 初始化操作 } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 验证用户权限 HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; HttpSession session = req.getSession(false); if (session == null || session.getAttribute(&quot;user&quot;) == null) { // 用户未登录,跳转到登录页面 res.sendRedirect(req.getContextPath() + &quot;/login.jsp&quot;); return; } // 用户已登录,继续处理请求 chain.doFilter(request, response); } public void destroy() { // 销毁操作 } } ``` 2. 接下来,创建一个监听器(Listener),用于记录用户登录和退出的日志: ``` public class LoginLogoutListener implements HttpSessionListener { public void sessionCreated(HttpSessionEvent event) { // 新建session HttpSession session = event.getSession(); System.out.println(&quot;Session created: &quot; + session.getId()); } public void sessionDestroyed(HttpSessionEvent event) { // 销毁session HttpSession session = event.getSession(); System.out.println(&quot;Session destroyed: &quot; + session.getId()); } } ``` 3. 在Web.xml文件中配置过滤器监听器: ``` &lt;filter&gt; &lt;filter-name&gt;AuthFilter&lt;/filter-name&gt; &lt;filter-class&gt;com.example.AuthFilter&lt;/filter-class&gt; &lt;/filter&gt; &lt;filter-mapping&gt; &lt;filter-name&gt;AuthFilter&lt;/filter-name&gt; &lt;url-pattern&gt;/*&lt;/url-pattern&gt; &lt;/filter-mapping&gt; &lt;listener&gt; &lt;listener-class&gt;com.example.LoginLogoutListener&lt;/listener-class&gt; &lt;/listener&gt; ``` 4. 最后,在需要进行用户权限验证的Servlet或JSP页面中添加以下代码段: ``` &lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=UTF-8&quot; pageEncoding=&quot;UTF-8&quot;%&gt; &lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot;%&gt; &lt;c:if test=&quot;${sessionScope.user != null}&quot;&gt; &lt;!-- 用户已登录,继续处理请求 --&gt; &lt;/c:if&gt; ``` 以上是一个简单的示例代码,用于演示如何在Java Web项目中使用过滤器监听器来完成用户权限验证功能。具体实现方式可能因项目需求和环境而异,您可以根据具体情况进行修改和调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值