javaWeb学习笔记-Session对象 - Go语言中文社区

javaWeb学习笔记-Session对象


一、Session简介

     Session是服务器端的会话技术,用户通过浏览器访问服务器时,服务器会给每个浏览器创建一个session,用于保存用户的信息。

二、Session和Cookie的区别

  • Cookie是将用户的数据保存在浏览器的
  • Session是将用户的数据保存在服务器的
  • Session是由服务器创建的,而Cookie是开发人员创建的
  • Session保存数据在服务器,所以比较安全。而Cookie保存数据在浏览器,数据相对来说不安全

三、Session的常用方法

  • Object getAttribute(java.lang.String name) :返回指定属性的值
  • java.util.Enumeration getAttributeNames() :返回所有属性名的一个集合
  • String getId():返回创建session对象的id编号的字符串形式
  • void invalidate() :销毁session对象
  • boolean isNew() :判断session对象是否新创建的
  • void removeAttribute(java.lang.String name):移除指定的属性
  • void setAttribute(java.lang.String name, java.lang.Object value):设置一个属性
  • HttpSession getSession():HttpServletRequest的方法,得到一个session对象,如果不存在就创建一个。
  • HttpSession getSession(boolean create) :HttpServletRequest的方法,如果参数为false,表示只去获取已经创建好的session对象,而不会去创建新的。参数为true,和上面的效果相同。

四、Session的原理

package test.session;

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;

public class SessionDemo5 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取Session,也就是创建一个Session
        HttpSession hs = request.getSession();
        // 保存数据到session中
        hs.setAttribute("data", "data");
        // 获取session编号
        String sid = hs.getId();

        // 判断是否为新创建的session
        if(hs.isNew()){
            response.getOutputStream().write(("创建一个session,其id为 "+sid).getBytes());
        }else {
            response.getOutputStream().write(("已创建session,其id为 "+sid).getBytes());
        }
    }

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

}

第一次访问该servlet时,显示:
这里写图片描述
然后点击刷新按钮,显示:
这里写图片描述
发现两次的id值是相同的。再查看浏览器的cookie信息:
这里写图片描述

在servlet代码的else中加入打印该Cookie的程序:

        if(hs.isNew()){
            response.getOutputStream().write(("创建一个session,其id为 "+sid).getBytes());
        }else {
            response.getOutputStream().write(("已创建session,其id为 "+sid).getBytes());

            // 打印名为Jseesionid的cookie信息
            Cookie[] cs = request.getCookies();
            if(cs != null){
                for(Cookie c : cs){
                    if(c.getName().equals("JSESSIONID")){
                        response.getOutputStream().write(("   JSESSIONID is "+c.getValue()).getBytes());
                    }
                }
            }
        }

再次访问:
这里写图片描述

发现cookie中的jsessionid的值和session的id编号相同。
由此可以推断出:在创建一个新的session时,服务器还做了额外的操作:获取session的id,然后将他存储到一个名为JSESSIONID的cookie中,返还给浏览器。在接下来的访问中,浏览器会带着这个cookie去访问服务器。

五、Session对象的生命周期

1、创建
在程序第一次执行request对象的getSession方法时,会创建一个Session对象

// 使用request对象的getSession方法,得到一个session,如果不存在就创建一个
HttpSession session = request.getSession(); 

2、销毁
销毁分为自然销毁和手动销毁。
自然销毁:session的默认保存时间为30分钟,到时间后服务器会自动销毁。也可以在web.xml文件中配置session的销毁时间。

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name></display-name>

  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

  <!-- 设置Session的有效时间,以分钟为单位-->
    <session-config>
        <session-timeout>15</session-timeout>
    </session-config>

</web-app>

手动销毁:调用session.invalidate方法,销毁session。

HttpSession session = request.getSession();
//手工调用session.invalidate方法,摧毁session
session.invalidate();

六、禁用Cookie后的Session处理

     通过session的原理分析可以知道,session在创建的时候会给浏览器一个名为JSESSIONID的cookie,通过这个cookie我们在下次访问时,会带上这个cookie信息,被服务器识别。如果禁用了浏览器的cookie,那么就不会有这种效果了。
     如果想实现禁用cookie后的效果和没有禁用之前的效果相同。那么我们可以使用URL重写。

URL重写
response.encodeRedirectURL(java.lang.String url) 用于对sendRedirect方法后的url地址进行重写。
response.encodeURL(java.lang.String url)用于对表单action和超链接的url地址进行重写

