cookie、session、filter、listener知识点回顾

会话:用户打开一个浏览器,点击了很多超链接,访问了多个web资源,关闭浏览器,这个过程称之为会话(打开浏览器到关闭浏览器的过程)

有状态会话

一个网站,如何证明访问过?

  1. 服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了 这个就是cookie
  2. 服务器登记当前客户端访问过,下次来的时候直接进行匹配 这个就是session

cookie

客户端技术(响应,请求)

从请求中拿到cookie,服务器响应给客户端cookie

cookie是服务器通知客户端保存键值对的一种技术,客户端有了cookie后,每次请求都发送给服务器,每一个cookie 的大小不能超过4kb

常用方法

Cookie[] cookies = request.getCookies();//获得Cookie
cookie.getName();//获得cookie中的key
cookie.getValue();//获得cookie中的value
new Cookie("cookie的名称","cookie的值");//新建一个cookie 注意:这两个参数必须都是String类型
cookie.setMaxAge();//设置cookie的有效期 单位为秒
response.addcookie();//添加一个cookie并响应给客户端

cookie一般保存在本地的用户目录下appdata中

案例:保存用户访问上次访问的时间

package com.hty.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

//保存用户上次访问的时间
public class CookieDemo1Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //服务器告诉用户访问的时间,将这个时间进行封装

        //解决中文乱码
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        PrintWriter out = response.getWriter();

        //Cookie 服务器从客户端获取
        Cookie[] cookies = request.getCookies();//返回数组说明 cookie可能返回多个

        //判断cookie是存在
        if(cookies!=null){
            out.write("你上次访问的时间是:");
            for(int i=0;i<cookies.length;++i){
                Cookie cookie = cookies[i];
                //获取cookie的名字
                if(cookie.getName().equals("lastLoginTime")){
                    //获取cookie中的值
                    long lastLoginTime = Long.parseLong(cookie.getValue());
                    Date date = new Date(lastLoginTime);
                    out.write(date.toLocaleString());
                }
            }
        }else{
            out.write("这是你第一次访问本站");
        }

        //服务器给客户端响应一个cookie  将本次访问的时间写入到cookie中
        Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");

        //给cookie设置有效时间 单位为 秒  此时的时间为一天
        cookie.setMaxAge(24*60*60);

        response.addCookie(cookie);
    }
}

一个网站中cookie存在上限

  • 一个cookie只能保存一个信息
  • 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie
  • 浏览器的上限是300个cookie
  • cookie的大小不能超过4kb

不设置有效期,关闭浏览器,cookie自动失效

设置有效期为0也可以实现自动删除

案例 中文乱码的解决方案

package com.hty.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Date;

//中文数据的传递
public class CookieDemo2Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //Cookie 服务器从客户端获取
        Cookie[] cookies = request.getCookies();//返回数组说明 cookie可能返回多个
        PrintWriter out = response.getWriter();
        //判断cookie是存在
        if(cookies!=null){
            out.write("你上次访问的时间是:");
            for(int i=0;i<cookies.length;++i){
                Cookie cookie = cookies[i];
                //获取cookie的名字
                if(cookie.getName().equals("name")){
                    //获取cookie中的值
                    out.write(URLDecoder.decode(cookie.getValue(),"UTF-8"));
                    System.out.println(cookie.getValue());
                }
            }
        }else{
            out.write("这是你第一次访问本站");
        }
        //使用URLEncoder.encode()方法 这样可以让中文数据不乱码
        Cookie cookie = new Cookie("name", URLEncoder.encode("你好","UTF-8"));
        response.addCookie(cookie);
    }
}

session

服务器技术,利用这个技术可以保存用户的会话信息

什么是session:

  • 服务器会给每一个用户(浏览器)创建一个Session对象
  • 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在
  • 用户登录之后整个网站都可以访问—>保存用户信息;保存购物车信息

案例

package com.hty.servlet;

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

public class SessionDemo1Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //解决乱码问题
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        //得到session
        HttpSession session = request.getSession();

        //给session中存入信息
        session.setAttribute("name","你好");//String Object

        //获取session的id
        String id = session.getId();

        //判断是不是新的session
        if(session.isNew()){
            response.getWriter().write("session创建成功,id为"+id);
        }else{
            response.getWriter().write("session已经在服务器中存在了,id为"+id);
        }

        //Session创建的时候 将这个session值存入了Cookie
        Cookie cookie = new Cookie("JSESSIONID",id);
        response.addCookie(cookie);
    }
}
package com.hty.servlet;

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

public class SessionDemo2Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //取出SessionDemo1中的session
        //解决乱码问题
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        HttpSession session = request.getSession();
        String id = session.getId();
        response.getWriter().write(id);

        //首先需要访问SessionDemo1之后再访问2就可以得到name这个值
        Object name = session.getAttribute("name");
        System.out.println(String.valueOf(name));
    }
}

session的销毁

package com.hty.servlet;

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

public class SessionDemo3Servlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        session.removeAttribute("name");//除session中的某项属性
        //手动注销session
        session.invalidate();//销毁所有session
    }
}

设置session失效时间 在web.xml中进行配置

<!--设置session默认失效时间-->
<session-config>
    <!--15分钟后session失效 以分钟为单位-->
    <session-timeout>15</session-timeout>
</session-config>

Session和Cookie区别

  • cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)
  • session把用户的数据写到用户独占Session中,服务器端保存(保存重要信息,减少服务器资源浪费)
  • session对象由服务器进行创建

Filter

用来过滤网站的数据

用途

  • 处理中文乱码
  • 登陆验证

