Springmvc之过滤器和监听器

本文详细介绍了如何在Java Web应用中使用Filter进行预处理和后处理,以及监听器如何监听特定事件。涵盖了过滤器配置、拦截示例、乱码解决方案和监听session创建/销毁的应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

过滤器:
Filter即为过滤器,用于在servlet之外对request和response进行修改。它主要用于对用户请求进行预处理,也可以对HttpAervletResponse进行后处理。使用Filter的完整流程,Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称为Filter链。
在这里插入图片描述
过滤器链:执行顺序为,先配置的先执行,后配置的后执行
响应时顺序则相反。

请求用的多,响应配置的较少。
在这里插入图片描述

过滤器拦截例子

对过滤器进行配置(不是基于配置文件的,而是基于一个配置类的)
所拦截的请求路径为/s1
有三个生命周期方法。

@WebFilter("/s1")//如果此处为/*那么所有的请求都会进入到过滤器
public class FilterYZX implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("过滤器初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //拦截请求,进行一些过滤
        System.out.println("过滤器进行了拦截");
        //对资源进行放行,使其进入Servlet。
        filterChain.doFilter(servletRequest, servletResponse);
        //这是必须的,必须对资源进行放行

    }

    @Override
    public void destroy() {
        System.out.println("过滤器进行了销毁");
    }
}
@WebServlet("/s1")
public class Servlet01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("进入到servlet01");
    }
}

当我们访问s1时
在这里插入图片描述

@WebServlet("/s2")
public class Servlet02 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("进入到servlet02");
    }
}

当我们访问s2时,并没有经过过滤器。
在这里插入图片描述
注意:tomcat7及以下版本,get和post请求都会出现乱码问题,都需要进行解决。
tomcat8以上,get请求不会出现乱码,只需要解决post的乱码问题。
post请求乱码问题:
1,request.setCharacterEncoding(“UTF-8”);这样就解决了。
2,配置文件解决
在这里插入图片描述
get请求乱码问题:
1,在代码中体现
String userName = New
String(Request.getParameter(“userName”).getBytes(“ISO8859-1”), “utf-8”);
将 ISO8859-1格式改为utf-8
2,在tomcat的配置文件中修改

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="utf-8" />

3,重写getParameter方法
拦截请求,分析版本,将请求改为utf-8格式。

package OnLine;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

@WebFilter("/*")//拦截所有请求,因为所有的请求都有可能出现乱码问题
public class EcondingFilter implements Filter {
    public EcondingFilter() {
    }

    public void destory() {

    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //处理的乱码请求都是基于HTTP请求的
        //所以我们需要将其转为HttpServletRequest,HttpServletResponse
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;

        //处理post请求乱码问题
        httpServletRequest.setCharacterEncoding("utf-8");

        //获取请求方法
        String method = httpServletRequest.getMethod();
        if (method.equalsIgnoreCase("get")) {
            //获取服务器版本信息,如果低于7.0,那么重写get
            String serverInfo = httpServletRequest.getServletContext().getServerInfo();
            //得到具体的版本号
            String version = serverInfo.substring(serverInfo.indexOf("/") + 1, serverInfo.indexOf("."));
            if (Integer.parseInt(version) < 8) {
                HttpServletRequest myRequest = new MyWapper(httpServletRequest);
                //放行get请求
                filterChain.doFilter(myRequest, httpServletResponse);
                return;
            }
        }
        //放行其他请求
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }

    class MyWapper extends HttpServletRequestWrapper {
        HttpServletRequest request;

        public MyWapper(HttpServletRequest request) {
            super(request);
            this.request=request;
        }

        @Override
        public String getParameter(String name) {
          String value=request.getParameter(name);

          if (value!=null&&!(value.trim()).equals("")){
             try {
                 value=new String(value.getBytes("ISO8859-1"),"utf-8");
             } catch (UnsupportedEncodingException e) {
                 e.printStackTrace();
             }

          }
          return value;
        }
    }

    @Override
    public void destroy() {

    }
}

监听器
web监听器是Servlet中一种特殊的类,能够帮助开发者监听web种特定的事件,比如ServletContext,HttpSession,ServlerRequest的创建和销毁;变量的创建销毁和修改等
可以在某些动作前后进行增加处理,实现监听。例如统计在线人数。
监听器有三类八种
监听器都是接口,接口内的代码内容需要自己实现。

创建session监听器

@WebListener
public class MyListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("监听器监听到创建session");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("监听器监听到销毁session");
    }
}
@WebServlet("/s1")
public class Servlet01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();

    }
}

@WebServlet("/s2")
public class Servlet02 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       req.getSession().invalidate();
    }
}

在这里插入图片描述
监听器小例子:
监听session的创建,当每有一个人开启一个session那么我们监听到了,就会将OnlineNumber+1;

package OnLine;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class OnLineListener implements HttpSessionListener {
    private int OnlineNumber=0;
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("进来了");
        OnlineNumber++;
        se.getSession().setAttribute("OnlineNumber",OnlineNumber);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
         se.getSession().invalidate();
         OnlineNumber--;
        se.getSession().setAttribute("OnlineNumber",OnlineNumber);
    }
}

创建个假的servlet进行请求接收。

@WebServlet("/online")
public class OnLineServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置响应格式,以及编码规则
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().write("当前在线人数为"+req.getSession().getAttribute("OnlineNumber"));
    }
}

bug1:我们不能让tomcat直接进行启动浏览器,否则我们发完请求人数直接为2
设置:
在这里插入图片描述
然后我们自己打开浏览器,自己授敲路径。
bug2:当我们随着session的增加,但是最开始打开的网页的在线人数是不变的??
为什么?
因为session在当前浏览器存活,只要你不关闭,你的数据一直不会变。

解决办法?
扩大存储范围》》》存到整个应用中applicationContext里。

package OnLine;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/online")
public class OnLineServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String key = req.getParameter("key");
        System.out.println(key);
        if(key!=null&&key.equals("yzx")){
            req.getSession().invalidate();
            return;
        }
        //设置响应格式,以及编码规则
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().write("当前在线人数为"+req.getSession().getServletContext().getAttribute("OnlineNumber")+"<a href='online?key=yzx'>退出</a>");
    }
}

该监听器将OnlineNumber放在了整个应用的域上

package OnLine;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class OnLineListener implements HttpSessionListener {
    private int OnlineNumber = 0;

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("进来了");
        OnlineNumber++;
        se.getSession().getServletContext().setAttribute("OnlineNumber", OnlineNumber);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        se.getSession().invalidate();
        OnlineNumber--;
        se.getSession().getServletContext().setAttribute("OnlineNumber", OnlineNumber);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值