美文网首页
Filter和Listener编程实践

Filter和Listener编程实践

作者: ERROR505 | 来源:发表于2019-11-30 23:11 被阅读0次

一、实验内容

1、Filter的理解和应用

实现一个禁止缓存的过滤器。

要求和提示:

(1)禁止浏览器缓存所有动态页面;

(2)有3个http响应头字段可以禁止浏览器缓存当前页面,它们在Servlet中的示例代码如下。

response.setDateHeader("Expires",-1);

response.setHeader("Cache-Control","no-cache");

response.setHeader("Pragma","no-cache");

(3)并不是所有的浏览器都能完全支持上面的3个响应头,因此最好是同时使用上面的3个响应头。

代码如下:
ExampleFilter.java

package com.qst.chapter02;
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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebFilter("/ExampleFilter")
public class ExampleFilter implements Filter {


    public ExampleFilter() {
        // TODO Auto-generated constructor stub
    }


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

     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
              
            //HttpServletRequest req=(HttpServletRequest) request;  
            HttpServletResponse res=(HttpServletResponse) response;  
       
            res.setDateHeader("Expires",-1);
            res.setHeader("Cache-Control","no-cache");
            res.setHeader("Pragma","no-cache");
            chain.doFilter(request, response);
            
        }
    public void init(FilterConfig fConfig) throws ServletException {
        // TODO Auto-generated method stub
    }

}

xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>chapter02</display-name>

<filter>
    <filter-name>ExampleFilter</filter-name>
    <filter-class>com.qst.chapter02.ExampleFilter</filter-class>
  </filter>
  
  <filter-mapping>
    <filter-name>ExampleFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

验证方法:打开一个浏览器(不能在编译器自带的浏览器中打开),在网页中右键点审查元素,network中找到页面,如下图

image.png
效果:
有过滤器
image.png
无过滤器
image.png

2、Filter的理解和应用

设计一个简单的IP地址过滤器,根据用户的IP地址进行网站的访问控制。例如:禁止IP地址处在192.168.2网段的用户对网站的访问。
思路:
用字符串模拟一个IP地址,通过过滤器,观察是否能打开网页,网页代码随便一个皆可。
代码:
ExampleFilter.java

package com.qst.chapter02;
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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.Response;

@WebFilter("/ExampleFilter")
public class ExampleFilter implements Filter {

    private String ip;
    private String[] ips;
    public ExampleFilter() {
        // TODO Auto-generated constructor stub
    }


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

     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
              
            HttpServletRequest req=(HttpServletRequest) request;  
            HttpServletResponse res=(HttpServletResponse) response;  
            //模拟IP地址
            String localip="192.168.2.50";
            //拆分字符,提取部分IP地址
            String localipnum=localip.substring(0,localip.lastIndexOf("."));
            if(localipnum.equals("192.168.2"))
            {
                response.getWriter().print("IP:"+localip);
                response.getWriter().print("error!");
            }
            else
            {
                chain.doFilter(request, response);
            }

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

}

效果:
模拟地址192.168.2.50

image.png
模拟地址192.168.1.50(不是禁止的网段即可正常显示)
image.png

3、Listener的理解和应用

通过监听器记录在线用户的姓名,在页面进行用户姓名的显示,同时实现对某个用户的强制下线功能。
思路:
用监听器监听每一次会话的发起和结束,然后将信息保存下来并显示,注意,因为每一次的session会话都是要由不同的客户端发起的,所以你在运行的时候是无法在同一个浏览器测试的,请在多个浏览器打开网页地址同时测试,或者将浏览器关闭再重新打开一个新的会话(但这样的话你就无法关闭上一次会话创建的用户),退出也是只能退出你此次session会话创建的用户。强制下线功能需要在退出代码中查找想要退出用户的sessionID,然后将其移除map即可,下面的代码没有该功能,可以在此代码基础上更改。
代码:
监听器OnlineLoginUserViewListener.java代码

package com.qst.chapter02;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;


/**
 * Application Lifecycle Listener implementation class OnlineLoginUserViewListener
 *
 */
@WebListener
public class OnlineLoginUserViewListener implements HttpSessionAttributeListener {

