过滤器与监听器

一、过滤器

当需要限制用户访问某些资源或者在处理请求时提前处理某些资源的时候,就可以使用过滤器Filter完成。
过滤器是以一种组件的形式绑定到WEB应用程序当中的,与其他的WEB应用程序组件不同的是,过滤器是采用了“链”的方式进行处理的。


1、实现过滤器

在Servlet中,如果要定义一个过滤器,则直接让一个类实现javax.servlet.Filter接口即可,此接口定义了三个操作方法:
public void init(FilterConfig filterConfig) throws ServletException
public void doFilter(ServletRequest request,  ServletResponse response,FilterChain chain) throws IOException,ServletException
public void destroy()

注意:过滤器是在容器启动时自动加载的

2、FilterChain

FilterChain接口的主要作用是将用户的请求向下传递:

public void doFilter(ServletRequest request,ServletResponse response)throws

IOException,ServletException

package org.afanti.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class HelloFilter implements Filter{

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("HelloFilter初始化啦......");
		String admin=filterConfig.getInitParameter("admin");
		System.out.println("接收到传递给HelloFilter过滤器的初始化参数是:"+admin);
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		System.out.println("进入HelloFilter的doFilter()方法了...");
		chain.doFilter(request, response);  // "放行",将请求传递给下一个过滤器,如果没有下一个过滤器则使之请求资源
		System.out.println("准备离开HelloFilter的doFilter()方法...");
	}

	@Override
	public void destroy() {
		System.out.println("HelloFilter销毁了...");
	}

}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>FilterProjectT</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <filter>
    <filter-name>hello</filter-name>
    <filter-class>org.afanti.filter.HelloFilter</filter-class>
    <init-param>
      <param-name>admin</param-name>
      <param-value>obama</param-value>
    </init-param>
  </filter>
