JavaWeb = Session讲解

前言

session它是一个域对象

三大域对象:ServletContext,Session,Request

注意:

由于客户端需要接收、记录和回送Session对象的ID,因此,通常情况下,Session是借助Cookie技
术来传递ID属性的。

一,Session

(1)使用Cookie的问题:

1,最多存储4k字符串

2,存储数据不太安全

session的作用:在一次会话的多次请求之间共享数据,将数据保存到服务器

(2)HTTPSession也是一个域对象

扫描二维码关注公众号,回复: 11110540 查看本文章
void setAttribute(String name, Object value) 
在session中保存数据 

Object getAttribute(String name) 
从session中获取数据 

void removeAttribute(String name) 
从session中移除数据

使用:

1. 将数据存储到session中
	// 1.通过rquest对象,获取session对象
		HttpSession session = request.getSession();
	// 2.操作session的API,存储数据
		session.setAttribute("username","哈哈,呵呵");

2. 从session中获取数据
	// 1.通过rquest对象,获取session对象
		HttpSession session = request.getSession();
	// 2.操作session的API,获取数据
		session.getAttribute("username");

code:

@WebServlet("/SetSession")
public class SetSession extends HttpServlet {

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

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.通过rquest对象,获取session对象
        HttpSession session = request.getSession();
        // 2.操作session的API,存储数据
        session.setAttribute("username", "哈哈,呵呵");
    }

}

@WebServlet("/GetSession")
public class GetSession extends HttpServlet {

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

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.通过rquest对象,获取session对象
        HttpSession session = request.getSession();
        // 2.操作session的API,获取数据
        String username = (String) session.getAttribute("username");
        System.out.println("GetSession获取:" + username);
    }

}

(3)工作原理

Session基于Cookie技术实现

(4)Session细节

--1.客户端关闭,服务器不关闭

两次获取的Session数据是否为相同:

* 默认情况下,浏览器关闭,再次打开二次获取的session不一样
    基于cookie实现(浏览器关闭,cookie销毁)
    
* 设置cookie的存活时间(JESSIONID)
    这里我们代替服务器,做一个小操作,覆盖这个JSESSIONID,指定持久化时间

--2客户端不关闭,服务器关闭

两次获取的Session数据是否相同?

* 当服务器正常关闭,重启后,二次获取的session数据一样
    tomcat这实现以下二个功能
    钝化(序列化)
        当服务器正常关闭时,session中的数据,会序列化到磁盘
    活化(反序列化)
        当服务器开启后,从磁盘文件中,反序列化到内存中

注意一个问题:Idea问题:

支持钝化,但是在重新启动的时候又会删除了钝化文件,所以导致会变,解决方法如下:

进行打对勾,强制设置idea重启时,不清除Session会话

(4)生命周期:

* 何时创建
		用户第一次调用request.getSession()方法时,创建
		
* 何时销毁
		服务器非正常关闭		
		非活跃状态30分钟后
			tomcat进行配置  /tocmat安装目录/conf/web.xml
		session.invalidate(); 自杀

* 作用范围
		一次会话中,多次请求之间
		注意:每一个浏览器跟服务器都是独立的会话...

(5)URL重写

什么是url重写?
如果浏览器不支持 Cookie 或用户阻止了所有 Cookie ,可以把会话 ID 附加在 HTML 页面中所有的 URL 上,这些页面作为
响应发送给客户。这样,当用户单击 URL 时,会话 ID 被自动作为请求头的一部分而不是作为头行发送回服务器。这种
方法称为 URL 重写 (URL rewriting)
 
作用:
当客户机不接受 cookie 时, server 就使用 URL 重写作为会话跟踪的基本方式 .URL 重写,添加了附加数据 ( 会话 ID) 到请
求的 URL 路径上 .
会话 ID 必须被编码作为该 URL 字符串中的路径参数。该参数的名称为 jsessionid,
简单说就是 cookie 禁用了 jsessionid 就不能携带,那么每次请求,都是一个新的 session 对象。
如果想要使用同一个 session 对象,可以使用 url 重写
 
url 重写实现:
response. encodeRedirectURL(java.lang.String?url)
用于对 sendRedirect 方法后的 url 地址进行重写。
response. encodeURL(java.lang.String?url)
用于对表单 action 和超链接的 url 地址进行重写

Session基于Cookie技术实现;浏览器的Cookie是可以禁用的,一旦禁用了之后,Session就会出现问题了。

