06-JavaWEB_Filter和Listener

目录

一,cookie介绍

1,什么是会话跟踪技术

2,什么是cookie

二,cookie使用(实例演示)

三,cookie常用方法

1,删除cookie

2,Cookie的有效时间

四,session使用

1,什么是session

2,创建session的格式

3,session的生命周期

4,常用方法

5,session应用

5.1 登录

5.2 退出

五,cookie和session的区别

六,过滤器

1,什么是过滤器

2,过滤器的语法格式

3,代码演示

4,应用场景

七,监听器

1,什么是监听器

2,监听器的分类

3,代码演示

4,监听三大域对象的创建与销毁的监听器

4.1 生命周期

4.2 ServletContextListener

4.3 HttpSessionListener 

4.4 ServletRequestListener 


一,cookie介绍

1,什么是会话跟踪技术

会话跟踪是Web程序中常⽤的技术,⽤来跟踪⽤户的整个会话。保持对⽤户会话期间的数据管理。常⽤的会话跟踪技术是Cookie与Session。

  • Cookie通过在客户端记录信息确定⽤户身份。(一般存放不太重要的信息,防止被破解非法获取)
  • Session通过在服务器端记录信息确定⽤户身份。(重要信息存在这里)

2,什么是cookie

Cookie是客户端(⼀般指浏览器)请求服务器后,服务器发给客户端的⼀个辨认标识,保存在客户端,当客户端再次向服务器发送请求时,会携带着这个辨认标识,服务器就可以通过这个标识来识别客户端的身份或状态等。

Cookie的作⽤:跟踪会话,记录⼀次会话中(即Session,⼀次会话可能会有多次请求,当然也可以有多个Cookie来跟踪不同的信息)的信息,这样服务器就会知道⽤户的状态,⽐如有没有登录成功,付款时购物⻋中的东⻄等,就相当于贴在客户端脑⻔上的纸条,浏览器看不到,但服务器看得到。

 

二,cookie使用(实例演示)

1,创建web项目,引入【javaee-api-7.0.jar、jstl.jar、standard.jar】,在web目录下编写index.jsp,实现简单的登录页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <h1>登录</h1>
  <form action="login" method="post">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="pass"><br>
    <input type="submit" value="login">
  </form>
  </body>
</html>

2,编写简单的LoginServlet,并通过注解进行配置

package com.xrh.servlet;

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 java.io.IOException;

@WebServlet(urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.sendRedirect("error.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.接收参数
        String username = req.getParameter("username");
        String pass = req.getParameter("password");
        //2.判断正误
        if("admin".equals(username)&&"123456".equals(pass)){
            //登录成功
            resp.sendRedirect("success.jsp");
        }else{
            //登录失败(重定向到登录页面)
            resp.sendRedirect("index.jsp");
        }
    }
}

3,简单编写error.jsp、success.jsp

4,运行查看效果

5,填写完用户名/密码后,刷新页面,就会发现之前填写在输入框内的东西消失了,但在某些场景下,需要保存用户名/密码,这时就要引入cookie了。在LoginServlet中登陆失败跳转页面之前,添加cookie

package com.xrh.servlet;

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

@WebServlet(urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.sendRedirect("error.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.接收参数
        String username = req.getParameter("username");
        String pass = req.getParameter("password");
        //2.判断正误
        if("admin".equals(username)&&"123456".equals(pass)){
            //登录成功
            resp.sendRedirect("success.jsp");
        }else{
            //登录失败
            //1.后台创建cookie
            Cookie cookie = new Cookie("uname",username);
            //2.返回给前端
            resp.addCookie(cookie);
            resp.sendRedirect("index.jsp");
        }
    }
}

6,在index.jsp中通过小脚本,获取cookie,并显示

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>

  <%
    Cookie[] cookies = request.getCookies();
    String value ="";
    if(cookies!=null&&cookies.length>0){
      for (Cookie cookie : cookies) {
        if(cookie.getName().equals("uname")){
          value = cookie.getValue();
          break;
        }
      }
    }
    pageContext.setAttribute("unamecookie",value);

  %>

  <h1>登录</h1>
  <form action="login" method="post">
    用户名:<input type="text" name="username" value="${unamecookie}"><br>
    密码:<input type="password" name="password"><br>
    <input type="submit" value="login">
  </form>
  </body>
</html>

7,点击登录后,发现用户名仍为上次填写的输入内容

8,通过工具查看cookie

 

三,cookie常用方法

1,删除cookie

通过设置同名Cookie的最⼤存活时间为0,删除Cookie是指使浏览器不再保存Cookie,使Cookie⽴即失效

