过滤器与拦截器的区别

虽已工作多年,但对于过滤器与拦截器还是搞不清楚,今天特意留心学习了下:

1、拦截器是基于java的反射机制的,而过滤器是基于函数回调
2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器
3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用
4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能
5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次

1.过滤器

Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编 码、做一些业务逻辑判断等。其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对请求或响应 (Request、Response)统一设置编码,简化操作;同时还可进行逻辑判断,如用户是否已经登陆、有没有权限访问该页面等等工作。它是随你的 web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁

例:

public class ChineseFilter implements Filter {

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp,
            FilterChain chain) throws IOException, ServletException {
        // TODO Auto-generated method stub
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        chain.doFilter(req, resp);
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }

<!-- 编码过滤器 -->
    <filter>
        <filter-name>ChineseFilter</filter-name>
        <filter-class>com.dianzhi.filter.ChineseFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>ChineseFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

<filter>

例2:url

public class ChinaFilter implements Filter {

    public void destroy() {
        // TODO Auto-generated method stub

    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        String uri = req.getRequestURI();// /web1.0/admin/index.jsp
        // StringBuffer url
        // =req.getRequestURL();//http://localhost:8080/web1.0/admin/index.jsp
        String path = req.getContextPath();// /web1.0
        String reqPath = uri.substring(path.length());// /admin/login.jsp
        // System.out.println(uri);
        // System.out.println(path);
        // System.out.println(reqPath);
        if (reqPath.startsWith("/admin") && !reqPath.startsWith("/admin/js")
                && !reqPath.startsWith("/admin/css")
                && !reqPath.startsWith("/admin/images")){
            if(reqPath.equals("/admin/login.jsp")){
                chain.doFilter(request, response);
                return;
            }else{
                Users u=(Users)req.getSession().getAttribute("loginUser");
                if(u==null){
                    res.sendRedirect(req.getContextPath()+"/admin/login.jsp");
                    return;
                }else{
                    chain.doFilter(req, res);
                }
            }
            
        }else{
            chain.doFilter(req, res);
            
        }

    }
    
     /* public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        // TODO Auto-generated method stub
            
            HttpServletRequest req = (HttpServletRequest) request;
            HttpServletResponse res = (HttpServletResponse) response;
            String uri = req.getRequestURI();// /web/admin/index.jsp
            String path = req.getContextPath();// /web
            String reqpath = uri.substring(path.length());
            if(reqpath.startsWith("/admin")&&!reqpath.startsWith("/admin/csss")&&!reqpath.startsWith("/admin/images")&&!reqpath.startsWith("/admin/js")){
                if(reqpath.equals("/admin/login.jsp")){
                    chain.doFilter(request, response);
                    return;
                }else{
                    Users u = (Users) req.getSession().getAttribute("loginUser");
                    if(u==null){
                        res.sendRedirect(req.getContextPath()+"/admin/login.jsp");
                        return;
                    }else{
                        chain.doFilter(req, res);
                    }
                    
                }
                
                
            }else{
                chain.doFilter(req, res);
            }
            
    }
*/
    

    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub

    }

}

2.监听器

监听器:一个类一个实现监听器接口的类一个要在web.xml配置的类

现在来说说Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener 接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。主要作用是: 做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等等。

监听对象:request,session,application

何时监听:
监听器就是可以在       
       application,session,request三个对象
       创建消亡或者往其中
       添加修改删除属性时
       自动执行代码的组件
监听器接口:

request

ServletRequestAttributeListener

ServletRequestListener

session

HttpSessionAttributeListener

HttpSessionListener

application

ServletContextAttributeListener

ServletContextListener

web.xml

<listener>

  <listener-class>com.wangwang.ContextListener</listener-class>

</listener>

案例:统计网站在线数

public class InitNumberServletContextListener implements ServletContextListener{

    public void contextDestroyed(ServletContextEvent arg0) {
        
    }

    public void contextInitialized(ServletContextEvent event) {
        ServletContext application = event.getServletContext();
        //在线人数
        application.setAttribute("onLineCount", 0);
        //到目前为止访问量
        application.setAttribute("fangke", 0);
        //最高在线人数
        application.setAttribute("maxOnLineCount", 0);
    }

public class HttpSessionListenerImpl implements HttpSessionListener{

    public void sessionCreated(HttpSessionEvent event) {
        ServletContext application = event.getSession().getServletContext();
        //在线人数加一
        int onLineCount = Integer.parseInt(application.getAttribute("onLineCount").toString());    
        onLineCount ++;
        application.setAttribute("onLineCount", onLineCount);
        
        //累积访问人次加一
        int fangke = Integer.parseInt(application.getAttribute("fangke").toString());
        fangke ++;
        application.setAttribute("fangke", fangke);
        event.getSession().setAttribute("myweizhi", fangke);
        
        
        int maxOnLineCount = Integer.parseInt(application.getAttribute("maxOnLineCount").toString());
        //如果现在的在线人数大于最大在线人数
        if (onLineCount > maxOnLineCount) {
            application.setAttribute("maxOnLineCount", onLineCount);
            String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            application.setAttribute("maxOnLineCountDate", dateStr);
        }
        
    }

    public void sessionDestroyed(HttpSessionEvent event) {
        //在线人数减一
        ServletContext application = event.getSession().getServletContext();
        int onLineCount = Integer.parseInt(application.getAttribute("onLineCount").toString());
        onLineCount --;
        application.setAttribute("onLineCount", onLineCount);
    }

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <listener>
      <listener-class>com.yun4j.HttpSessionListenerImpl</listener-class>
  </listener>
  <listener>
      <listener-class>com.yun4j.InitNumberServletContextListener</listener-class>
  </listener>
</web-app>

index.jsp

<%@ page language="java" contentType="text/html; charset=gbk"%>
<html>
  <head>
    <title>网站人数统计</title>
  </head>
 
  <body>
 
        您好,您是本网站第${sessionScope.myweizhi}位访客.<br>
        目前的在线人数为${applicationScope.onLineCount}位.<br>
        本网站在${applicationScope.maxOnLineCountDate}达到了最多访问人数,为${applicationScope.maxOnLineCount}位<br>
        
        <hr>
        您好,您是本网站第<%=session.getAttribute("myweizhi")%>位访客.<br>
        目前的在线人数为<%=application.getAttribute("onLineCount")%>位.<br>
        本网站在<%=application.getAttribute("maxOnLineCountDate")%>达到了最多访问人数,
        为<%=application.getAttribute("maxOnLineCount")%>位<br>
        <a href="invalidate.jsp">注销</a>
  </body>
</html>

invalidate.jsp

<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
    session.invalidate();

%>
//其是有一个严重问题就是如果是当前的访问量可以用session,但是如果是累计访问量就不能用application对象(如果是需要登陆的系统就不能用),如果上下文一消失,累计访问量就又成了0,所以应该在用户登陆后,把累计的数据写到一个文件中,用户登陆时,再从文件中读取文件。

3.拦截器

拦截器是在面向切面编程中应用的,就是在你的service或者一个方法前调用一个方法,或者在方法后调用一个方法。是基于JAVA的反射机制。拦截器不是在web.xml,比如struts在struts.xml中配置

原文地址:https://www.cnblogs.com/chizizhixin/p/5383613.html