实例:
IndexServlet

import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//首页:列出所有书
public class IndexServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        //创建Session
        request.getSession();
        out.write("本网站有如下书:<br/>");
        Set<Map.Entry<String,Book>> set = DB.getAll().entrySet();
        for(Map.Entry<String,Book> me : set){
            Book book = me.getValue();
            String url =request.getContextPath()+ "/servlet/BuyServlet?id=" + book.getId();
            //response. encodeURL(java.lang.String url)用于对表单action和超链接的url地址进行重写
            url = response.encodeURL(url);//将超链接的url地址进行重写
            out.println(book.getName()  + "   <a href='"+url+"'>购买</a><br/>");
        }
    }

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


// 模拟数据库
class DB{
    // 使用LinkedHashMap,方便遍历,并且数据有序
    private static Map<String,Book> map = new LinkedHashMap<String,Book>();
    static{
        map.put("1", new Book("1","javaweb开发"));
        map.put("2", new Book("2","spring开发"));
        map.put("3", new Book("3","hibernate开发"));
        map.put("4", new Book("4","struts开发"));
        map.put("5", new Book("5","ajax开发"));
    }

    public static Map<String,Book> getAll(){
        return map;
    }
}

class Book{

    private String id;
    private String name;

    public Book() {
        super();
    }
    public Book(String id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

BuyServlet

package xdp.gacl.session;

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

// 将买的数添加到session中
public class BuyServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //得到用户想买的书
        String id = request.getParameter("id");
        Book book = DB.getAll().get(id);  

        //得到用户用于保存所有书的容器
        HttpSession session = request.getSession();
        List<Book> list = (List) session.getAttribute("list");  
        // 第一次创建一个list集合
        if(list==null){
            list = new ArrayList<Book>();
            session.setAttribute("list", list);
        }
        list.add(book);

        //response. encodeRedirectURL(java.lang.String url)用于对sendRedirect方法后的url地址进行重写
        String url = response.encodeRedirectURL(request.getContextPath()+"/servlet/ListCartServlet");
        System.out.println(url);
        response.sendRedirect(url);
    }

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

}

ListCartServlet

package xdp.gacl.session;

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

public class ListCartServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        HttpSession session = request.getSession();
        List<Book> list = (List) session.getAttribute("list");
        if(list==null || list.size()==0){
            out.write("对不起,您还没有购买任何商品!!");
            return;
        }

        //显示用户买过的商品
        out.write("您买过如下商品:<br>");
        for(Book book : list){
            out.write(book.getName() + "<br/>");
        }
    }

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

在禁用了cookie的IE8下的运行效果如下:
这里写图片描述
通过查看IndexServlet生成的html代码可以看到,每一个超链接后面都带上了session的Id,如下所示

本网站有如下书:<br/>javaweb开发   <a href='/JavaWeb_Session_Study_20140720/servlet/BuyServlet;jsessionid=96BDFB9D87A08D5AB1EAA2537CDE2DB2?id=1'>购买</a><br/>
spring开发   <a href='/JavaWeb_Session_Study_20140720/servlet/BuyServlet;jsessionid=96BDFB9D87A08D5AB1EAA2537CDE2DB2?id=2'>购买</a><br/>
hibernate开发   <a href='/JavaWeb_Session_Study_20140720/servlet/BuyServlet;jsessionid=96BDFB9D87A08D5AB1EAA2537CDE2DB2?id=3'>购买</a><br/>
struts开发   <a href='/JavaWeb_Session_Study_20140720/servlet/BuyServlet;jsessionid=96BDFB9D87A08D5AB1EAA2537CDE2DB2?id=4'>购买</a><br/>
ajax开发   <a href='/JavaWeb_Session_Study_20140720/servlet/BuyServlet;jsessionid=96BDFB9D87A08D5AB1EAA2537CDE2DB2?id=5'>购买</a><br/>

另外,esponse. encodeRedirectURL(java.lang.String url) 和response. encodeURL(java.lang.String url)是两个非常智能的方法,当检测到浏览器没有禁用cookie时,那么就不进行URL重写了。

部分引用自:http://www.cnblogs.com/xdp-gacl/p/3855702.html

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/Q_Sea__/article/details/79430215
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-02-13 13:51:45
  • 阅读 ( 1415 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