在web服务器与servlet等资源之间交互的时候,需要使用过滤器来过滤掉不合理的请求

开发步骤

  1. 实现javax.servlet包下的Filter接口
  2. 重写方法
  3. 配置web.xml
package com.hty.filter;

import javax.servlet.*;
import java.io.IOException;
public class CharacterEncodingFilter implements Filter {
    //初始化  web服务器启动就已经初始化了,随时等待过滤对象出现
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化了");
    }

    //China : 链
    /*
    * 过滤中的代码,在过滤特定请求的时候都会执行(特定的请求就是在web.xml中配置的请求)
    * */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("UTF-8");
        servletResponse.setCharacterEncoding("UTF-8");
        servletResponse.setContentType("text/html;charset=UTF-8");

        System.out.println("CharacterEncodingFilter执行前");
        //需要使用filterChain这个对象执行doFilter这个方法才能让过滤器生效
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("CharacterEncodingFilter执行后");
    }
    //销毁  web服务器关闭的时候过滤器就会销毁
    @Override
    public void destroy() {
        System.out.println("销毁了");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>com.hty.filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/servlet/*</url-pattern>
    </filter-mapping>
</web-app>

常见应用

实现权限拦截:用户登陆之后才能进入主页,用户注销之后就不能进入主页

  1. 用户登陆之后向Session中放入用户的数据
  2. 进入主页的时候要判断用户是否已经登陆

过滤器代码

package com.hty.filter;

import com.hty.util.Constant;

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

public class SysFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        Object user_session = request.getSession().getAttribute(Constant.USER_SESSION);
        if(user_session != null){
            response.sendRedirect("http://localhost:8080/filter_war_exploded/sys/success.jsp");
        }else{
            response.sendRedirect("http://localhost:8080/filter_war_exploded/login.jsp");
        }

        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

servlet代码

登陆

package com.hty.servlet;

import com.hty.util.Constant;

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

public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        if(username.equals("admin")){
            //登陆成功
            HttpSession session = request.getSession();
            session.setAttribute(Constant.USER_SESSION,request.getSession().getId());
            response.sendRedirect("http://localhost:8080/filter_war_exploded/sys/success.jsp");
        }else{
            response.sendRedirect("http://localhost:8080/filter_war_exploded/error.jsp");
        }
    }
}

注销

package com.hty.servlet;

import com.hty.util.Constant;

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

public class LogoutServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //注销的时候只需要将和这个session进行消除就可以了
        Object user_session = request.getSession().getAttribute(Constant.USER_SESSION);
        if(user_session != null){
            request.getSession().removeAttribute(Constant.USER_SESSION);
            response.sendRedirect("http://localhost:8080/filter_war_exploded/login.jsp");
        }else{
            response.sendRedirect("http://localhost:8080/filter_war_exploded/error.jsp");
        }
    }
}

常量类

package com.hty.util;

public class Constant {
    public static String USER_SESSION = "USER_SESSION";
}

jsp页面

登陆页面

<%--
  Created by IntelliJ IDEA.
  User: 黄天佑
  Date: 2022-02-16
  Time: 15:24
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>登陆</h1>
    <form action="servlet/login" method="post">
        <input type="text" name="username">
        <input type="submit">
    </form>
</body>
</html>

主页

<%--
  Created by IntelliJ IDEA.
  User: 黄天佑
  Date: 2022-02-16
  Time: 15:23
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%
        //最简单的过滤方法  但是应该使用过滤器来做
//        Object user_session = request.getSession().getAttribute("USER_SESSION");
//        if(user_session == null){
//            response.sendRedirect("http://localhost:8080/filter_war_exploded/login.jsp");
//        }
    %>

    <h1>主页</h1>
    <a href="/filter_war_exploded/servlet/logout">注销</a>
</body>
</html>

错误页面

<%--
  Created by IntelliJ IDEA.
  User: 黄天佑
  Date: 2022-02-16
  Time: 15:30
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>错误</h1>
    <h3>没有权限,用户名错误</h3>
    <a href="http://localhost:8080/filter_war_exploded/login.jsp">返回登陆页面</a>
</body>
</html>

注:记得在web.xml中注册这个过滤器

Listener

实现一个监听器的接口

案例:统计在线人数

package com.hty.listener;

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

//统计在线人数 : 统计session的数量
public class OnlineCount implements HttpSessionListener {
    //创建session监听 看你的一举一动
    //一旦创建一个session就会触发一次这个事件
    public void sessionCreated(HttpSessionEvent se){
        ServletContext servletContext = se.getSession().getServletContext();
        Integer onlinecount = (Integer)servletContext.getAttribute("onlinecount");

        if(onlinecount == null){//说明还没有人访问过
            onlinecount = new Integer(1);
        }else{
            onlinecount++;
        }
        servletContext.setAttribute("onlinecount",onlinecount);
    }

    //销毁session监听
    //一旦Session销毁,就会触发一次这个事件
    public void sessionDestroyed(HttpSessionEvent se){
        ServletContext servletContext = se.getSession().getServletContext();
        Integer onlinecount = (Integer)servletContext.getAttribute("onlinecount");

        if(onlinecount == null){//说明还没有人访问过
            onlinecount = new Integer(0);
        }else{
            onlinecount--;
        }
        servletContext.setAttribute("onlinecount",onlinecount);
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--注册监听器-->
    <listener>
        <listener-class>com.hty.listener.OnlineCount</listener-class>
    </listener>
</web-app>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <h1>当前有<span><%=application.getAttribute("onlinecount")%></span>人在线</h1>
  </body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值