Session

一、Session的简单介绍

  在web开发中,服务器可以为每个用户浏览器创建一个跟踪会话的session对象,注意:在默认情况下,一个浏览器独占一个session对象。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户对应的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。

二、Session和Cookie的主要区别

1.Cookie是把用户的数据写给用户的浏览器,以文本文件的格式存储在浏览器中。

2.Session技术把用户的数据写到用户独占的session中,Session存储在服务器端。Session对象由服务器创建,可以调用request对象的getSession方法得到session对象。

三、Session实现原理

  服务器创建session出来后,会把session的id号,以cookie的形式回写给浏览器,这样,只要客户机的浏览器不关,再去访问服务器时,都会带着session的id号去,服务器发现客户机浏览器带session的id过来了,就会使用服务器内存储的对应的session为之服务。

public class SessionDemo1 extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        HttpSession session=request.getSession();
        session.setAttribute("data","会话");
        String sessionId = session.getId();
        //判断session是否是新创建的
        if(session.isNew()) {
            response.getWriter().write("session创建成功,它的id是:" + sessionId);
        }else {
            response.getWriter().write("session已经存在,它的id是:"+sessionId);
        }

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

运行结果:

在刚打开浏览器进入localhost:8080/Demo01_war_exploded这个站点时,session已经被创建,再进入localhost:8080/Demo01_war_exploded/SessionDemo1这个站点时,session就不是新创建的了,session已经存在。

找到浏览器存储的cookie,发现一个cookie中保存着session的id,说明session被创建时,通过cookie将session的id发送到浏览器:

在上面的代码中为该浏览器对应的session设置了值:session.setAttribute("data","会话"),新建一个取出这个值。

四、浏览器禁用Cookie后的session处理

浏览器禁用Cookie:

     在禁用浏览器保存服务器端发来的cookie时,这时客户端就不知道session的id,客户端跳转到另一个页面时,就不能去访问服务器端的session共享里面的数据了。

这时可以用response.encodeRedirectURL(java.lang.String url)和response.encodeURL(java.lang.String url)两个方法重写sevlet中执行跳转的URL。

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

示例:

public class SessionDemo3 extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter writer = response.getWriter();
        request.getSession();
        writer.write("本网站有如下书:<br/>");
        //set只有键,键就是值,不允许重复。map是键值对,键不能重复。entrySet()把map里的值传到一个set里存放
        Set<Map.Entry<String, Book>> set = DB.getAll().entrySet();
        for (Map.Entry<String, Book> me : set) {
            Book book = me.getValue();
            //request.getContextPath()返回的是这个web应用的url
            String url = request.getContextPath() + "/SessionDemo4?id=" + book.getId();
            //response. encodeURL(java.lang.String url)用于对表单action和超链接的url地址进行重写
            url = response.encodeURL(url);//将超链接的url地址进行重写
            writer.println(book.getName() + "   <a href='" + url + "'>购买</a><br/>");
        }

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) {

    }
}

/**
 * 42  * @author gacl
 * 43  * 模拟数据库
 * 44
 */
class DB {
    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;
    }
}

SessionDemo3的界面:

对“购买”添加了超链接跳转到SessionDemo4,并将书的id传过去:String url = request.getContextPath() + "/SessionDemo4?id=" + book.getId();

再将超链接的url地址进行重写: response.encodeURL(url);

看一下SessionDemo3的页面源代码:

可以看出在超链接中添加上了session的id,这就能使通过超链接跳转过去的页面也能共享到session中的数据

跳转到SessionDemo4后,SessionDemo4通过url得到的书的id,通过id得到书的名字,将书的名字写到session中,然后SessionDemo4重定向SessionDemo5中:

public class SessionDemo4 extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("UTF-8");
        String id = request.getParameter("id");
        Book book = DB.getAll().get(id);  //得到用户想买的书
        HttpSession session = request.getSession();
        List<Book> list = (List) session.getAttribute("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() + "/SessionDemo5");
        System.out.println(url);
        response.sendRedirect(url);
    }

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

在SessionDemo4中通过response.encodeRedirectURL(java.lang.String url)方法重写重定向于SessionDemo5的url:

String url = response.encodeRedirectURL(request.getContextPath() + "/SessionDemo5");

在SessionDemo5中读取session中的数据,显示购买了哪本书:

public class SessionDemo5 extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws 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 IOException {
        doGet(request, response);
    }
}

在网址栏中可以看到重定向SessionDemo5的url中也添加了session的id,这也是为什么在浏览器禁用cookie的情况下,SessionDemo5还能共享session中的数据

      在浏览器没有禁用Cookie的情况下,即使调用了response.encodeRedirectURL(java.lang.String url)和response.encodeURL(java.lang.String url)这两个方法,执行跳转的URL也不会被重写:

五、session对象的创建和销毁时机

1.在程序中第一次调用request.getSession()方法时就会创建一个新的Session,可以用isNew()方法来判断Session是不是新创建的。

2.session对象默认30分钟没有使用,则服务器会自动销毁session,在web.xml文件中可以手工配置session的失效时间:

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

3.当需要在程序中设置Session失效时,可以调用session.invalidate方法,摧毁session。

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值