• Servlet 浅谈(三)


    关于Session

    关于http协议后面会有一系列文章专门介绍。这里就大概了解一下:首先需要知道一点:HTTP是无状态的

    什么是无状态呢?

    客户与服务器建立连接、发出请求、得到响应、关闭连接。整个流程走完就算完了。下次服务器并不知道是否跟客户打过交道。

    简言之,对于容器而言,每一个请求都来自于一个新的客户。

    怎么让服务器记住你?

    对于客户的一个请求,容器会生成一个唯一的ID,并通过响应把它返回给客户。客户再在以后的每一个请求中发回这个会话ID。容器看到此ID后,会找到响应的匹配的画画,并把这个会话与请求关联。而交换会话ID的最简单也最常用的方式是通过cookie。

    cookie是谁来管理的?

    容器会做cookie的所有工作。包括:生成会话ID,创建新的cookie对象,把会话ID放在cookie中,把cookie设置为响应的一部分。

    在响应中发送一个会话

    HttpSession session = request.getSession();
    

    如何判断会话已经存在还是刚刚创建?

    session.isNew();//如果是刚创建的会返回true,反之则为false
    

    只想要已经有的会话怎么办?

    对此,专门有一个重载的方法getSession(boolean),如果不想创建一个新的会话,可以调用getSession(false),此会话要么返回null,要么返回一个已经有的HttpSession。

    如果客户不接受cookie怎么办?

    如果客户禁用cookie,则意味着getSession()总会返回一个新的会话,客户不会发回一个带有会话ID cookie首部的请求。

    此时可以使用URL重写。

    我们的目的是为了让容器和客户交换会话ID信息,最简单的方法当然是用cookie。但是此时如果不能把ID放在cookie中,怎么办?只有利用URL重写将cookie会话中的会话ID取出来放在访问应用的各个URL的最后。

    会话怎么删除?

    会话对象会占用资源,所以必须要让没用的对话删除。

    那么问题来了?怎么才能让容器知道你什么时候删除一个对话呢?或者什么时候客户已经离开了?容器又在什么时候删除这个对话呢?

    这个时候要用到HttpSession接口了。他有一些很有用的方法可供调用。

    getCreationTime():返回第一次创建对话的时间。**可以用它来得出对话存在的时间。**
    
    getLastAccessedTime():返回容器最后一次得到包含这个会话ID请求后过去了多长时间。**可用来得出客户最后一次访问这个对话是什么时候**。
    
    setMaxInactiveInterval():指定对于这个会话客户请求的最大间隔时间。**可以用来撤销容器中废弃的会话**。
    
    getMaxInactiveIntervale():返回这个会话客户请求的最大间隔时间。
    
    invalidate():结束会话。
    

    所以会话通常有三种死法:

    • 超时

    • 你在会话对象上调用validate

    • 应用结束(崩溃或者取消部署)

    1.在DD中配置会话超时

    <web-app ....>
    	<servlet>
    		...
    	</servlet>
    	<session-config>
    		<session-timeout>15</session-timeout>
    		<!--15分钟超时-->
    	</session-config>
    </web-app>
    

    2.设置一个特定会话超时

    session.setMaxInactiveInterval(20*60);//20 minutes
    

    关于Cookie

    cookie还有什么别的作用?

    前面提到了cookie可以帮助容器记住会话状态,那么除此之外还能干什么呢?

    默认,cookie与会话寿命一样长,一旦客户离开浏览器,cookie就会消失。但是你可以让cookie活的更长一些,甚至在关闭浏览器之后还能存活。

    创建一个cookie:

    Cookie cookie = new Cookie("username", name);
    

    设置Cookie在客户端上存活多久:

    cookie.setMaxAge(30*60);//30 minutes
    

    把Cookie发送到客户:

    response.addCookie(cookie);
    

    从客户请求得到cookie:

    Cookie[] cookie = request.getCookies();
    for(int i= 0;i < cookies.length; i++) {
    	Cookie cookie = cookies[i];
    	if(cookie.getName().equals("username")) {
    		String userName = cookie.getValue();
    		break;
    	}
    }
    

    HttpSessionBindingListener

    这个监听器的作用是:当一个属性类实现了此接口是,这个实例增加到一个会话或者从一个会话中删除时,容器会调用该事件处理的回调方法。

    代码示例:

    public class ClassName implements HttpSessionBindingListener {
    //省略其他属性方法定义,或者Setter、getter定义
    public void valueBound(HttpSessionBindingEvent event) {
       //添加处理事件
    }
    public void valueUnBound(HttpSessionBindingEvent event) {
     	//添加处理事件
    }
    

    会话迁移

    在分布式应用上,应用的各个部分可以复制到网络的多个节点上,在一个集群环境中,容器可能会完成负载均衡,取得客户的请求并把它放在多个JVM上。

    这个时候ServletContext, ServletConfig, HttpSession对象会发生什么变化呢?

    答案是:每个VM上都有一个ServletContext。每个VM上的每个Servlet有一个ServletConfig。但是每个Web应用的一个给定的会话ID,只有一个HttpSession对象,而不论应用分布在多少个VM上

    所以尽管应用的其他部分会在每个节点VM上复制,但是会话对象不会复制,只会迁移

    HttpSessionActivationListener

    如果你的属性类型是Serializable,那就用不着该监听器了。如果不是,可以实现该监听器,使得属性实现串行化。

    总结与会话相关的监听器

    HttpSessionListener 
    
    主要方法:sessionCreated sessionDestroyed
    
    可以用来统计有多少个并发用户
    
    HttpSessionBindingListener
    
    HttpSessionBindingListener
    //上面两种监听器,前面已经介绍,此处从略
    
    HttpSessionAttributeListener
    
    主要方法:attributeAdded() attributeRemoved() attributeReplaced()
    
    可以知道会话中什么时候增加删除或者替换会话属性。
    

    这是最后一篇关于Servlet基础知识的文章,通过三篇博客,大致介绍了Servlet的常用功能,我们知道怎么用它,但是具体Servlet的原理,请看第四篇。

  • 相关阅读:
    Linux常用命令
    Springboot环境搭建_第一个例子
    java 填写一个银行卡如何判断是否真实存在
    java 理解如何实现图片验证码 傻瓜都能看懂。
    编程语言学习路线··
    他他他她她她所唱所写………
    Docker 学习笔记 (4)
    Docker 学习笔记 (3)
    Docker 学习笔记 (2)
    Docker 学习笔记 (1)
  • 原文地址:https://www.cnblogs.com/xuehanlee/p/4606140.html
Copyright © 2020-2023  润新知