过滤器与监听器

Posted Vodka~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了过滤器与监听器相关的知识,希望对你有一定的参考价值。

一,过滤器(Filter):
1.用于在Servlet之外对Request 或 Response 进行修改。主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理。
2.过程:对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。
3.在一个web应用中可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。
实例:请求乱码的处理,用户非法访问的拦截
4.在HttpServletRequest 到达 Servlet之前,拦截客户的HttpServletRequest。 根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据。
5.在HttpServletResponse 到达客户端之前,拦截 HttpServletResponse。根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。

@WebFilter("/One")
public class FilterTest implements Filter {
    @Override
    public void init(FilterConfig fc) throws ServletException{

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//           doFilter();放行方法前做请求拦截
            System.out.println("正在过滤/One 链接的请求资源");
//            设置可放行资源 ,如果不设置,则服务器将收不到相应的url请求
           filterChain.doFilter(servletRequest,servletResponse);
//           doFilter();  放行方法后做响应拦截
            System.out.println("Filter处理响应");
    }

    @Override
    public void destroy() {

    }
}




//处理请求乱码问题
@WebFilter("/*")
public class FilterTest implements Filter {
    @Override
    public void init(FilterConfig fc) throws ServletException{

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//             基于HTTP
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

//        处理post请求乱码
        request.setCharacterEncoding("UTF-8");

//        处理GET请求且服务器版本在Tomcat8以下的
        String method = request.getMethod();
//        若是Get请求
        if("GET".equalsIgnoreCase(method)){
//            获取服务器版本
            String ServerInfo = request.getServletContext().getServerInfo();
            String version = ServerInfo.substring(ServerInfo.indexOf("/")+1,ServerInfo.indexOf("."));
//            判断服务器是否小于8
            if(Integer.parseInt(version) < 8){
//    得到自定义内部类,MyWapper 继承了HttpServletRequestWapper对象,而HttpServletRequestWapper对象实现了
//                HttpServletRequest接口,所以MyWapper的本质也是request对象
                HttpServletRequest myRequest = new MyWapper(request);
//                放行资源
                filterChain.doFilter(myRequest,response);
                return ;
            }
        }
//        这里放行的资源是post请求的
        filterChain.doFilter(request,response);
    }

    @Override
    public void destroy() {

    }
}
//Mywapper,自定义的Request包装类
public class MyWapper  extends HttpServletRequestWrapper {
//    定义成员变量,提升构造器中的request对象的范围
    private HttpServletRequest req;
    public MyWapper(HttpServletRequest request) {
        super(request);
        this.req = request;
    }
// 重写getParameter()方法
    @Override
    public String getParameter(String name){
        String val = req.getParameter(name);

        if(val != null && "".equals(val.trim())){
            try{
//                将默认的ISO-8859-1编码的字符转换成UTF-8
                val = new String(val.getBytes("ISO-8859-1"),"UTF-8");
            } catch (UnsupportedEncodingException e){
                e.printStackTrace();
            }
        }
        return val;
    }
}




//用户非法访问拦截
 *  非法访问拦截(即当用户未登录时,拦截需要登录授权才能使用的请求)
 *       拦截的资源:   所有,“/*”
 *       可放行访问的资源:
 *                 -不需要登录就能访问的页面:(登录页面,注册页面等)
 *                 -静态资源:(css,js,image等)
 *                 -放行指定操作(登录操作,注册操作等)
 *                 -登录状态放行(如果存在指定sessuin对象,则为登录状态)
 */
public class BlockIllegalAccess implements Filter {

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

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//                      将变量转换成基于HTTP实现
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse res = (HttpServletResponse) servletResponse;

//        得到请求路径
        String UrlPath = req.getRequestURI();     //      站点名/资源路径

//        放行可访问的资源
        if(UrlPath.contains("/Login.jsp") || UrlPath.contains("/Register.jsp")){
            filterChain.doFilter(req,res);
            return;
        }
        if(UrlPath.contains("/js") || UrlPath.contains("/css") ||UrlPath.contains("/image")){
            filterChain.doFilter(req,res);
            return;
        }
        if(UrlPath.contains("/Login") || UrlPath.contains("/Register") || UrlPath.contains("/ElseOperation")){
            filterChain.doFilter(req,res);
            return;
        }
        //        获取用户登录状态
        HttpSession hsr = req.getSession();
        String UserStatus = (String) hsr.getAttribute("UserStatus");

        if(UserStatus.equals("0")){
            //当用户未登录时,拦截请求跳转到登录页面
            res.sendRedirect("Login.jsp");
            
        } else{
            filterChain.doFilter(req,res);
            return;
        }

    }

    @Override
    public void destroy() {

    }
}

二,监听器:
1.web监听器是Servlet中一种的特殊的类,能帮助开发者监听web中的特定事件,如:
SevletContext,HttpSession, ServletRequest等的创建和销毁,其变量的创建和销毁,修改等,
可以在某些动作前后增加处理,实现监控。
2. 实例:在线人数统计
3.监听器有三类:
-监听生命周期:
ServletRequestListener
HttpSessionListener
ServletContextListener

             -监听属性的值的变化:
                     ServletRequestAttributeListener
                     ServletSessionAttributeListener
                     ServletContextAttributeListener
          
             -监听Session中的对象:
                    监听Session中java对象(javaBean),是javaBean直接实现监听器的接口。 
//监听Session创建和销毁的类
@WebListener("/*")
public class ListenerTest implements HttpSessionListener {

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("Session被创建了");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
         System.out.println("Session被销毁了");
    }
}

@WebServlet("/SessionTest")
public class TestServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        HttpSession MySession  = req.getSession();
        MySession.setAttribute("Name","vodka");

    }
}


@WebServlet
public class SessionDestroy extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
//      销毁对象
        req.getSession().invalidate();
    }
}




//监听在线人数
@WebListener
public class DetectedNumbers implements HttpSessionListener {

//    定义一个变量记录登录人数
    private int PeopleNumbers = 0;
    @Override
    public void sessionCreated(HttpSessionEvent hse) {
        System.out.println("session已建立");
        PeopleNumbers++;
//    将人数变量存进ServletContext作用域
        hse.getSession().getServletContext().setAttribute("PeopleNumbers",PeopleNumbers);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent hse) {
        PeopleNumbers--;
//        修改人数
        hse.getSession().getServletContext().setAttribute("PeopleNumbers",PeopleNumbers);
        System.out.println("session被销毁了");
    }
}





@WebServlet("/PeopleNum")
public class DetectedServer extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

//             设置响应编码
             resp.setContentType("text/html;charset=UTF-8");
        HttpSession session = req.getSession();
//        获取参数key ,判断是否为空,若不为空,则退出
             String key = req.getParameter("key");
             if(key != null && "logout".equals(key)){
//                  销毁session对象
                 session.invalidate();
                 return;
             }

        ServletContext sc =  session.getServletContext();
             int nums = (int) sc.getAttribute("PeopleNumbers");
             resp.getWriter().write("<h1>当前在线人数为:"+ nums+"</h1> <a href='PeopleNum?key=logout'>退出</a>");
    }
}

以上是关于过滤器与监听器的主要内容,如果未能解决你的问题,请参考以下文章

片段 - 全局视图变量与本地和内部类侦听器和内存泄漏

从父片段到选项卡片段的接口侦听器不起作用

Spring中过滤器+监听器的使用

Recyclerview 滚动在嵌套滚动视图中的片段中不起作用

重学SpringBoot系列之生命周期内的拦截过滤与监听

Listener监听器与Filter过滤器