文章目录
- Cookie概述
- Cookie是什么? Cookie作用? Cookie保存在哪里?
- Cookie只有在javaweb中有吗?
- Cookie实现的功能,常见的有哪些?
- 在java中Cookie被当做类来处理,使用new运算符可以创建Cookie对象,而且Cookie由两部分组成,
- 在java程序中怎么创建和读取Cookie?
- 在浏览器客户端无论是硬盘文件中还是缓存中保存的Cookie,什么时候会再次发送给服务器呢?
- 默认情况下Cookie会和哪些路径绑定在一起????
- 浏览器提交Cookie给服务器,服务器怎么接收Cookie?
- 浏览器是可以禁用Cookie,什么意思?
- 浏览器禁用Cookie会出现什么问题?怎么解决?
- Cookie在客户端的保存形式和有效时间
- Cookie和请求路径之间的关系
- 关于url-pattern的编写方式和路径的总结
- 路径的编写形式:
- HttpSession详解(简称session)
- session的工作原理:
- 什么情况下一次会话结束?
- 思考:为什么当前会话中的每一次请求可以获取到属于自己的会话对象? session的实现原理?
- 和HttpSession对象关联的这个Cookie的name是比较特殊的,在java中就叫做:jsessionid
- 浏览器关闭之后,服务器端对应的session对象会被销毁吗?为什么?
- session对象在什么时候被销毁?
- 什么是一次会话呢?
- 关于javax.servlet.http.HttpSession接口中常用方法:
- ServletContext、HttpSession、HttpServletRequest接口的对比:
- 补充HttpServletRequest中的方法:
- Session 和 Cookie 的区别
Cookie概述
Cookie是由服务器端生成并储存在浏览器客户端上的数据,是服务端在 HTTP 响应中附带传给浏览器的⼀个⼩⽂本⽂件,⼀旦浏览器保存了某个 Cookie,在之后的请求和响应过程中,会将此 Cookie 来回传递,这样就可以通过 Cookie 这个载体完成客户端和服务端的数据交互。
在javaweb开发中Cookie被当做java对象在web服务器端创建,并由web服务器发送给特定浏览器客户端,并且WEB服务器可以向同一个浏览器客户端上同时发送多个Cookie,每一个Cookie对象都由name和value组成,name和value只能是字符串类型,浏览器接收到来自服务器的Cookie数据之后默认将其保存在浏览器缓存中(如果浏览器关闭,缓存消失,Cookie数据消失),只要浏览器不关闭,当我们下一次发送“特定”请求的时候,浏览器负责将Cookie数据发送给WEB服务器。
我们还可以使用特殊的方法,将Cookie保存在客户端的硬盘上。永久性保存。这样关闭浏览器Cookie还是存在的,不会消失,比如:实现两周内自动登录。
Cookie是什么? Cookie作用? Cookie保存在哪里?
翻译过来:曲奇饼干
Cookie可以保存会话状态,但是这个会话状态是保留在客户端上。
只要Cookie清除,或者Cookie失效,这个会话状态就没有了。
Cookie是保存在浏览器客户端上的
Cookie可以保存在浏览器的缓存中,浏览器关闭Cookie消失
Cookie也可以保存在客户端的硬盘文件中,浏览器关闭Cookie还在,除非Cookie失效。
Cookie只有在javaweb中有吗?
Cookie不止是在javaweb中存在
只要是web开发,只要是B/S架构的系统,只要是基于HTTP协议,就有Cookie的存在。
Cookie这种机制是HTTP协议规定的。
Cookie实现的功能,常见的有哪些?
保留购物车商品的状态在客户端上
十天内免登录
…
在java中Cookie被当做类来处理,使用new运算符可以创建Cookie对象,而且Cookie由两部分组成,
分别是Cookie的name和value,name和value都是字符串类型String。
在java程序中怎么创建和读取Cookie?
- 创建Cookie
Cookie cookie = new Cookie(String cookieName,String cookieValue);
- 读取Cookie
Cookie[] cookies = request.getCookies();
for (Cookie cookie:cookies){
out.write(cookie.getName()+":"+cookie.getValue()+"<br/>");
}
服务器可以一次向浏览器发送多个Cookie
默认情况下,服务器发送Cookie给浏览器之后,浏览器将Cookie保存在缓存当中,只要不关闭浏览器,Cookie永远存在,并且有效。
当浏览器关闭之后,缓存中的Cookie被清除。
在浏览器客户端无论是硬盘文件中还是缓存中保存的Cookie,什么时候会再次发送给服务器呢?
- 浏览器会不会提交发送这些Cookie给服务器,和请求路径有关系。
- 请求路径和Cookie是紧密关联的。
- 不同的请求路径会发送提交不同的Cookie
默认情况下Cookie会和哪些路径绑定在一起???
/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一定会提交给服务器。
其实路径是可以指定的,可以通过java程序进行设置,保证Cookie和某个特定的路径绑定在一起。
假设,执行了这样的程序:cookie.setPath("/prj-servlet-18/king");
那么:Cookie将和"/prj-servlet-18/king"路径绑定在一起
只有发送“/prj-servlet-18/king”请求路径,浏览器才会提交Cookie给服务器。
默认情况下,没有设置Cookie的有效时长,该Cookie被默认保存在浏览器的缓存当中,只要浏览器不关闭Cookie存在,只要关闭浏览器Cookie消失,我们可以通过设置Cookie的有效时长,以保证Cookie保存在硬盘文件当中。但是这个有效时长
必须是>0的。换句话说,只要设置Cookie的有效时长大于0,则该Cookie会被保存在客户端硬盘文件当中。有效时长过去之后,
则硬盘文件当中的Cookie失效。
cookie有效时长 = 0 直接被删除
cookie有效时长 < 0 不会被存储
cookie有效时长 > 0 存储在硬盘文件当中
cookie.setMaxAge(60 * 60); 1小时有效
浏览器提交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);
}
}
浏览器是可以禁用Cookie,什么意思?
表示服务器发送过来的Cookie,我浏览器不要,不接收。
服务器还是会发送Cookie的,只不过浏览器不再接收。
浏览器禁用Cookie会出现什么问题?怎么解决?
浏览器禁用Cookie,则浏览器缓存中不再保存Cookie
- 导致在同一个会话中,无法获取到对应的会话对象
- 禁用Cookie之后,每一次获取的会话对象都是新的
浏览器禁用Cookie之后,若还想拿到对应的Session对象,必须使用URL重写机制,怎么重写URL:
http://localhost/prj-servlet-21/user/accessMySelfSession;jsessionid=D3E9985BC5FD4BD05018BF2966863E94
重写URL会给编程带来难度/复杂度,所以一般的web站点是不建议禁用Cookie的。建议浏览器开启Cookie
Cookie在客户端的保存形式和有效时间
服务器端默认创建的Cookie,发送到浏览器之后,浏览器默认将其保存在缓存中,当浏览器关闭之后Cookie消失。
服务器创建Cookie对象之后,调用setMaxAge方法设置Cookie的有效时间,
如果这个有效时间 >0,则该Cookie对象发送给浏览器之后浏览器将其保存到硬盘文件中。 如果这个有效时间
<0,则该Cookie对象也是被保存在浏览器缓存中,待浏览器关闭Cookie消失。 如果这个有效时间
=0,则该Cookie从服务器端发过来的时候就已经是一个已过时的Cookie。
Cookie和请求路径之间的关系
每一个Cookie和请求路径是绑定在一起的,只有特定的路径才可以发送特定的Cookie。实际上浏览器是这样做的:浏览器在向web服务器发送请求的时候先去对应的请求路径下搜索是否有对应的Cookie,如果有Cookie,并且Cookie没有失效,则发送该Cookie或者多个Cookie到服务器端。请求路径和Cookie的关系是这样对应的:
假如获取Cookie时的路径是 :http://127.0.0.1:8080/PrjCookies/getCookie
将来发送Cookie的路径包括如下路径 :
http://127.0.0.1:8080/PrjCookies/getCookie(相同路径)
http://127.0.0.1:8080/PrjCookies/xxxx(同目录)
http://127.0.0.1:8080/PrjCookies/xxxx/xxxx/xxx(子目录)
假如获取Cookie时的路径是 :http://127.0.0.1:8080/PrjCookies/servlet/getCookie
将来发送Cookie的路径包括如下路径 :
http://127.0.0.1:8080/PrjCookies/servlet/getCookie(相同路径)
http://127.0.0.1:8080/PrjCookies/servlet/xxxxx(同目录)
http://127.0.0.1:8080/PrjCookies/servlet/xxxxx/xxxx(子目录)
不过我们也可以在创建Cookie对象的时候设置Cookie的关联路径,例如:cookie.setPath(“/PrjCookies/system/login”);那么如下的请求路径浏览器会发送该Cookie:
http://127.0.0.1:8080/PrjCookies/system/login(相同路径)
http://127.0.0.1:8080/PrjCookies/system/xxx(同一目录)
http://127.0.0.1:8080/PrjCookies/system/xxx/xxx(子目录)
当浏览器禁用Cookie之后,服务器还是仍然会将Cookie发送给浏览器,只不过这次浏览器选择了不接收。现在有很多网站的使用都是需要开启接收Cookie的。例如126邮箱。
关于url-pattern的编写方式和路径的总结
路径的编写形式:
- <a href="/项目名/资源路径"></a>
- <form action="/项目名/资源路径"></form>
- 重定向:response.sendRedirect("/项目名/资源路径");
- 转发:request.getRequestDispatcher("/资源路径").forward(request,response);
- 欢迎页面
<welcome-file-list>
<welcome-file>资源路径</welcome-file>
</welcome-file-list>
- servlet路径
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.bjpowernode.javaweb.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/资源路径</url-pattern>
</servlet-mapping>
- Cookie设置path
cookie.setPath("/项目名/资源路径");
- ServletContext
ServletContext application = config.getServletContext();
application.getRealPath("/WEB-INF/classes/db.properties");
application.getRealPath("/资源路径");
2、url-pattern的编写方式
2.1 url-pattern可以编写多个
2.2 精确匹配
<url-pattern>/hello</url-pattern>
<url-pattern>/system/hello</url-pattern>
2.3 扩展匹配
<url-pattern>/abc/*</url-pattern>
2.4 后缀匹配
<url-pattern>*.action</url-pattern>
<url-pattern>*.do</url-pattern>
2.5 全部匹配
<url-pattern>/*</url-pattern>
web.xml文件中的路径
在<servlet-mapping></servlet-mapping>标签中<url-pattern></url-pattern>可以写多个。
<url-pattern>可以写成如下格式:
<url-pattern>/hello</url-pattern>
<url-pattern>/hello.do</url-pattern>
<url-pattern>/hello.action</url-pattern>
<url-pattern>/system/login.action</url-pattern>
<url-pattern>/*</url-pattern> <!--匹配任何请求-->
<url-pattern>*.do</url-pattern> <!--匹配所有以 .do 结尾的请求-->
<url-pattern>*.action</url-pattern><!--匹配所有以 .action 结尾的请求-->
原则:如果有精确匹配的则走精确匹配的。
关于路径的总结:
1、 目前我们接触的所有路径都是以“/”开始,都是绝对路径,没有使用过相对路径。
2、 在向web服务器发送请求的时候(包括使用超链接、使用form表单、直接在浏览器地址栏上输入)以及我们在java程序中使用“重定向”的时候,这些请求路径中是需要添加“项目名“的,其他的位置都不需要添加项目名。
在HTML页面中
<a href=”/webappname/testServlet”>超链接</a>
<form action=”/webappname/testServlet”></form>
重定向
response.sendRedirect(“/webappname/testServlet”);
转发
request.getRequestDispatcher(“/testServlet”).forward(request,response);
欢迎页面
<welcome-file-list>
<welcome-file>index.html</welcome-file> 注:必须保证webapp的根下(WebRoot下)有index.html文件
</welcome-file-list>
web.xml文件中配置servlet的url-pattern
<url-pattern>/testServlet</url-pattern>
Cookie关联的path:
cookie.setPath(“/webappname/testServlet”);
session_224">HttpSession详解(简称session)
session概述
在java web中session是一个存储在WEB服务器端的java对象,该对象代表用户和WEB服务器的一次会话(一次会话指的就是用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间),通过session对象可以完成数据的存取,而放在session对象中的数据都是用户相关的。也就说张三访问WEB服务器,服务器会生成一个张三的session对象,李四去访问WEB服务器,服务器就会生成一个李四的session对象。 系统为每个访问者都设立一个独立的session对象,用以存取数据,并且各个访问者的session对象互不干扰。 session与cookie是紧密相关的。 session的使用要求用户浏览器必须支持cookie,如果浏览器不支持使用cookie,或者设置为禁用cookie,那么将不能使用Session。除非服务器使用了URL重写机制(uri;jsessionid=xxxxxx)。
⽤户会话 服务器⽆法识别每⼀次 HTTP
请求的出处(不知道来⾃于哪个终端),它只会接受到⼀个请求信号,所就存在⼀个问题:将⽤户的响应发送给其他⼈,必须有⼀种技术来让服务器知道请求来⾃哪,这就是会话技术。
会话:就是客户端和服务器之间发⽣的⼀系列连续的请求和响应的过程,打开浏览器进⾏操作到关闭浏览器的过程。
会话状态:指服务器和浏览器在会话过程中产⽣的状态信息,借助于会话状态,服务器能够把属于同⼀次会话的⼀系列请求和响应关联起来。实现会话有两种⽅式:
思考以下问题
购物网站中的购物车是一个用户一个购物车,购物车是在服务器端的一个java对象,那么该java对象一定是需要找一个临时的区域存储起来的,因为用户在不断的购物,不断的向WEB服务器发送购物请求。那么这个购物车可以存储在ServletContext对象中吗?或者可以存储在HttpServletRequest对象中吗?
1、 购物车是一个用户级别的java对象,不是大家共享的对象,所以购物车千万不能存储在ServletContext对象中。因为ServletContext对象是服务器级别的对象,是大家共享的对象。
2、 购物车是一个用户级别的java对象,用户发送**“N次”请求**完成购物,这N次请求必须使用底层同一个购物车对象,所以购物车不能存储在HttpServletRequest对象中,如果存储在该对象中,那么用户只要发送一次请求就是一个新的购物车对象。
分析以下案例
假设有两个用户,一个是北京的张三,一个是南京的李四,都在访问京东商城购物网站,那么在京东WEB服务器中一定会有两个购物车,一个是张三的购物车,一个是属于李四的购物车,大家思考:一个WEB服务器,两个浏览器客户端,为什么张三在购物的时候向购物车中放入的商品一定是放到张三的购物车中,而不会存放到李四的购物车中,也就是说session是怎么实现和某个特定用户绑定的?下面使用图形描述session的工作原理:
session_256">session的工作原理:
当用户第一次访问web服务器的时候,web服务器会为该用户分配一个session对象,并且同时生成一个cookie对象(jsessionid=xxxx),然后web服务器将cookie对象的值和session对象以键值对的方式存储在web服务器端的session列表(Map)中,服务器负责将该cookie数据发送给浏览器,浏览器将cookie信息存储在浏览器的缓存中,只要浏览器不关闭,用户第二次访问服务器的时候会自动发送缓存中存储的cookie数据给服务器,服务器收到cookie数据之后获取cookie的值,然后通过该值在session列表(Map)中搜索对应的session对象。需要注意的是,当浏览器关闭之后,缓存中的cookie消失,这样客户端下次再访问服务器的时候就无法获取到服务器端的session对象了。这就意味着会话已经结束。但是这并不代表服务器端的session对象马上被回收,session对象仍然在session列表中存储,当长时间没有用户再访问这个session对象了,我们称作session超时,此时web服务器才会回收session对象。
什么情况下一次会话结束?
1、 浏览器关闭,缓存中的Cookie消失,会话不一定结束,因为服务器端的session对象还没有被销毁。我们还可以通过URL重写机制继续访问Session对象。
2、 浏览器没关闭,但是由于长时间没有访问web服务器,服务器判定session超时,将session对象销毁。此时浏览器虽然没关闭,但是这次会话已经结束。
3、 session对象所关联的这个Cookie的name有点特殊,这个name必须是jsessionid,必须全部小写,这是HTTP协议中规定的。
4、 浏览器禁用了Cookie,可以采用URL重写机制(这样编码的代价比较大,所以一般网站都是不允许禁用Cookie的)
注意:B/S架构采用HTTP协议通信,该协议是一个无连接协议,浏览器向服务器发送请求的瞬间是连接状态,等请求结束之后,B和S的连接断开了,服务器是无法监测浏览器的(浏览器关闭服务器是无法监测的)。
HttpSession对象的相关方法
获取session对象(1):request.getSession(true); request.getSession();
获取session对象,如果获取不到则新建
获取session对象(2):request.getSession(false);
获取session对象,如果获取不到则返回null
向session中存储数据:session.setAttribute(“name”,ObjectValue);
从session中获取数据:Object value = session.getAttribute(“name”);
删除session中某个数据:session.removeAttribute(“name”);
使session失效:session.invalidate();
session对象的超时包括三种设置方式
在web.xml中定义:
<session-config>
<session-timeout>30</session-timeout>
</session-config>
关于web编程中的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_302">思考:为什么当前会话中的每一次请求可以获取到属于自己的会话对象? session的实现原理?
打开浏览器,在浏览器上发送首次请求
- 服务器会创建一个HttpSession对象,该对象代表一次会话
- 同时生成HttpSession对象对应的Cookie对象,并且Cookie对象的name是JSESSIONID,Cookie的value是32位长度的字符串
- 服务器将Cookie的value和HttpSession对象绑定到session列表中
- 服务器将Cookie完整发送给浏览器客户端
- 浏览器客户端将Cookie保存到缓存中
- 只要浏览器不关闭,Cookie不会消失
- 当再次发送请求的时候,会自动提交缓存当中的Cookie
- 服务器接收到Cookie,验证该Cookie的name确实是:JSESSIONID,然后获取该Cookie的value
- 通过Cookie的value去session列表中检索对应的HttpSession对象。
sessionid_316">和HttpSession对象关联的这个Cookie的name是比较特殊的,在java中就叫做:jsessionid
session_321">浏览器关闭之后,服务器端对应的session对象会被销毁吗?为什么?
浏览器关闭之后,服务器不会销毁session对象
- 因为B/S架构的系统基于HTTP协议,而HTTP协议是一种无连接/无状态的协议
- 什么是无连接/无状态?
- 请求的瞬间浏览器和服务器之间的通道是打开的,请求响应结束之后,通道关闭
- 这样做的目的是降低服务器的压力。
session_330">session对象在什么时候被销毁?
web系统中引入了session超时的概念。
<session-config>
<session-timeout>120</session-timeout>
</session-config>
什么是一次会话呢?
一般多数情况下,是这样描述的:用户打开浏览器,在浏览器上进行一些操作,然后将浏览器关闭,表示一次会话结束。
本质上的描述:从session对象的创建,到最终session对象超时之后销毁,这个才是真正意义的一次完整会话。
关于javax.servlet.http.HttpSession接口中常用方法:
-void setAttribute(String name, Object value)
-Object getAttribute(String name)
-void removeAttribute(String name)
-void invalidate() 销毁session
ServletContext、HttpSession、HttpServletRequest接口的对比:
以上都是范围对象:
ServletContext application; 是应用范围
HttpSession session; 是会话范围
HttpServletRequest request; 是请求范围
三个范围的排序:
application > session > request
application完成跨会话共享数据、
session完成跨请求共享数据,但是这些请求必须在同一个会话当中、
request完成跨Servlet共享数据,但是这些Servlet必须在同一个请求当中【转发】
使用原则:有小到大尝试,优先使用小范围。
例如:登录成功之后,已经登录的状态需要保存起来,可以将登录成功的这个状态保存到session对象中。
登录成功状态不能保存到request范围中,因为一次请求对应一个新的request对象。
登录成功状态也不能保存到application范围中,因为登录成功状态是属于会话级别的,不能所有用户共享。
补充HttpServletRequest中的方法:
HttpSession session = request.getSession(); 获取当前的session,获取不到,则新建session
HttpSession session = request.getSession(true); 获取当前的session,获取不到,则新建session
HttpSession session = request.getSession(false); 获取当前的session,获取不到,则返回null
ServletContext(application)、HttpSession(session)、HttpServletRequest(request)三者的区别与联系:
a) 相同点:都可以用来传递数据,都有相同的存取数据的方法。
存:xxx.setAttribute(“name”,ObjectValue);
取:Object value = xxx.getAttribute(“name”);
删: xxx.removeAttribute(“name”);
不同点:
ServletContext(appliation)是Servlet上下文对象,在服务器启动阶段解析web.xml文件创建ServletContext对象,在同一个web app中所有的Servlet对象共享同一个ServletContext对象。
该对象一旦创建不会被销毁,除非将服务器停掉。所以尽量不要往这个对象中存放大数据,因为这是一个所有用户共享的空间,往该对象中存储的数据在多线程环境下涉及到修改操作的话注意线程安全问题。一般存储在该对象中的数据首先是所有用户共享的,不会被修改的,少量数据。ServletContext对象传递数据可以跨Servlet、跨请求、跨用户(跨会话)传递数据。
HttpSession(session)是会话对象,每一个用户都有一个这样的对象,是一个用户级别的对象,存储在该对象中的数据一般都是该用户专属的数据,例如购物车对象可以存储在session中,HttpSession对象传递数据可以跨Servlet、跨请求(这些请求必须属于同一个会话)、但是不能跨用户传递数据。
HttpServletRequest(request)是请求对象,一次请求一个对象,每一次请求都会新建一个请求对象,是一个请求级别的对象,存储该对象中的数据一般都是请求级别的数据,一次请求之后这个数据就不再使用的数据可以存储在该对象中,HttpServletRequest对象传递数据可以跨Servlet,但是不能跨请求,更不能跨用户传递数据。
原则:尽量从小范围向大范围使用。(考虑原则:request< session < application)
Session 和 Cookie 的区别
-
session:保存在服务器
保存的数据是 Object
会随着会话的结束⽽销毁
保存重要信息 -
cookie:保存在浏览器
保存的数据是 String
可以⻓期保存在浏览器中,⽆会话⽆关
保存不重要信息 -
存储⽤户信息:
session: setAttribute(“name”,“admin”) 存
getAttribute(“name”) 取
⽣命周期:服务端:只要 WEB 应⽤重启就销毁,客户端:只要浏览器关闭就销毁。
退出登录: session.invalidate()
cookie: response.addCookie(new Cookie(name,“admin”)) 存取
⽣命周期:不随服务端的重启⽽销毁,客户端:默认是只要关闭浏览器就销毁,我们通过 setMaxAge()
⽅法设置有效期,⼀旦设置了有效期,则不随浏览器的关闭⽽销毁,⽽是由设置的时间来决定。
退出登录: setMaxAge(0)