07.《JavaEE 笔记》Session会话
2024-04-10 10:10:09  阅读数 547

1、会话的概念

客户端向服务器端发送请求,服务器端接受请求并生成响应返回给客户端,客户端对服务器端这样一次连续的调用过程,被称为会话(session)。

Session:记录一系列状态

Session与cookie功能效果相同。Session与Cookie的区别在于Session是记录在服务端的,而Cookie是记录在客户端的。

Cookie与Session的区别

  • session是在服务器端保存用户信息,Cookie是在客户端保存用户信息
  • session中保存的是任意对象,Cookie保存的是字符串
  • session随会话结束而关闭,Cookie可以长期保存在客户端硬盘上,也可以临时保存在浏览器内存中
  • Cookie通常用于保存不重要的用户信息,重要的信息使用session保存

解释session:当访问服务器某个网页的时候,会在服务器端的内存里开辟一块内存,这块内存就叫做session,而这个内存是跟浏览器关联在一起的。这个浏览器指的是浏览器窗口,或者是浏览器的子窗口,意思就是,只允许当前这个session对应的浏览器访问,就算是在同一个机器上新启的浏览器也是无法访问的。而另外一个浏览器也需要记录session的话,就会再启一个属于自己的session

原理:HTTP协议是非连接性的,取完当前浏览器的内容,然后关闭浏览器后,链接就断开了,而没有任何机制去记录取出后的信息。而当需要访问同一个网站的另外一个页面时(就好比如在第一个页面选择购买的商品后,跳转到第二个页面去进行付款)这个时候取出来的信息,就读不出来了。所以必须要有一种机制让页面知道原理页面的session内容。

2. HttpSession接口

Servlet 提供了 HttpSession 接口,该接口提供了一种跨多个页面请求或访问网站时识别用户以及存储有关用户信息的方式。

Servlet 容器使用这个接口来创建一个 HTTP 客户端和 HTTP 服务器之间的 session 会话。会话持续一个指定的时间段,跨多个连接或页面请求。

2.1 如何获取Session接口对象

Servlet API中,定义了HttpSession接口,用来封装会话对象。

HttpSession是接口,不能直接用new创建对象,会话对象是容器创建的,使用HttpServletRequest中的方法获得会话对象。

  • public HttpSession getSession():获取跟当前请求相关的session,如果不存在session,就创建一个新的session对象返回。
  • public HttpSession getSession(boolean create):如果参数create值为true,与无参的getSession方法等同。如果参数create的值是false,那么如果不存在与当前请求相关的session对象,则返回null,如果存在则直接返回会话对象。
  • JSP文件中有内置对象session,可以直接调用HttpSession接口中任意方法

获取当前请求的session会话对象:

HttpSession session = request.getSession();

2.2 常用方法

  1. public Object getAttribute(String name) 通过key获取对象值 。
  2. public void setAttribute(String name, Object value) 以key/value的形式保存对象值。
  3. public Enumeration getAttributeNames() 该方法返回 String 对象的枚举,String 对象包含所有绑定到该 session 会话的对象的名称。
  4. public long getCreationTime() 该方法返回该 session 会话被创建的时间,自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。
  5. public String getId() 获取session对象的编号。
  6. public long getLastAccessedTime() 该方法返回客户端最后一次发送与该 session 会话相关的请求的时间自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。
  7. public int getMaxInactiveInterval() 获取session的有效非活动时间,以秒为单位。
  8. public void setMaxInactiveInterval(int interval) 该方法在 Servlet 容器指示该 session 会话无效之前,指定客户端请求之间的时间,以秒为单位。
  9. public void invalidate() 设置session对象失效,并解除绑定到它上面的任何对象。
  10. public boolean isNew() 判断一个session是不是一个新创建的会话对象。
  11. public void removeAttribute(String name) 通过key删除属性。