<filter-mapping>
    <filter-name>hello</filter-name>
    <url-pattern>/images/*</url-pattern>
  </filter-mapping>
</web-app>

2、Filter的配置方式

方式一:
    注解配置
    @WebFilter(filterName="",urlPatterns={"/images/*"},
     initParams={
     @WebInitParam(name="fruit",value="grape")
     })

方式二:
    web.xml中配置

3、过滤器的过滤路径配置类型

 路径类型一:以目录的方式配置过滤路径:eg: /images/*
 路径类型二:以资源类型的方式配置过滤路径: eg:  *.jpg
 但是,不能将两种路径类型的配置结合起来,否则Web容器启动时发生错误。

4、过滤器的应用
编码过滤
   在过滤器中设置编码

package org.afanti.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class EncodingFilter implements Filter{
	
	private String encode;

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("EncodingFilter初始化了...");
		this.encode=filterConfig.getInitParameter("encode");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		System.out.println("进入EncodingFilter的doFilter...");
		request.setCharacterEncoding(encode);   // 设置请求编码
		chain.doFilter(request, response);// “放行”
		System.out.println("将要离开EncodingFilter的doFilter...");
	}

	@Override
	public void destroy() {
		System.out.println("EncodingFilter销毁了...");
	}

} 

web.xml

<filter>
    <filter-name>encoding</filter-name>
    <filter-class>org.afanti.filter.EncodingFilter</filter-class>
    <init-param>
      <param-name>encode</param-name>
      <param-value>utf-8</param-value>
    </init-param>
  </filter>
 <filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>*.jsp</url-pattern>
  </filter-mapping>

登录验证
   在过滤器中判断session属性是否为空,从而进行登录验证

package org.afanti.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class LoginFilter implements Filter{

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("LoginFilter初始化了...");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		System.out.println("进入LoginFilter的doFilter...");
	    HttpServletRequest req=(HttpServletRequest)request;
	    HttpSession session=req.getSession();
	    if(session.getAttribute("user")!=null){   // 如果session范围中user属性不为null,则说明已经登录
	    	chain.doFilter(request, response);   // “放行”
	    }else{
	    //	String contextPath=request.getServletContext().getContextPath();
	    	request.setAttribute("msg","您还未登录,请先登录!");
	    	request.getRequestDispatcher("/login/login.jsp").forward(request, response);  // 服务端跳转(转发)
	    //	HttpServletResponse resp=(HttpServletResponse)response;
	    	//resp.sendRedirect("/FilterProject/login/login.jsp");
	    }
	    System.out.println("将要离开LoginFilter的doFilter......");
	}

	@Override
	public void destroy() {
		
		
	}

}

web.xml

 <filter>
    <filter-name>loginValidate</filter-name>
    <filter-class>org.afanti.filter.LoginFilter</filter-class>
  </filter>
 <filter-mapping>
    <filter-name>loginValidate</filter-name>
    <url-pattern>/success/*</url-pattern>
  </filter-mapping>

二、监听器

在WEB中可以对application、session、request三种操作进行监听。
Servlet监听器分为三种:
    1.ServletContext监听器(容器监听器)
    2.HttpSession监听器(会话监听器)
    3.ServletRequest监听器(请求监听器)

1、Servlet配置监听器的方式

方式一:
   注解配置: @WebListener

方式二:
       web.xml中配置:
   <listener>
      <listener-class>监听器路径</listener-class>
   </listener>

2、ServletContext监听器

1.对Web容器状态(生命周期)的监听
    实现ServletContextListener接口,覆写相关方法

补充:ServletContextEvent代表容器状态的事件类,里面有个getServletContext()方法

package session;

import java.util.*;

import javax.servlet.http.HttpSession;

public class MySessionUtil {
    private static Map<String,HttpSession> map=new HashMap<String,HttpSession>();  // 用来装session的
    
    public static void addSession(HttpSession session){
    	map.put(session.getId(),session);
    }
    
    // 通过sessionid查询session
    public static HttpSession getSessionById(String sessionId){
    	return map.get(sessionId);
    }
    
    
}
package application;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
// 监听Web容器状态的监听器
@WebListener
public class ContextStateListener implements ServletContextListener{

	@Override
	public void contextInitialized(ServletContextEvent sce) {
		String contextPath=sce.getServletContext().getContextPath();
		System.out.println("容器启动啦,上下文路径是:"+contextPath);
	}

	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		String contextPath=sce.getServletContext().getContextPath();
		System.out.println("容器销毁啦,bye bye~~~,上下文路径是:"+contextPath);
	}

}

2.对ServletContext属性范围的监听
    实现ServletContextAttributeListener接口,覆写相关方法

package application;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class ContextAttributeListener implements ServletContextAttributeListener{

	@Override
	public void attributeAdded(ServletContextAttributeEvent event) {
		String attrName=event.getName();   // 获取属性名
		Object attrValue=event.getValue();   // 获取属性值
		System.out.println("属性添加(add)了,属性名为:"+attrName+";属性值为:"+attrValue);
	}

	@Override
	public void attributeRemoved(ServletContextAttributeEvent event) {
		String attrName=event.getName();   // 获取属性名
		Object attrValue=event.getValue();   // 获取属性值
		System.out.println("属性移除(remove)了,属性名为:"+attrName+";属性值为:"+attrValue);
		
	}

	@Override
	public void attributeReplaced(ServletContextAttributeEvent event) {
		String attrName=event.getName();   // 获取属性名
		Object attrValue=event.getValue();   // 获取属性值
		System.out.println("属性替换(replace)了,属性名为:"+attrName+";属性值为:"+attrValue);
	}

}

3、HttpSession监听器(对会话进行监听)

 (1)对会话状态(生命周期)进行监听
      实现HttpSessionListener接口,覆写相关方法

package session;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
public class SessionStateListener implements HttpSessionListener{

	@Override
	public void sessionCreated(HttpSessionEvent se) {
	   HttpSession session=se.getSession();
	  // session.setMaxInactiveInterval(30);
	   MySessionUtil.addSession(session);   // 将新创建的session添加到工具类的Map集合中
       String sessionid=session.getId(); 	
       System.out.println("新的session创建了,sessionID是:"+sessionid);
	}

	@Override
	public void sessionDestroyed(HttpSessionEvent se) {
		String sessionid=se.getSession().getId(); 	
	    System.out.println("session销毁了,sessionID是:"+sessionid);
	}

}

(2)对会话(HttpSession)属性范围进行监听

      实现HttpSessionAttributeListener接口,覆写相关方法

package session;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
@WebListener
public class SessionAttributeListener implements HttpSessionAttributeListener{

	@Override
	public void attributeAdded(HttpSessionBindingEvent event) {
		String name=event.getName();   // 获取属性名
		Object value=event.getValue();   // 获取属性值
		System.out.println("添加(add)session属性了,属性名是:"+name+";属性值是:"+value);
	}

	@Override
	public void attributeRemoved(HttpSessionBindingEvent event) {
		String name=event.getName();   // 获取属性名
		Object value=event.getValue();   // 获取属性值
		System.out.println("移除session(remove)属性了,属性名是:"+name+";属性值是:"+value);
	}

	@Override
	public void attributeReplaced(HttpSessionBindingEvent event) {
		String name=event.getName();   // 获取属性名
		Object value=event.getValue();   // 获取属性值
		System.out.println("替换session(replace)属性了,属性名是:"+name+";属性值是:"+value);
		
	}

}

(3)对会话(HttpSession)属性范围进行监听———使用HttpSessionBindingListener接口

 实现HttpSessionBindingListener接口,覆写相关方法
特别注意:使用HttpSessionBindingListener接口实现会话属性监听时,不用注册!
实现了HttpSessionBindingListener接口的类,将该类的对象在会话属性范围绑定和解绑属性时,会自动调用valueBound(xxx)方法和valueUnbound(xxx)方法。

package session;

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

// 实现了HttpSessionBindingListener接口的监听器,用来监听session范围的属性,该监听器不用注册!
public class SessionBindingListener implements HttpSessionBindingListener{

	@Override
	public void valueBound(HttpSessionBindingEvent event) {
		String name=event.getName();   // 获取属性名
		Object value=event.getValue();   // 获取属性值
		System.out.println("绑定(bound)session属性了,属性名是:"+name+";属性值是:"+value);
		
	}

	@Override
	public void valueUnbound(HttpSessionBindingEvent event) {
		String name=event.getName();   // 获取属性名
		Object value=event.getValue();   // 获取属性值
		System.out.println("解绑(unbound)session(remove)属性了,属性名是:"+name+";属性值是:"+value);
	}

}

4、ServletRequest监听器(请求监听)

1.对请求状态(生命周期)进行监听
      实现ServletRequestListener接口,覆写相关方法
2.对请求范围的属性进行监听
      实现ServletRequestAttributeListener接口,覆写相关方法














内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索局部开发之间实现平衡。文章详细解析了算法的初始化、勘探开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOAMOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值