Cookie
1、Cookie是什么? Cookie作用? Cookie保存在哪里?
- 翻译过来:曲奇饼干
- Cookie可以保存会话状态,但是这个会话状态是保留在客户端上,只要Cookie清除,或者Cookie失效,这个会话状态就没有了
- Cookie可以保存在浏览器的缓存中,浏览器关闭则Cookie消失
- Cookie也可以保存在客户端的硬盘文件中,浏览器关闭Cookie还在,除非Cookie失效
2、Cookie只有在javaweb中有吗?
- Cookie不止是在javaweb中存在
- 只要是web开发,只要是B/S架构的系统,只要是基于HTTP协议,就有Cookie的存在
- Cookie这种机制是HTTP协议规定的
3、Cookie实现的功能,常见的有哪些?
- 保留购物车商品的状态在客户端上
* 十天内免登录
* .......
*
4、在java中Cookie被当做类来处理,使用new运算符可以创建Cookie对象,而且Cookie由两部分组成
* 分别是Cookie的name和value,name和value都是字符串类型String
*
5、在java程序中怎么创建Cookie?
* Cookie cookie = new Cookie(String cookieName,String cookieValue);
*
6、服务器可以一次向浏览器发送多个Cookie
*
7、默认情况下,服务器发送Cookie给浏览器之后,浏览器将Cookie保存在缓存当中,只要不关闭浏览器,Cookie永远存在,并且有效
* 当浏览器关闭之后,缓存中的Cookie被清除
*
8、在浏览器客户端无论是硬盘文件中还是缓存中保存的Cookie,什么时候会再次发送给服务器呢?
* 浏览器会不会提交发送这些Cookie给服务器,是和请求路径有关系的
* 请求路径和Cookie是紧密关联的
* 不同的请求路径会发送提交不同的Cookie
*
9、默认情况下Cookie会和哪些路径绑定在一起?
* /prj-servlet-18 项目名
* /prj-servlet-18/test/createAndSendCookieToBrowser 请求服务器,服务器生成Cookie,并将Cookie发送到浏览器客户端
* 这个浏览器中的Cookie会默认和“test/”这个路径绑定在一起
* 也就是说,以后只要发送“test/”请求,Cookie一定会提交给服务器
* /prj-servlet-18/a 请求服务器,服务器生成Cookie,并将Cookie发送给浏览器客户端
* 这个浏览器中的Cookie会默认和“prj-servlet-18/”这个路径绑定在一起
* 也就是说,以后只要发送“prj-servlet-18/”请求,Cookie一定会提交给服务器
*
10、其实路径是可以指定的,可以通过java程序进行设置,保证Cookie和某个特定的路径绑定在一起。
* 假设,执行了这样的程序:cookie.setPath("/prj-servlet-18/king");
* 那么:Cookie将和"/prj-servlet-18/king"路径绑定在一起
* 只有发送“/prj-servlet-18/king”请求路径,浏览器才会提交Cookie给服务器
*
11、默认情况下,没有设置Cookie的有效时长,该Cookie被默认保存在浏览器的缓存当中
* 只要浏览器不关闭Cookie存在,只要关闭浏览器Cookie消失,我们可以通过设置Cookie的有效时长,以保证Cookie保存在硬盘文件当中
* 但是这个有效时长必须是>0的,换句话说,只要设置Cookie的有效时长大于0,则该Cookie会被保存在客户端硬盘文件当中
* 有效时长过去之后,则硬盘文件当中的Cookie失效
* cookie有效时长 = 0 直接被删除
* cookie有效时长 < 0 不会被存储
* cookie有效时长 > 0 存储在硬盘文件当中
* cookie.setMaxAge(60 * 60); 设置1小时有效
*
12、浏览器提交Cookie给服务器,服务器怎么接收Cookie?
* Cookie[] cookies = request.getCookies();
* if(cookies != null){
* for(Cookie cookie : cookies){
* String cookieName = cookie.getName();
* String cookieValue = cookie.getValue();
* System.out.println(cookieName + "=" + cookieValue);
* }
* }
13、浏览器可以禁用Cookie,是什么意思?
- 表示服务器发送过来的Cookie,我浏览器不要,不接收
- 服务器还是会发送Cookie的,只不过浏览器不再接收
14、示例
- 创建Cookie对象
* Cookie cookie1 = new Cookie("username","zhangsan");
* Cookie cookie2 = new Cookie("password","123");
*
- 设置Cookie的关联路径
* //cookie1.setPath(request.getContextPath() + "/king");
* //cookie2.setPath(request.getContextPath() + "/king");
*
- 设置Cookie的有效期
* cookie1.setMaxAge(60 * 60);
* cookie2.setMaxAge(60 * 60 * 24);
*
- 将Cookie对象发送给浏览器客户端
* response.addCookie(cookie1);
* response.addCookie(cookie2);
public class Cookie {
public static void main(String[] args) {
/**
*/一、Cookie
*
*
*
*
*
* //从request中获取所有的Cookie
* Cookie[] cookies = request.getCookies();
* String username = null;
* String password = null;
* if(cookies != null){
* 遍历Cookie
* for(Cookie cookie : cookies){
* String cookieName = cookie.getName();
* String cookieValue = cookie.getValue();
* if("username".equals(cookieName)){
* username = cookieValue;
* }else if("password".equals(cookieName)){
* password = cookieValue;
* }
* }
* }
*/
}
}
Session
测试(1):在同一个web项目中编写两个Servlet类firstServlet和secondServlet,通过前端发起请求,获取当前的session对象
package com.exercise.servlet; 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; public class firstServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String ip=request.getRemoteAddr(); HttpSession session=request.getSession(); System.out.println(ip+"'s session="+session); } }
第一次请求:
当关闭浏览器,重新打开浏览器访问时:
测试(2):同一个浏览器窗口访问不同的web项目(比如第一次访问京东,第二次访问淘宝),获取当前的session
第一个web项目:
第二个web项目:
package com.exercise.login;
public class Test {
public static void main(String[] args) {
/**
*/二、Session
*
* 1、Session表示会话,不止是在javaweb中存在,只要是web开发,都有会话这种机制
*
* 2、在java中会话对应的类型是:javax.servlet.http.HttpSession,简称session/会话
*
* 3、Cookie可以将会话状态保存在客户端,HttpSession可以将会话状态保存在服务器端
*
* 4、HttpSession对象是一个会话级别的对象,一次会话对应一个HttpSession对象
*
* 5、什么是一次会话?
* “目前”可以这样理解:用户打开浏览器,在浏览器上发送多次请求,直到最终关闭浏览器,表示一次完整的会话
*
* 6、在会话进行过程中,web服务器一直为当前这个用户维护着一个会话对象/HttpSession
*
* 7、在WEB容器中,WEB容器维护了大量的HttpSession对象,换句话说,在WEB容器中应该有一个“session列表”
* 思考:为什么当前会话中的每一次请求可以获取到属于自己的会话对象? session的实现原理?
* (1)打开浏览器,在浏览器上发送首次请求
* 服务器会创建一个HttpSession对象,该对象代表一次会话
* 同时生成HttpSession对象对应的Cookie对象,并且Cookie对象的name是JSESSIONID(比较特殊)
* Cookie的value是32位长度的字符串,value为session对象的id
* 服务器将Cookie的value和HttpSession对象绑定到session列表中
* 服务器将Cookie完整发送给浏览器客户端
* 浏览器客户端将Cookie保存到缓存中,只要浏览器不关闭,Cookie不会消失
* (2)当再次发送请求的时候,会自动提交缓存当中的Cookie
* 服务器接收到Cookie,验证该Cookie的name确实是:JSESSIONID,然后获取该Cookie的value
* 通过Cookie的value(session对象的id)去session列表中检索对应的HttpSession对象,从而区分不同用户
* 8、和HttpSession对象关联的这个Cookie的name是比较特殊的,在java中就叫做:jsessionid
*
* 9、浏览器禁用Cookie会出现什么问题?怎么解决?
* 浏览器禁用Cookie,则浏览器缓存中不再保存Cookie
* 导致在同一个会话中,无法获取到对应的会话对象
* 禁用Cookie之后,每一次获取的会话对象都是新的
* 浏览器禁用Cookie之后,若还想拿到对应的Session对象,必须使用URL重写机制,怎么重写URL:
* http://localhost/prj-servlet-21/user/accessMySelfSession;
* jsessionid=D3E9985BC5FD4BD05018BF2966863E94(记下value,浏览器地址栏上 ;value)
* 重写URL会给编程带来难度/复杂度,所以一般的web站点是不建议禁用Cookie的,建议浏览器开启Cookie
*
* 10、浏览器关闭之后,服务器端对应的session对象会被销毁吗?为什么?
* 浏览器关闭之后,服务器不会销毁session对象
* 因为B/S架构的系统基于HTTP协议,而HTTP协议是一种无连接/无状态的协议
* 什么是无连接/无状态?
* 请求的瞬间浏览器和服务器之间的通道是打开的,请求响应结束之后,通道关闭
* 这样做的目的是降低服务器的压力
*
* 11、session对象在什么时候被销毁?
* web系统中引入了session超时的概念
* 当很长一段时间(这个时间可以配置)没有用户再访问该session对象,此时session对象超时,web服务器自动回收session对象
* 可配置在:web.xml文件中,默认是30分钟,一般设置2小时
* <session-config>
* <session-timeout>120</session-timeout>
* </session-config>
*
* 12、什么是一次会话呢?
* 一般多数情况下,是这样描述的:用户打开浏览器,在浏览器上进行一些操作,然后将浏览器关闭,表示一次会话结束
* 本质上的描述:从session对象的创建,到最终session对象超时之后销毁,这个才是真正意义的一次完整会话
* 13、关于javax.servlet.http.HttpSession接口中常用方法:
* void setAttribute(String name, Object value)
* Object getAttribute(String name)
* void removeAttribute(String name)
* void invalidate() 销毁session
*
* 14、ServletContext、HttpSession、HttpServletRequest接口的对比:
* 14.1 以上都是范围对象:
* ServletContext application; 是应用范围
* HttpSession session; 是会话范围
* HttpServletRequest request; 是请求范围
* 14.2 三个范围的排序:
* application > session > request
* 14.3 三者区别:
* application完成跨会话共享数据
* session完成跨请求共享数据,但是这些请求必须在同一个会话当中
* request完成跨Servlet共享数据,但是这些Servlet必须在同一个请求当中【转发】
* 14.4 使用原则:由小到大尝试(越小耗费资源越少),优先使用小范围
* 例如:登录成功之后,已经登录的状态需要保存起来,可以将登录成功的这个状态保存到session对象中
* 登录成功状态不能保存到request范围中,因为一次请求对应一个新的request对象
* 登录成功状态也不能保存到application范围中,因为登录成功状态是属于会话级别的,不能所有用户共享
*
* 15、补充HttpServletRequest中的方法:
* HttpSession session = request.getSession();
* 获取当前的session,获取不到,则新建session
* HttpSession session = request.getSession(true);
* 获取当前的session,获取不到,则新建session
* HttpSession session = request.getSession(false);
* 获取当前的session,获取不到,则返回null(退出系统)
* HttpSession session = request.getSession(false);
* if(session != null){
* 销毁session
* session.invalidate();
* }
*/
}
}