举例:使name为username的Cookie⽴即失效

//1.创建⼀个name为username的Cookie
Cookie cookie = new Cookie("username", "aaa");
//2.设置Cookie的有效时间为0
cookie.setMaxAge(0);//删除cookie的关键
//3.将cookie发送给浏览器,来替换同名Cookie
response.addCookie(cookie);

2,Cookie的有效时间

Cookie发送给浏览器以后,浏览器并不会永久保存,也就是到了⼀定的时间以后浏览器会⾃动销毁Cookie。

Cookie的默认有效时间为⼀次会话(⼀次打开关闭浏览器的过程),我们也可以⼿动指定Cookie的有效时间

 //setMaxAge⽤来设置Cookie的最⼤有效时间,需要int型的参数,代表有效的秒数
 cookie.setMaxAge(秒数);
 //当参数⼤于0时,会设置为指定的秒数
 cookie.setMaxAge(30);
 //当参数等于0时,浏览器不会保存Cookie,Cookie⽴即失效
 cookie.setMaxAge(0);
 //当参数⼩于0时,和不设置是⼀样,当前会话有效
 cookie.setMaxAge(-100);
 //设置⼀个永久有效的Cookie,并⾮永久,只是使Cookie的⽣命很⻓⽽已
 cookie.setMaxAge(60*60*24*365*10);

 

四,session使用

1,什么是session

Session是另⼀种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,⽽Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。

如果说Cookie机制是通过检查客户身上的“通⾏证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建⽴的⼀份客户档案,客户来访的时候只需要查询客户档案表就可以了。

2,创建session的格式

Session对应的类为javax.servlet.http.HttpSession类。

每个来访者对应⼀个Session对象,所有该客户的状态信息都保存在这个Session对象⾥。

Session对象是在客户端第⼀次请求服务器的时候创建的。

Session也是⼀种key-value的属性对,通过getAttribute(Stringkey)和setAttribute(String key,Objectvalue)⽅法读写客户状态信息。

Servlet⾥通过request.getSession()⽅法获取该客户的 Session

HttpSession session = request.getSession(); // 获取Session对象
session.setAttribute("loginTime", new Date()); // 设置Session中的属性
out.println("登录时间为:" +(Date)session.getAttribute("loginTime")); // 获取Session属性

3,session的生命周期

Session保存在服务器端。为了获得更⾼的存取速度,服务器⼀般把Session放在内存⾥。每个⽤户都会有⼀个独⽴的Session。

如果Session内容过于复杂,当⼤量客户访问服务器时可能会导致内存溢出。因此,Session⾥的信息应该尽量精简。(不要将大量的无关信息存放在session中)

Session在⽤户第⼀次访问服务器的时候⾃动创建。需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session。

如果尚未⽣成Session,也可以使request.getSession(true)强制⽣成Session。

Session⽣成后,只要⽤户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。⽤户每访问服务器⼀次,⽆论是否读写Session,服务器都认为该⽤户的Session“活跃(active)”了⼀次。由于会有越来越多的⽤户访问服务器,因此Session也会越来越多。为防⽌内存溢出,服务器会把⻓时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就⾃动失效了。

Session的超时时间为maxInactiveInterval属性,可以通过对应的getMaxInactiveInterval()获取,通过 setMaxInactiveInterval(longinterval)修改。

Session的超时时间也可以在web.xml中修改。另外,通过调⽤Session的invalidate()⽅法可以使Session失效。

<session-config> 
 <session-timeout>30</session-timeout>
</session-config>

4,常用方法

5,session应用

5.1 登录

1,账户密码验证正确之后,添加session

package com.xrh.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;

@WebServlet(urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.sendRedirect("error.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.接收参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //2.判断正误
        if("admin".equals(username)&&"123456".equals(password)){
            //登录成功
            //session存值
            HttpSession session = req.getSession();
            session.setAttribute("username",username);
            session.setAttribute("password",password);
            session.setMaxInactiveInterval(60*30);//单位是秒
            //重定向或者转发时,session数据是不会丢失的,重定向时,request中的数据会丢失
            resp.sendRedirect("success.jsp");
        }else{
            //登录失败
            //1.后台创建cookie
            Cookie cookie = new Cookie("uname",username);
            //2.返回给前端
            resp.addCookie(cookie);
            resp.sendRedirect("index.jsp");
        }
    }
}

2,编写success.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>success.jsp</h1>
    当前登录用户:${sessionScope.username}<br>

</body>
</html>