    /**
     * Default constructor. 
     */
    public OnlineLoginUserViewListener() {
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpSessionAttributeListener#attributeAdded(HttpSessionBindingEvent)
     */
    @SuppressWarnings("unchecked")
    public void attributeAdded(HttpSessionBindingEvent arg0)  { 
        HttpSession session = arg0.getSession();
        //获取表示用户成功登陆后的会话域属性username
        String username = (String) session.getAttribute("username");
        if (username != null) {
            
            //将登陆的用户信息封装到javabean中
            UserSessionInfo userSessionBean = new UserSessionInfo(username,session.getId(), new Date(session.getCreationTime()));
            
            //map表
            Map<String, UserSessionInfo> onlineRegister = (Map<String, UserSessionInfo>) session.getServletContext().getAttribute("onlineRegister");
            if (onlineRegister == null) {
                
                onlineRegister = new HashMap<String, UserSessionInfo>();
            }
            
            //将登录信息保存到map中,key为sessionId
            onlineRegister.put(session.getId(), userSessionBean);
            
            //保存更新后的登陆用户信息
            session.getServletContext().setAttribute("onlineRegister",onlineRegister);
        }
    }

    /**
     * 删除session时
     */
    public void attributeRemoved(HttpSessionBindingEvent arg0)  { 
         // TODO Auto-generated method stub
        if ("username".equals(arg0.getName())) {
            HttpSession session = arg0.getSession();
            
            Map<String, UserSessionInfo> onlineRegister = (Map<String, UserSessionInfo>) session
                    .getServletContext().getAttribute("onlineRegister");     
            onlineRegister.remove(session.getId());   
            session.getServletContext().setAttribute("onlineRegister",
                    onlineRegister);
        }
    }

    /**
     * @see HttpSessionAttributeListener#attributeReplaced(HttpSessionBindingEvent)
     */
    public void attributeReplaced(HttpSessionBindingEvent arg0)  { 
         // TODO Auto-generated method stub
    }
    
}

用户信息javabean,UserSessionInfo.java

package com.qst.chapter02;

import java.io.IOException;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class UserSessionInfo {

    private String username;
    
    private String sessionID;
    
    private Date creationDate;
    
    public UserSessionInfo(){
        
    }

    public UserSessionInfo(String username, String sessionID, Date creationDate) {
        super();
        this.username = username;
        this.sessionID = sessionID;
        this.creationDate = creationDate;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getSessionID() {
        return sessionID;
    }

    public void setSessionID(String sessionID) {
        this.sessionID = sessionID;
    }

    public Date getCreationDate() {
        return creationDate;
    }

    public void setCreationDate(Date creationDate) {
        this.creationDate = creationDate;
    }

}

实时在线用户显示页面onlineLoginUserView.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>view</title>
</head>
<body>
<c:forEach items="${applicationScope.onlineRegister}" var="mapRegister">
        <p>
            用户名:${mapRegister.value.username},会话创建时间:
            <fmt:formatDate value="${mapRegister.value.creationDate}"
                pattern="yyyy-MM-dd HH:mm:ss" /> 
                <a href="logoutPro.jsp">退出</a>            
        </p>
    </c:forEach>
    <a href="loginPro.jsp">注册登录</a>      
</body>
</html>

登陆页面longinPro.jsp

<%@page import="java.util.Random"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户登录</title>
</head>
<body>
    <%
    session.setAttribute("username","用户1"+new Random().nextInt());
    //System.out.print("用户"+new Random().nextInt());
    response.sendRedirect("onlineLoginUserView.jsp");
    %>
    
</body>
</html>

退出页面logoutPro.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户退出</title>
</head>
<body>
    <p>已经退出本系统!</p> 
    
    <%
    //String username =  request.getParameter("username");
    //System.out.print(username);
    session.removeAttribute("username");
    response.sendRedirect("onlineLoginUserView.jsp");
    %>
    
</body>
</html>

运行效果:
未有用户注册时

image.png
有用户注册时(需要打开多个浏览器测试,或者重启浏览器测试)
image.png
退出登陆时(一次会话只能退出当前会话的用户,所以你只能退出一个用户)
image.png

总结

下面是废话,可不看。。。。
过滤器和监听器是java web中非常重要的两个功能,可以帮助我们处理很多逻辑上的问题,通过监听器监听网页发出的请求,就可以及时的对请求进行处理,通过过滤器过滤掉我们不需要的信息,可以大大提高网页运行的效率,也方便程序员对页面操作进行编程。

相关文章

  • Filter和Listener编程实践

    一、实验内容 1、Filter的理解和应用 实现一个禁止缓存的过滤器。 要求和提示: (1)禁止浏览器缓存所有动态...

  • Filter和Listener

    Filter:过滤器 Listener:监听器 Filter(重点) 概念:生活中的过滤器:净水器,空气净化器,土...

  • Filter和Listener

    1.Filter是通过实现Filter接口实现的,重写方法 ①init是开始过滤 ②destroy是结束过滤 ③d...

  • java基础-day42-Filter、Listener和Bas

    Filter ,Listener和BaseServlet 1. Filter过滤器 1.1 Filter过滤器的配...

  • Listener

    Listener与Filter

  • JavaWeb- Filter 和 Listener

    Filter和Listener 1. Filter 概念:Filter(过滤器),当访问服务器资源时,过滤器可以将...

  • 七、Filter和Listener

    Servlet进阶 1.过滤器-Filter 1.1.什么过滤器? 过滤器,即具有拦截过滤的作用的器具。例如:筛子...

  • Servlet学习6--过滤器

    一.过滤器Filter Filter介绍Servlet有三大组件:Servlet,Filter,Listener....

  • Listener and Filter

    Listener监听器 Javaweb开发中的监听器,是用于监听web常见对象HttpServletRequest...

  • Filter,Listener

    Filter基本使用 过滤器Filter作为Web的组件,能对所有Web资源(Jsp,Servlet,,静态图片或...

网友评论

      本文标题:Filter和Listener编程实践

      本文链接:https://www.haomeiwen.com/subject/uesgwctx.html