2.3 会话属性与请求属性区别

  • 主要区别是有效范围不同。请求中的属性只在当前的请求对象中有效。只有通过请求转发时,才能把当前请求对象转发到下一个资源,其他情况都生成新的请求,所以请求属性也不再可用
  • 会话属性在会话对象中有效。客户端与服务器连接后,只要没有关闭浏览器,服务器也没有出现异常,就是一次会话,会话属性就一直有效。
  • 由于会话对象有效时间长,所以安全性相对低,所占资源相对多,因此:请求属性可以解决的问题就用请求,必须用会话的才用会话。

2.4 删除 Session 会话数据

当您完成了一个用户的 session 会话数据,您有以下几种选择:

  • 移除一个特定的属性:您可以调用 public void removeAttribute(String name) 方法来删除与特定的键相关联的值。
  • 删除整个 session 会话:您可以调用 public void invalidate() 方法来丢弃整个 session 会话。
  • 设置 session 会话过期时间:您可以调用 public void setMaxInactiveInterval(int interval) 方法来单独设置 session 会话超时。
  • 注销用户:如果使用的是支持 servlet 2.4 的服务器,您可以调用 logout 来注销 Web 服务器的客户端,并把属于所有用户的所有 session 会话设置为无效。
  • web.xml 配置:如果您使用的是 Tomcat,除了上述方法,您还可以在 web.xml 文件中配置 session 会话超时,如下所示:
  <session-config>
    <session-timeout>15</session-timeout>
  </session-config>

案例:登录界面、欢迎界面、退出界面

login.jsp(登录界面)

<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Session</title>
</head>
<body>
<form action="login-servlet" method="post">
用户名: <input type="text" name="username">
<br />
密码: <input type="password" name="password" />
<br>
<input type="submit" value="提交" />
</form>
</body>
</html>

LoginServlet.java(登录处理)

package com.company.project.servlet;

import java.io.IOException;
import java.io.PrintWriter;
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 javax.servlet.http.HttpSession;

@WebServlet("/login-servlet")
public class LoginServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public LoginServlet() {
        super();
    }

    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");
        // 假设已经拿到了用户名和密码
        String serverUserName = "86_god";
        String serverPassword = "123456";

        // 获取到客户端的数据
        String username = "";
        String password = "";

        username = request.getParameter("username");
        password = request.getParameter("password");
        System.out.println(username);
        System.out.println(password);
        
        if (username != null && password != null && username.equals(serverUserName)
                && password.equals(serverPassword)) {
            System.out.println("登录成功");
            HttpSession session = request.getSession();
            session.setAttribute("username", username);
            request.getRequestDispatcher("welcome.jsp").forward(request, response);
        }
        else {
            //获取输出流
            PrintWriter out = response.getWriter();
            //生成登录失败界面
            out.println("<html>");
            out.println("<head>");
            out.println("</head>");
            out.println("<body bgcolor=\"deepskyblue\">");
            out.println("<h1>登陆失败</h1>");
            out.println("<p>您输入的用户名或密码不正确,请重新输入</p>");
            out.println("<a href=\"login.jsp\">");
            out.println("<button>重新登录</button>");
            out.println("</a>");
            out.println("</body>");
            out.println("</html>");
            out.close();
        }
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doGet(request, response);
    }
}

welcome.jsp(欢迎界面)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%boolean flag = false;
String username = "";
username = (String)session.getAttribute("username");
if(username != null && username !=""){
    flag = true;
}

%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>欢迎</title>
</head>
<body>
欢迎,
<%
if(flag){
%>
<%= username %>
<a href="logout-servlet">退出</a>
<%  
}else{
%>
<a href="login.jsp">点击登录</a>
<%
}
%>
</body>
</html>

LogoutServlet.java

package com.company.project.servlet;

import java.io.IOException;
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 javax.servlet.http.HttpSession;


@WebServlet("/logout-servlet")
public class LogoutServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public LogoutServlet() {
        super();
      
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        session.invalidate();
        request.getRequestDispatcher("welcome.jsp").forward(request, response);
        
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        doGet(request, response);
    }
}