3,输入正确的账号密码之后,成功跳转

5.2 退出

1,在success.jsp中添加退出链接

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
   <h1>success.jsp</h1>
 当前登录用户:${sessionScope.username}<br>

<a href="loginout">退出</a>
</body>
</html>

2,新建LogoutServlet

package servlet;

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 java.io.IOException;

@WebServlet(urlPatterns = "/loginout")
public class LoginOutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 超链接属于get请求,所以只用重写get方法即可
        req.getSession().invalidate();//使session失效
        resp.sendRedirect("index.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

3,运行程序,正确输入账户密码,点击退出后,发现无法获取session

五,cookie和session的区别

Cookie数据保存在客户端,Session数据保存在服务器端。

Session是由应⽤服务器维持的⼀个服务器端的存储空间,⽤户在连接服务器时,会由服务器⽣成⼀个唯⼀的SessionID,⽤该SessionID 为标识符来存取服务器端的Session存储空间。⽽SessionID这⼀数据则是保存到客户端,⽤Cookie保存的,⽤户提交⻚⾯时,会将这⼀SessionID提交到服务器端,来存取Session数据。这⼀过程,是不⽤开发⼈员⼲预的。所以⼀旦客户端禁⽤Cookie,那么Session也会失效

Cookies是属于Session对象的⼀种。但有不同,Cookies不会占服务器资源,是存在客服端内存或者⼀个Cookie的⽂本⽂件中;⽽Session则会占⽤服务器资源。所以,尽量不要使⽤Session,⽽使⽤Cookies。但是我们⼀般认为Cookie是不可靠的,Cookies是保存在本机上的,但是其信息的完全可⻅性且易于本地编辑性,往往可以引起很多的安全问题Session是可靠地。但是⽬前很多著名的站点也都⽤Cookie。

六,过滤器

1,什么是过滤器

过滤器实际上就是对web资源进⾏拦截,做⼀些处理后再交给下⼀个过滤器或servlet处理,通常都是⽤来拦截request进⾏处理的,也可以对返回的response进⾏拦截处理

2,过滤器的语法格式

1,创建⼀个类实现Filter接⼝

public class CharSetFilter implements Filter{}

2,重写接⼝中的⽅法

public void destroy() { //销毁的⽅法}

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
    //过滤⽅法 主要是对request和response进⾏⼀些处理,然后交给下⼀个过滤器或Servlet处理
    chain.doFilter(req, resp);
}

public void init(FilterConfig config) throws ServletException {
    /*初始化⽅法 接收⼀个FilterConfig类型的参数 该参数是对Filter的⼀些配置*/
}

3,在web.xml⽂件中配置

 <filter>
     <filter-name>过滤器名称</filter-name>
     <filter-class>过滤器所在的路径</filter-class>
 </filter>
 
<filter-mapping>
     <filter-name>过滤器名称</filter-name>
     <url-pattern>需要过滤的资源</url-pattern>
 </filter-mapping>

3,代码演示

1,在src/util包中编写FirstFilter类

package util;


import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class FirstFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化filter");//当服务器启动时执行init
    }

    @Override   //请求和响应时都会执行这个方法
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("过滤器开始");

        //调取下一个过滤器,或者调取servlet
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("过滤器结束");

    }

    @Override  //关闭服务器时执行
    public void destroy() {
        System.out.println("销毁filter");
    }
}

2,在web.xml中添加配置

    <filter>
        <filter-name>f1</filter-name>
        <filter-class>
            util.FirstFilter
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>f1</filter-name>
        <url-pattern>/login</url-pattern>
    </filter-mapping>

3,设置多个过滤器。编写过滤器2

package util;

import javax.servlet.*;
import java.io.IOException;

public class SecondFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化2filter");//当服务器启动时执行init
    }

    @Override   //请求和响应时都会执行这个方法
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("过滤器2开始");
        //调取下一个过滤器,或者调取servlet
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("过滤器2结束");

    }

    @Override
    public void destroy() {
        System.out.println("销毁2filter");
    }
}
    <filter>
        <filter-name>f2</filter-name>
        <filter-class>
            util.SecondFilter
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>f2</filter-name>
        <url-pattern>/login</url-pattern>
    </filter-mapping>

4, 观察执行顺序:先开始的后结束,而过滤器1、2哪个先执行取决于配置文件

5,为FirstFilter添加功能,防止未登录的用户访问资源

package util;