开发中,一般我们是不关注用户的cookie是否禁用的,若用户禁用了cookie,只能用其他网站了

若真想处理用户端的cookie禁用,我们可以使用url重写技术:

@WebServlet("/SessionDemo")
public class SessionDemo2 extends HttpServlet {

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

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取session对象
        HttpSession session = request.getSession();
        // 向session中存数据
        session.setAttribute("username", "浏览器禁用了cookie,也不影响我使用");

        // 定义url
        String url = "/dsession/GetSession";

        // 重写url,拼接JSESSIONID
        url = response.encodeURL(url); // /dsession/GetSession?JSESSIONID=xxsdfasdf
        System.out.println(url);

        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("<a href='" + url + "'>跳转到获取session内容</a>");
    }

}

(6)Session特点

1. session存储数据在服务器

2. session存储类型任意(Object)

3. session存储大小和数量没有限制(相对于内存)

4. session存储相对安全

cookie和session的选择

  1. cookie将数据保存在浏览器端,数据相对不安全.建议敏感的数据不要放在cookie中,而且数据大小是有限制的

    1. 成本低,对服务器要求不高

    2. 浏览器,解决这个不足,localStroage【项目二中讲解...】

  2. session将数据保存在服务器端,数据相对安全.数据的大小要比cookie中数据灵活很多

    1. 成本较高,对服务器压力较大

二、三大域对象总结:

request、session、ServletContext

相关API

1. 设置数据
		void setAttribute(String name, Object o)
		
2. 获取数据
		Object getAttribute(String name)
		
3. 删除数据
		void removeAttribute(String name)

生命周期:

ServletContext域对象

* 何时创建
		服务器正常启动,项目加载时,创建

* 何时销毁
		服务器关闭或项目卸载时,销毁

* 作用范围
		整个web项目(共享数据)
针对一个 WEB 应用。一个 WEB 应用只有一个 ServletContext 对象,使用该对象保存的数据在整个 WEB 应用中都有
效。
创建 : 服务器启动的时候 .
销毁 : 服务器关闭的时候或者项目移除的时候 .
 

HTTPSessiont域对象

* 何时创建
		用户第一次调用request.getSession()方法时,创建
		用户访问携带的jsessionid与服务器不匹配时,创建
		
* 何时销毁
		服务器非正常关闭
		未活跃状态30分钟
		自己消灭自己

* 作用范围
		一次会话中,多次请求间(共享数据)
针对一次会话。使用该对象保存数据,一次会话(多次请求)内数据有效。
创建 : 可以暂且认为在服务器第一次调用 getSession() 的时候 . 服务器创建 session 的对象 . 因为 session 销毁后 , 再次
调用 getSession() 的时候也会创建 .
销毁 :
非正常关闭服务器
Session 过期了 , 默认时间是 30 分钟 .
手动调用 session invalidate 的方法
 

HttpServletRequest域对象

* 何时创建
		用户发送请求时,创建
        
* 何时销毁
		服务器做出响应后,销毁

* 作用范围
		一次请求中,多次转发间(共享数据)
针对一次请求。使用该对象保存数据,一次请求(一个页面,如果是请求转发多个页面)内数据有效 .
创建 : 客户端向服务器发送一次请求
销毁 : 服务器为这次请求作出响应之后 , 销毁 request.
 

总结:

  • 能用小的不用大的:request<session<servletContext

  • 常用的场景:

    • request:一次查询的结果(servlet转发jsp)

    • session:存放当前会话的私有数据

      • 用户登录状态

      • 验证码

      • 购物车

  • servletContext:若需要所有的servlet都能访问到,才使用这个域对象.

三 。案例:

1.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>goods.jsp</title>
</head>
<body>
<h3>商品列表</h3>
<a href="/dsession/AddCartServlet?name=电视机">电视机</a><br>
<a href="/dsession/AddCartServlet?name=冰箱">冰箱</a><br>
<a href="/dsession/AddCartServlet?name=洗衣机">洗衣机</a><br>
<a href="/dsession/AddCartServlet?name=电脑">电脑</a><br>
</body>
</html>
@WebServlet("/AddCartServlet")
public class AddCartServlet extends HttpServlet {

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

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8"); // 请求解码
        response.setContentType("text/html;charset=utf-8");// 响应编码

