美文网首页JavaWebJavawebjavaWeb学习
Web应用开发: JSP语法编程实践(六):Filter和Lis

Web应用开发: JSP语法编程实践(六):Filter和Lis

作者: Topus | 来源:发表于2018-11-22 11:58 被阅读175次

    一、实验内容

    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个响应头。
    2、Filter的理解和应用
    设计一个简单的IP地址过滤器,根据用户的IP地址进行网站的访问控制。例如:禁止IP地址处在192.168.2网段的用户对网站的访问。
    3、Listener的理解和应用
    通过监听器记录在线用户的姓名,在页面进行用户姓名的显示,同时实现对某个用户的强制下线功能。

    二、实验要求

    源代码和测试截图(均直接输入到答题框中)

    三、实验原理

    过滤器原理

    直白的说,就是这幅图
    对应的是以下代码里面的三个方法


    屏幕快照 2018-11-22 上午10.32.16.png

    注意web.xml格式

    <filter>
    
             <filter-name>此处给过滤器起一个名字</filter-name>
    
             <filter-class>此处写过滤器实现类的全类名</filter-class>
    
             <init-param>
    
                <param-name>此处填写该过滤器初始化参数的名称</param-name>
    
                <param-value>此处填写该过滤器初始化参数的值</param-value>
    
             </init-param>
    
          </filter>
    
       <filter-mapping>
    
           <filter-name>此处用上边起过的名字</filter-name>
    
           <url-mapping>此处写我们需要过滤哪些URL请求</url-mapping>
    
           <dispacher>REQUEST,FORWORDMINCLUDE.ERROE</dispacher>
    
    

    四、实验代码

    实验1️⃣:

    分为三个文件FirstFilter.java(用于执行过滤器的业务逻辑)、web.xml(用于配置过滤器的映射)、index.jsp(用作展示的页面)

    //FirstFilter.java
    package topus;
    
    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;
    
    /**
     * Servlet Filter implementation class FirstFilter
     */
    @WebFilter("/FirstFilter")
    public class FirstFilter implements Filter {
    
        /**
         * Default constructor. 
         */
        public FirstFilter() {
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see Filter#destroy()
         */
        public void destroy() {
            System.out.println("First Filter------Destory");
        }
    
        /**
         * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
         */
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            
            System.out.println("First Filter------doFilter start");     
            
            //HttpServletRequest req=(HttpServletRequest) request;  
            HttpServletResponse res=(HttpServletResponse) response;  
       
            res.setDateHeader("Expires",-1);// //指定网页在缓存中的过期时间
            res.setHeader("Cache-Control","no-cache");// //HTTP消息头,控制网页的缓存
            res.setHeader("Pragma","no-cache");// //禁止浏览器从缓存中调阅页面内容
    
            // pass the request along the filter chain
            chain.doFilter(request, response);
            
            System.out.println("First Filter------doFilter end");
        }
    
        /**
         * @see Filter#init(FilterConfig)
         */
        public void init(FilterConfig fConfig) throws ServletException {
            System.out.println("First Filter------Init");
        }
    
    }
    
    
    //web.xml
    <?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>shiyan10-1</display-name>
      
      <filter>
        <filter-name>firstFilter</filter-name>
        <filter-class>topus.FirstFilter</filter-class>
      </filter>
      
      <filter-mapping>
        <filter-name>firstFilter</filter-name>
        <!-- 代指所有url -->
        <url-pattern>/*</url-pattern>
      </filter-mapping>
    
    </web-app>
    
    //index.jsp
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <h2>Hello World!</h2>
      
    <%
        System.out.println("index.jsp------");
    %>
    
    </body>
    </html>
    
    实验结果 no-cache

    注意在此,检测办法是在Chrome-右键-检查-network-选择对应文件-header,如果出现no-cache则证明过滤成功

    实验2️⃣:

    思路:访问index.jxp,触发过滤器,筛选IP,若不满足则跳转到error.jsp
    index.jxp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <h2>index!</h2>
      
    <%
        System.out.println("index.jsp------");
    %>
    </body>
    </html>
    

    error.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <h2>error!</h2>
      
    <%
        System.out.println("error.jsp------");
    %>
    </body>
    </html>
    

    IPFilter.jsp

    package topus;
    
    import java.io.IOException;
    //import java.net.InetAddress;
    
    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 org.apache.tomcat.util.codec.binary.StringUtils;
    
    
    /**
     * Servlet Filter implementation class IPFilter
     */
    @WebFilter("/IPFilter")
    public class IPFilter implements Filter {
    
    
        
        /**
         * Default constructor. 
         */
        public IPFilter() {
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see Filter#destroy()
         */
        public void destroy() {
            // TODO Auto-generated method stub
        }
    
        /**
         * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
         */
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest request1  = (HttpServletRequest)request;
            HttpServletResponse response1 = (HttpServletResponse)response;
            
            
            //四种痛苦的尝试
            //1.这里tomcat只能获取IPV6的地址0:0:0:0:0:0:0:1不好判断
            //String ip= request.getRemoteAddr();
            
            //2.如此之判断还是得不到
            /*
            String ip = request1.getHeader("x-forwarded-for");
            if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
                ip = request1.getHeader("Proxy-Client-IP");
            }
            if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
                ip = request1.getHeader("WL-Proxy-Client-IP");
            }
            if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
                ip = request1.getRemoteAddr();
            }
            */
            
            //3.这里用getLocalHost()模拟
            //getLocalHost()仅返回象征本地主机的InetAddress对象
            //InetAddress inet = InetAddress.getLocalHost();
            //String ip= inet.getHostAddress();
            
            //4.这里用字符模拟假的ip实例(前面实力劝退)
            String ip =  "192.165.2.47" ;
            System.out.println("the ip is"+ip);
            
             //拆分字符
             int ad = Integer.parseInt(ip.substring(ip.lastIndexOf(".") + 1));
             
            if(ad >= 1 && ad <= 50){
                response.setContentType("text/html;charset=utf-8");
                //跳转到error.jsp
                request1.getRequestDispatcher("error.jsp").forward(request1, response1);
            }
            else{
                chain.doFilter(request, response);
            }
        }
        
        /**
         * @see Filter#init(FilterConfig)
         */
        public void init(FilterConfig fConfig) throws ServletException {
            // TODO Auto-generated method stub
        }
    
    }
    
    
    IP不符合要求不允许访问

    实验3️⃣:

    实验三比较复杂,思路正确实现起来还是很简单的,项目结构:


    项目结构
    流程图 实验10-3.gif

    login.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>
    <form name="logForm" action="loginPro.jsp" method="get">
        <p>用户名:<input type="text" name="username"></p>
        <p><input type="submit" value="登录"></p>
    </form>
    </body>
    </html>
    

    loginPro.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>
    
    <%      
            String username =  request.getParameter("username");
            session.setAttribute("username",username);
            //直接跳转
            /* response.sendRedirect("users.jsp"); */
        
            if(!username.isEmpty()){
                out.println(username+"登陆成功");
            }else out.println("登陆失败");
    %>
        <a href="users.jsp">跳转到用户中心</a>
    </body>
    </html>
    

    logout.jsp(退出按钮所跳转的界面,用于对退出进行处理)

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8" import="java.util.Map" import="topus.UserSessionInfo" import="topus.MySessionContext"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>用户退出</title>
    </head>
    <body>
        <p>该用户已经退出本系统!</p>
        <a href="users.jsp">跳转到用户中心</a>
        
        <%
        
        String sessionID = request.getParameter("sessionID");
        //out.println(sessionID);
            
        MySessionContext myc= MySessionContext.getInstance();  
        HttpSession sess = myc.getSession(sessionID);  
            
        //HttpSession sess = session.getSessionContext().getSession(sessionID) ;
        sess.invalidate(); // 本次会话对象失效
            //session.removeAttribute("username");
            //response.sendRedirect("users.jsp");
            
            
            
            
            //Map<String, UserSessionInfo> onlineRegister=(Map<String, UserSessionInfo>) application.getAttribute("onlineRegister");
            //onlineRegister.remove(sess.getId());
            //application.setAttribute("onlineRegister",onlineRegister); 
            
            //Map<String, UserSessionInfo> onlineRegister = (Map<String, UserSessionInfo>) session.getServletContext().getAttribute("onlineRegister");
            //onlineRegister.remove(session.getId());
            //session.getServletContext().setAttribute("onlineRegister",onlineRegister);
        %>
        
    </body>
    </html>
    

    users.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>用户管理中心</title>
    </head>
    <body>
    <%-- ${applicationScope.onlineRegister} --%>
    <c:forEach items="${applicationScope.onlineRegister}" var="mapRegister">
            <p>
                用户名:${mapRegister.value.username},会话创建时间:
                <fmt:formatDate value="${mapRegister.value.creationDate}"
                    pattern="yyyy-MM-dd HH:mm:ss" />
                    <%-- sessionID:${mapRegister.value.sessionID} --%>
                    
                    <a href="logout.jsp?sessionID=${mapRegister.value.sessionID}">退出</a>
                    
                    
            </p>
        </c:forEach>
    </body>
    </html>
    

    MySessionAttributeListener.java(SessionAttributeListener监听器,用于监听session的参数,如在logPro.jsp内的session.setAttribute有用到)

    package topus;
    
    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 MySessionAttributeListener
     *
     */
    @WebListener
    public class MySessionAttributeListener implements HttpSessionAttributeListener {
    
        /**
         * Default constructor. 
         */
        public MySessionAttributeListener() {
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpSessionAttributeListener#attributeAdded(HttpSessionBindingEvent)
         */
        @SuppressWarnings("unchecked")
        public void attributeAdded(HttpSessionBindingEvent arg0)  { 
            HttpSession session = arg0.getSession();
            
            String username = (String) session.getAttribute("username");
            if (username != null) {
                
                //给用户模型赋值
                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>();
                }
                
                //将sessionId和用户模型一一对应构成一个单独的个体
                onlineRegister.put(session.getId(), userSessionBean);
                
                //set回去
                session.getServletContext().setAttribute("onlineRegister",onlineRegister);
            }
        }
    
        /**
         * @see HttpSessionAttributeListener#attributeRemoved(HttpSessionBindingEvent)
         */
        @SuppressWarnings("unchecked")
        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
        }
        
    }
    
    

    MySessionContext.java和SessionListener.java 用于完成通过seesionID来获取到session的事件,魔改过来使用
    作者csdn链接:https://blog.csdn.net/sihai12345/article/details/81098765

    
    package topus;
    
    import java.util.HashMap;
    
    import javax.servlet.http.HttpSession;
    
    public class MySessionContext {
        private static MySessionContext instance;  
        private HashMap<String,HttpSession> sessionMap;  
    
        private MySessionContext() {  
            sessionMap = new HashMap<String,HttpSession>();  
        }  
    
        public static MySessionContext getInstance() {  
            if (instance == null) {  
                instance = new MySessionContext();  
            }  
            return instance;  
        }  
    
        public synchronized void addSession(HttpSession session) {  
            if (session != null) {  
                sessionMap.put(session.getId(), session);  
            }  
        }  
    
        public synchronized void delSession(HttpSession session) {  
            if (session != null) {  
                sessionMap.remove(session.getId());  
            }  
        }  
    
        public synchronized HttpSession getSession(String sessionID) {  
            if (sessionID == null) {  
                return null;  
            }  
            return sessionMap.get(sessionID);  
        }  
    
    }
    
    
    package topus;
    
    import javax.servlet.annotation.WebListener;
    import javax.servlet.http.HttpSession;
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;
    
    /**
     * Application Lifecycle Listener implementation class SessionListener
     *
     */
    @WebListener
    public class SessionListener implements HttpSessionListener {
    
        
        private MySessionContext myc = MySessionContext.getInstance();  
        /**
         * Default constructor. 
         */
        public SessionListener() {
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpSessionListener#sessionCreated(HttpSessionEvent)
         */
        public void sessionCreated(HttpSessionEvent se)  { 
             // TODO Auto-generated method stub
            HttpSession session = se.getSession();  
            myc.addSession(session);  
            
        }
    
        /**
         * @see HttpSessionListener#sessionDestroyed(HttpSessionEvent)
         */
        public void sessionDestroyed(HttpSessionEvent se)  { 
             // TODO Auto-generated method stub
            HttpSession session = se.getSession();  
            myc.delSession(session); 
            
        }
        
    }
    
    

    UserSessionInfo.jsp(用于构建用户数据模型的Javabean)

    package topus;
    
    import java.util.Date;
    
    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;
        }
    
    }
    
    

    项目截图:


    5.png 6.png 7.png 1.png 2.png 3.png 4.png 8.png

    相关文章

      网友评论

      • 房东的萨摩耶:小哥哥,我是非计算机专业的,最近才刚刚学习JAVA WEB,看了你的文章感觉对我的帮助很大,我会一直关注你的:relaxed: :relaxed: :relaxed:
        Topus:@房东的萨摩耶 哈哈:smile:感谢

      本文标题:Web应用开发: JSP语法编程实践(六):Filter和Lis

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