import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class FirstFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化filter");//当服务器启动时执行init
    }

    @Override   //请求和响应时都会执行这个方法
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("过滤器开始");
        //处理乱码
        HttpServletRequest request=(HttpServletRequest)servletRequest;
        HttpServletResponse response=(HttpServletResponse)servletResponse;
        request.setCharacterEncoding("utf-8");

        //防止用户在未登录的情况下访问资源
        String requestURI = request.getRequestURI();//获得请求地址
        System.out.println("requestURI="+requestURI);
        Object username = request.getSession().getAttribute("username");

        //用户访问testsession.jsp页面时,若未登录则会跳转到index.jsp
        if(requestURI.endsWith("testsession.jsp")&&username==null){
            response.sendRedirect("index.jsp");
        }

        //调取下一个过滤器,或者调取servlet
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("过滤器结束");

    }

    @Override  //关闭服务器时执行
    public void destroy() {
        System.out.println("销毁filter");
    }
}

6,修改web.xml配置,使所有页面都需执行FirstFilter(/login改为/*)

    <filter>
        <filter-name>f1</filter-name>
        <filter-class>
            util.FirstFilter
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>f1</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

7,运行效果

未登录时访问testsession页面时,会自动跳转到index.jsp。

登陆后可以访问。

退出后访问testsession页面时,会自动跳转到index.jsp。

4,应用场景

  • 3.1.如何防⽌⽤户未登录就执⾏后续操作
 String name=(String)session.getAttribute("key");
 if(name==null){
     //跳转到登录⻚⾯
 }
  • 3.2.设置编码⽅式--统⼀设置编码
  • 3.3.加密解密(密码的加密和解密)
  • 3.4.⾮法⽂字筛选
  • 3.5.下载资源的限制 

过滤器的特点:在servlet之前和之后都会被执⾏

 

七,监听器

1,什么是监听器

监听器就是监听某个域对象的的状态变化的组件

监听器的相关概念:

  • 事件源:被监听的对象(三个域对象 request、session、servletContext)
  • 监听器:监听事件源对象事件源对象的状态的变化都会触发监听器
  • 注册监听器:将监听器与事件源进⾏绑定
  • 响应⾏为:监听器监听到事件源的状态变化时所涉及的功能代码(程序员编写代码)

2,监听器的分类

第⼀维度按照被监听的对象划分:ServletRequest域、HttpSession域、ServletContext域

第⼆维度按照监听的内容分:监听域对象的创建与销毁的、监听域对象的属性变化的

3,代码演示

1,编写SessionListener和AttributeListener

package util;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class SessionListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("session创建");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("session销毁");
    }
}
package util;

import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

public class AttributeListener implements HttpSessionAttributeListener {
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("session存值,"+httpSessionBindingEvent.getName()+","+httpSessionBindingEvent.getValue());
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("session移除数据");
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {

    }
}

2,修改web.xml配置

    <!--配置监听器-->
    <listener>
        <listener-class>util.SessionListener</listener-class>
    </listener>
    <listener>
        <listener-class>util.AttributeListener</listener-class>
    </listener>

3,运行效果

4,监听三大域对象的创建与销毁的监听器

4.1 生命周期

Servlet域的⽣命周期

  • 创建:服务器启动创建
  • 销毁:服务器关闭销毁

HttpSession对象的⽣命周期

  • 创建:第⼀次调⽤request.getSession时创建
  • 销毁:服务器关闭销毁、session过期(默认30分钟,修改默认的30分钟是在Tomcat的web.xml,修改当前项⽬的过期时间是在⾃⼰项⽬的web.xml中)、⼿动销毁

ServletRequest的⽣命周期

  • 创建:每⼀次请求都会创建request
  • 销毁:请求结束

4.2 ServletContextListener

监听ServletContext域的创建与销毁的监听器

  • 初始化的⼯作:初始化对象、初始化数据(加载数据库驱动、连接池的初始化)
  • 加载⼀些初始化的配置⽂件(spring的配置⽂件)
  • 任务调度(定时器—Timer/TimerTask)

4.3 HttpSessionListener 

监听Httpsession域的创建和销毁的监听器

由于每次访问⽹站都会默认创建session对象(jsp⻚⾯中page指令中的session属性默认为true,即被访问时创建session),可以⽤于计数⽹站访问过的⼈

4.4 ServletRequestListener 

监听ServletRequest域创建与销毁的监听器


章节汇总在这里(づ ̄3 ̄)づ╭❤~@&再见萤火虫&【06-JavaWEB】


对学习Java感兴趣的同学欢迎加入QQ学习交流群:1126298731

有问题欢迎提问,大家一起在学习Java的路上打怪升级!(o゜▽゜)o☆[BINGO!]

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值