Session学习

一、Session的简单介绍

当客户端访问服务端时,服务端会为每一个用户创建一个独一无二的Session对象,因此服务端如果需要保存客户端的一些数据的话,可以把数据存放到Session对象中,当用户使用浏览器访问该服务端其他的web资源时,服务端可以,从Session对象中取出必要的数据来服务用户。

二、Session与Cookie的区别

存放的位置:
Cookie是把用户的数据写给用户的浏览器。
Session是服务器把用户的数据写到Session中,来完成必要的数据获取。

储存数据方面:
Cookie只能存取String数据类型的数据,Session能够储存任意的Java对象。

安全方面:
Cookie保存在的是客户端,所以会被窃取,不太安全。Session存取在服务器,比较安全存放用户的一些重要的信息。

三、Session与Cookie的应用场景

Cookie:主要是一些网站用来存取账号与密码。登录所需要的数据。

Session:主要是购物网站中的购物车,添加了商品,把商品的信息存在Session中。

四、Session实现原理


虽然Session保存在服务器,对客户端是透明的,它的正常运行仍然需要客户端浏览器的支持。这是因为Session需要使用Cookie作为识别标志。
HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,
它的值为该Session的id(也就是HttpSession.getId()的返回值)。Session依据该Cookie来识别是否为同一用户。
该Cookie为服务器自动生成的,它的maxAge属性一般为–1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效。
因此同一机器的两个浏览器窗口访问服务器时,会生成两个不同的Session。但是由浏览器窗口内的链接、脚本等打开的新窗口(也就是说不是双击桌面浏览器图标等打开的窗口)除外。这类子窗口会共享父窗口的Cookie,因此会共享一个Session。

注意:新开的浏览器窗口会生成新的Session,但子窗口除外。子窗口会共用父窗口的Session。例如,在链接上右击,在弹出的快捷菜单中选择“在新窗口中打开”时,
子窗口便可以访问父窗口的Session。如果客户端浏览器将Cookie功能禁用,或者不支持Cookie怎么办?
例如,绝大多数的手机浏览器都不支持Cookie。Java Web提供了另一种解决方案:URL地址重写。

 

package com.luther.TestWeb;

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;
import java.io.IOException;

@WebServlet("/sessiontest")
public class TestSession extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        req.setCharacterEncoding("utf-8");
        HttpSession session=req.getSession();
        session.setAttribute("country","中国");
        String sessionId = session.getId();
        if(session.isNew()){
            resp.getWriter().write("Session创建,Session的ID是"+sessionId);
        }else{
            resp.getWriter().println("服务器已经有session了,Session的ID是"+sessionId);
        }

    }
}

 

五、session共享数据的实例展示

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

展示购买的书籍的页面:

package com.luther.TestWeb;

import javax.servlet.ServletException;
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.HashMap;
import java.util.Map;
import java.util.Set;

public class IndexServlet extends HttpServlet {


    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        //返回的是map的映射关系,一个关系就是一个键值对,就是把(key和value)当成一个整体
       Set<Map.Entry<String,Book>> set=DB.getAll().entrySet();
        PrintWriter out=resp.getWriter();
        out.write("有下面的一些书:<br>");
        for(Map.Entry<String,Book> set1:set){
            //返回一个映射关系
            Book book=set1.getValue();
            //获取名称
            String name=book.getName();
            //获取值
            String id=book.getId();
            out.write(name+":");
            String url=req.getContextPath()+"/BuyServlet?id="+book.getId();
            resp.encodeURL("url");
            out.write("<a href='"+url+"'>购买</a><br/>");


        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       doGet(req,resp);
    }
}
//这里应该是从数据库里获取的,这里简单就直接展示出来,也可以自己写XML文件来进行储存
class DB{
    private static  Map<String,Book> map=new HashMap<String,Book>();
    static {
        map.put("1",new Book("JAVA开发","1"));
        map.put("2",new Book("C++开发","2"));
        map.put("3",new Book("C语言开发","3"));
    }
    public static Map<String,Book> getAll(){
        return map;
    }

}
class Book{
    private String name;
    private String id;

    public Book(String name, String id) {
        this.name = name;
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public String getId() {
        return id;
    }
}

购买图书,存取数据的中间过程:

package com.luther.TestWeb;

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;
import java.util.ArrayList;
import java.util.List;

public class BuyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session=req.getSession();
        //获取传来的ID
        String id=(String)req.getParameter("id");
        Book book=DB.getAll().get(id);
        List<Book> list=(List)session.getAttribute("List");
        if(list==null) {
             list = new ArrayList<Book>();
        }
        list.add(book);
        //把数据存放到Session中
        session.setAttribute("List",list);
        String url=req.getContextPath()+"/ListServlet";
        resp.sendRedirect(url);//这里可以防止表单的重复提交
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       doGet(req,resp);
    }
}

展示已经购买的书籍:

package com.luther.TestWeb;

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;
import java.io.PrintWriter;
import java.util.List;

public class ListServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter out=resp.getWriter();
        HttpSession session=req.getSession();
        //获取到Session存取的值
        List<Book> list=(List)session.getAttribute("List");
        if(list==null){
            out.println("服务器出错误了");
        }else {
            out.println("你已经购买了:<br/>");
            for(Book l:list)
                out.println(l.getName()+"<br/>");
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

运行截图:

六、Session的创建与销毁

1、Session的创建是当我们第一次调用getSession()方法时创建

2、Session对象的销毁(默认的是30分钟之后销毁),可以在web.xml文件中设置销毁的时间

<!--分钟为单位-->
 <session-config>
        <session-timeout>900</session-timeout>
    </session-config>

3、也可以手动的销毁

session.invalidate();

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值