针对近期找工作一些经典的面试问题Http是否是有状态协议(回答没有),那么如何弥补http这种不足问题的回答。
回答如下
实现状态保持的方案:
1)修改Http协议,使得它支持状态保持(难做到)
2)Cookies:通过客户端来保持状态信息 Cookie是服务器发给客户端的特殊信息 cookie是以文本的方式保存在客户端,每次请求时都带上它
3)Session:通过服务器端来保持状态信息 Session是服务器和客户端之间的一系列的交互动作 服务器为每个客户端开辟内存空间,从而保持状态信息 由于需要客户端也要持有一个标识(id),因此,也要求服务器端和客户端传输该标识, 标识(id)可以借助Cookie机制或者其他的途径来保存
此处我仅对cookie、session的入门知识(包括java对cookie、session的使用)进行简单介绍。
一、Cookie
定义
Cookie 是在 HTTP 协议下,服务器或脚本可以维护客户工作站上信息的一种方式。Cookie 是由 Web 服务器保存在用户浏览器(客户端)上的小文本文件,它可以包含有关用户的信息。无论何时用户链接到服务器,Web 站点都可以访问 Cookie 信息。
应用
Cookie应用在需要频繁操作、记录浏览历史的场景。比如一些不涉及金钱的网站,可以保存用户与密码以保证在一段时间内不再进行操作,给用户更好的使用体验。早期电商平台的购物车功能,也采用cookie实现。某些特定技术也要依赖cookie,如禁用cookie会导致会话跟踪失效。
种类
Cookie分成二类,一种是窗口级还一种为指定时间级。所谓窗口级是指浏览器关闭后失效,指定时长级在到达指定的时间后自动失效。会话跟踪技术中的sessionId就是采用的窗口级cookie,“二周自动登陆”功能就要使用指定时长级cookie。
会话Cookie Cookie.setMaxAge(-1);//负整数
保存在浏览器的内存中,也就是说关闭了浏览器,cookie就会丢失
普通cookie Cookie.setMaxAge(60);//正整数,单位是秒 表示浏览器在1分钟内不继续访问服务器,Cookie就会被过时失效并销毁(通常保存在文件中)
注意: cookie.setMaxAge(0);//等价于不支持Cookie;
cookie编程
1>创建
Cookie cookie = new Cookie(“key”,”value”);//Cookie是键值对,键值都是字符类型
2>Cookie类
Servlet API封装了一个类:javax.servlet.http.Cookie,封装了对Cookie的操作,包括:
public Cookie(String name, String value) //构造方法,用来创建一个Cookie
HttpServletRequest.getCookies() //从Http请求中可以获取Cookies
HttpServletResponse.addCookie(Cookie) //往Http响应添加Cookie
public int getMaxAge() //获取Cookie的过期时间值
public void setMaxAge(int expiry) //设置Cookie的过期时间值
二、Session
应用领域:web交易需要保存状态的时候,都可以使用,比如在分布式场景下可以利用分布式session技术等。
SESSION机制
每次客户端发送请求,服务断都检查是否含有sessionId。如果有,则根据sessionId检索出session并处理;如果没有,则创建一个session,并绑定一个不重复的sessionId。
1)基本特点
状态信息保存在服务器端。这意味着安全性更高
通过类似与Hashtable的数据结构来保存
能支持任何类型的对象(session中可含有多个对象)
2)保存会话id的技术
Cookie
这是默认的方式,在客户端与服务器端传递JSeesionId
缺点:客户端可能禁用Cookie
表单隐藏字段
在被传递回客户端之前,在 form 里面加入一个hidden域,设置JSeesionId: <input type=hidden name=jsessionid value="3948E432F90932A549D34532EE2394" />
URL重写
直接在URL后附加上session id的信息
HttpServletResponse对象中,提供了如下的方法:
encodeURL(url); //url为相对路径
SESSION编程
1)HttpSession接口
Servlet API定义了接口:javax.servlet.http.HttpSession, Servlet容器必须实现它,用以跟踪状态。 当浏览器与Servlet容器建立一个http会话时,容器就会通过此接口自动产生一个HttpSession对象。
2)获取Session
HttpServletRequest对象获取session,返回HttpSession:
request.getSession(); //表示如果session对象不存在,就创建一个新的会话
request.getSession(true); //等价于上面这句;如果session对象不存在,就创建一个新的会话
request.getSession(false); //表示如果session对象不存在就返回 null,不会创建新的会话对象
3)Session存取信息
session.setAttribute(String name,Object o) //往session中保存信息
Object session.getAttribute(String name) //从session对象中根据名字获取信息
4)设置Session的有效时间
public void setMaxInactiveInterval(int interval) 设置最大非活动时间间隔,单位秒; 如果参数interval是负值,表示永不过时。零则是不支持session。 通过配置web.xml来设置会话超时,单位是分钟
<seesion-config> <session-timeout>1</session-timeout> </session-config>
允许两种方式并存,但前者优先级更高
三、两种状态跟踪机制的比较
Cookie | Session
保持在客户端 | 保存在服务器端
只能保持字符串对象 | 支持各种类型对象
通过过期时间值区分Cookie的类型 | 需要sessionid来维护与客户端的通信
普通Cookie——正数 | 表单隐藏字段
不支持Cookie——0 | url重写
注:参考自知乎以及简書。