07.《JavaEE 笔记》Session会话

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);
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容