        // 1.获取请求参数
        String product = request.getParameter("name");
        // 2.返回结果
        response.getWriter().write(product + ",商品已成功加入购物车 <br>");

        // 3.从session中获取购物车
        Map<String, Integer> cart = (Map<String, Integer>) request.getSession().getAttribute("cart");

        // 4.判断购物车是否为空
        if (cart == null) {
            cart = new HashMap<>();
        }
        // 5.判断购物车中是否包含本次添加的商品
        if (cart.containsKey(product)) {// 6.存在,数量+1
            Integer oldCount = cart.get(product); // 之前数量
            cart.put(product, oldCount + 1);// 数量加1
        } else { // 7.不存在,直接添加商品,数量为1
            cart.put(product, 1);
        }
        // 8.重新将购物车,写入到session中
        request.getSession().setAttribute("cart", cart);

        // 9.继续浏览
        response.getWriter().write("<a href='/dsession/goods.jsp'>继续浏览</a><br>");
        // 10.查看购物车
        response.getWriter().write("<a href='/dsession/cart.jsp'>查看购物车</a><br>");
    }

}
<%@ page import="java.util.Map" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>cart</title>
</head>
<body>
<h3>购物车页面</h3>

<table border="1" width="200px" align="center">
    <tr>
        <th>商品</th>
        <th>数量</th>
    </tr>
    <%
         // 1.从session中获取购物车
        Map<String,Integer> cart = (Map<String, Integer>) request.getSession().getAttribute("cart");
        // 2.判断是否为空
        if(cart == null){
            out.write("购物车内暂时没有商品<br>");
        }else{
            for (String s : cart.keySet()) {
                out.write("<tr><td>"+s+"</td><td>"+cart.get(s)+"</td></tr>");
            }
        }

    %>
</table>
</body>
</html>

2.用户登录

<%--
  Created by IntelliJ IDEA.
  User: apple
  Date: 2020/4/19
  Time: 18:55
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录</title>

    <style type="text/css">
        .content{
            margin: 0 auto;
            height: 600px;
            width: 800px;
            background-color: white;
        }
        #errormsg{
            font-size: 16px;
            color: red;
        }

        input{
            width: 160px;
            height: 40px;
        }
    </style>
</head>
<body>


<div class="content">
    <h3>用户登录</h3>

    <form action="/day20200419/LoginServlet" method="post">
        <span id="errormsg"></span><br>
        用户名:<input type="text" name="username"><br>
        密码: <input type="password" name="password"> <br>
        验证码:<input type="text" name="checkcode"><img src="/d19/CheckCodeServlet" alt="" id="checkcode"> <br>
        <input type="submit" value="登录">
    </form>
</div>

<script type="text/javascript">
    let elementById = document.getElementById("errormsg");
    <%
     String errormsg = (String) request.getAttribute("errormsg");
    if (errormsg==null||errormsg.length()==0){
        errormsg="";
    }
    %>
    elementById.innerHTML=`<%=errormsg%>`;

    document.getElementById("checkcode").onclick = function () {
        this.src="/d19/CheckCodeServlet?"+new Date().getTime();
    }
</script>


</body>
</html>


<%--
  Created by IntelliJ IDEA.
  User: apple
  Date: 2020/4/19
  Time: 18:55
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录成功</title>
</head>
<body>

<h1>您登录成功了:
<%
    String username = (String) request.getSession().getAttribute("username");
    out.write(username);
%>
</h1>

</body>
</html>
package com.wsl.zy;

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("/LoginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");

        String checkcode = request.getParameter("checkcode");
        String codeSession = (String) request.getSession().getAttribute("codeSession");
        if (!checkcode.equalsIgnoreCase(codeSession)){
            request.setAttribute("errormsg","验证码有误!");
            request.getRequestDispatcher("/login.jsp").forward(request,response);
            return;
        }
//获取输入的用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");
// 判断用户名或者密码不正确
        if (!("wsl".equals(username)&&"123456".equals(password))){
            request.setAttribute("errormsg","用户名或者密码错误");
            request.getRequestDispatcher("/login.jsp").forward(request,response);
            return;
        }

        request.getSession().setAttribute("username",username);
        response.sendRedirect(request.getContextPath()+"/success.jsp");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}
发布了141 篇原创文章 · 获赞 27 · 访问量 27万+

猜你喜欢

转载自blog.csdn.net/u010581811/article/details/105618333
今日推荐