cookie和session

cookie和HttpSession

cookie和HttpSsession都是用来跟踪客户端浏览器和服务器端的通话状态,不同之处在于cookie是在服务器创建,存储在浏览器端。HttpSsession是服务器端创建,并存储在服务器端。以下文章主要讲述了cookie和HttpSsession的生命周期、特点、常用的方法和两者之间的联系。

一、Cookie
cookie:cookie是在服务器端创建,cookie对象由客户端进行缓存,

1、cookie特点:
1.1、cookie使用字符串存储数据

1.2、cookie使用key-value 键值对存储数据

1.3、单个cookie存储的最大数据不能超过4K;

1.4、cookie存储的数据不支持中文,Servlet 4.0之后支持中文

1.5、cookie是和域名进行绑定的,所以cookie不能跨一级域名进行访问,但是可以跨二级域名

1.6、cookie对象保存在浏览器或系统磁盘中

1.7、cookie分为状态cookie和持久化cookie

1.8、浏览器保存同一域名返回的cookie是有限的,不同浏览器支持的数量不同,chrome浏览器支持50个

1.9、浏览器每次请求时都会把和该域名相关的所有cookie在请求中提交给服务器

2、状态cookie和持久化cookie的区别:
状态cookie是指cookie缓存在浏览器中,当浏览器关闭时,cookie也会被销毁。

持久化cookie是指浏览器会对cookie对象进行持久化处理,以文件的方式存储在系统磁盘中。

当cookie对象创建时默认是状态cookie。可以使用cookie对象下的cookie.setMaxge(int time)方法设置实效时间,单位是秒。一旦设置了失效时间,cookie对象会自动转化为持久化cookie,浏览器会将持久化cookie对象持久化到磁盘中,当到达失效时间后,系统会删除该文件,cookie对象失效。

3、Cookie对象的使用:
3.1 Cookie对象的创建
Cookie cookie = new Cookie( “key” , “value” );

通过new关键字创建cookie对象

response.addCookie(cookie)

通过HttpServletResponse对象将cookie对象写回客户端浏览器

3.2 获取Cookie中的数据
    Cookie[] cookies=request.getCookies();

通过HttpServletRequest对象获取cookie,返回cookie数组。

3.3 解决cookie中不支持中文
    因为Servlet 4.0之前版本不支持cookie存储中数据,因此需要设置编码格式

URLEncode.encodr( “content” ,“code” )

将内容按照指定的编码格式做URL编码处理

URLDecode.decode( “content” , “code” );

将内容按照指定的编码格式做URL解码处理

4、Cookie总结
  cookie对于存储是基于明文进行存储的,所以安全性较低,不要在cookie中存放敏感数据。存放数据时,虽然Servlet 4.0以后支持中文存储,建议对cookie中存储的数据做编码处理,以提高安全性。

二、HttpSession

HttpSession 是由服务器创建,由服务器端进行缓存

1、HttpSession的特点
1.1 HttpSession保存在服务器端

1.2 HttpSession可以存储任意类型的数据

1.3 HttpSession使用key-value结构存储数据

1.4 HttpSession存储数据无大小限制

2、HttpSession的使用
  2.1 HttpServlet对象的创建
 HttpSession对象的创建是通过request.getSession()方法来创建的。当客户端请求服务器资源时,如果请求中没有Session ID,.getSession()方法会给客户端创建一个Session对象,并生成相对应的Session ID,然后response对象在响应中通过Cookie写回浏览器。如果客户端请求中有SessionID,.getSession()方法则根据这个SessionID返回对应的HttpSession对象。

getSession()方法还有一个重载的方法,getSession(true/false),当参数为true时,和getSession()方法作用相同。当参数为false时,则只会根据SessionID来查找对应的HttpSession对象,如果有则返回。如果没有SessionID,也不会重新创建HttpSession对象。

2.2 获取HttpSession数据
    session.setAttribute(“key”,value);

将数据存储到HttpSession对象中

Object value = session.getAttribute(“key”);

根据key获取HttpSession对象中的value值,返回值类型是Object

Enumeration attributeNames = session.getAttributeNames();

获取HttpSession对象中的所有key,返回枚举类型

session.removeAttribute(“key”);

根据key删除HttpSession中的对象

String id = session.getID();

获取HttpSession对象的SessionID,返回String类型

3 HttpSession对象的销毁方式
    HttpSession对象的销毁方式有两种

(1)调用invalidate()方法销毁当前HttpSession对象

(2)在web-xml文件中配置HttpSession对象的超时时间

我们可以在web-xml文件中设置HttpSession的超时时间,当到达指定的超时时间时,容器会自动销毁HttpSession对象,单位是分钟。该时间对该项目下所有 HttpSession对象有效。时间的计算方式是根据最后一次请求时间作为起始时间计算。

        <session-config>
          <session-timeout>1</session-timeout>
        </session-config>

我们也可以在Tomcat 的web.xml 文件中配置HttpSession 的销毁时间。如果在Tomcat的web.xml 文件中配置了HttpSession 的超时时间对应的是Tomcat 中所有的Web 项目都有效。相当于配置了全局的HttpSession 超时时间。如果我们在Web 项目中配置了超时时间,那么会以Web 项目中的超时时间为准

invalidate()方法是HttpSession 对象中所提供的用于销毁当前HttpSession 的方法。我们通过调用该方法可以销毁当前HttpSession 对象。

4 HttpSession的生命周期
 在HttpSession对象的声明周期中没有固定的创建时间和销毁时间。创建时间取决于何时执行request.getSession()或request.getSession(true)方法,销毁时间取决于何时调用invalidate()方法或设置的超时时间。如果没有超时也没有调用invalidate()方法,则HttpSession对象对一致存在,默认的超时时间是30分钟(tomcat服务器的web-xml文件设置的超时时间)

5 HttpSession总结
 HttpSession对象保存在服务器端,所以安全性较高,我们可以在HttpSession对象中存储数据,但是由于HttpSession对象的声明周期不确定,所以不建议存放业务数据,一般存储用户登陆数据、

三、Cookie和HttpSession之间的联系

从上文可以知道,HttpSession对象的创建是通过request.getSession()方法来创建的。当客户端请求服务器资源时,如果请求中没有Session ID,.getSession()方法会给客户端创建一个Session对象,并生成相对应的Session ID,然后response对象在响应中通过Cookie写回浏览器。如果客户端请求中有SessionID,.getSession()方法则根据这个SessionID返回对应的HttpSession对象。也就是说服务器端的HttpSession对象的调用依赖于Cookie中的SessionID,如果Cookie被销毁,则Cookie中存储的SessionID也会被销毁,所以当客户端浏览器再次向服务器端发送请求时,由于请求信息中不包含SessionID,所以服务器端会调用request.getSession()方法,重新创建一个HttpSession对象,而原有的HttpSession则不会被返回,最终被销毁。(可以将SessionID直接附加到URL 后面也可以返回对应的HttpSession对象,但是这样操作会造成安全问题,所以不建议使用)

cookie的应用场景

1,记住用户名;2,自动登录

2,创建cookie发送给浏览器 并获取cookie

@WebServlet(name = "CookieServlet1",urlPatterns = "/cookie1")
public class CookieServlet1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} p
rotected void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
//创建cookie
Cookie cookie = new Cookie("username","tom");
//设置cookie的路径——浏览器根据这个路径判断那些cookie要发送给服务器
cookie.setPath("/day04");
//将cookie发送给浏览器
response.addCookie(cookie);
}
}
@WebServlet(name = "CookieServlet2",urlPatterns = "/cookie2")
public class CookieServlet2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} 
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
//获取浏览器发送的cookie
Cookie[] cookies = request.getCookies();
if(cookies != null){
for (Cookie coo : cookies) {
if("username".equals(coo.getName())){
//打印cookie的名称和值
System.out.println(coo.getName()+":"+coo.getValue());
}
}
}
}

cookie.setPath()的用法

正常的cookie只能在一个应用中共享,即一个cookie只能由创建它的应用获得。
1.可在同一应用服务器内共享方法:设置cookie.setPath("/");

本机tomcat/webapp下面有两个应用:cas和webapp_b,

1)原来在cas下面设置的cookie,在webapp_b下面获取不到,path默认是产生cookie的应用的路径。

2)若在cas下面设置cookie的时候,增加一条cookie.setPath("/");或者cookie.setPath("/webapp_b/");就可以在webapp_b下面获取到cas设置的cookie了。

3)此处的参数,是相对于应用服务器存放应用的文件夹的根目录而言的(比如tomcat下面的webapp),因此cookie.setPath("/");之后,可以在webapp文件夹下的所有应用共享cookie,而cookie.setPath("/webapp_b/");是指cas应用设置的cookie只能在webapp_b应用下的获得,即便是产生这个cookie的cas应用也不可以。

4)设置cookie.setPath("/webapp_b/jsp")或者cookie.setPath("/webapp_b/jsp/")的时候,只有在webapp_b/jsp下面可以获得cookie,在webapp_b下面但是在jsp文件夹外的都不能获得cookie。

5)设置cookie.setPath("/webapp_b");,是指在webapp_b下面才可以使用cookie,这样就不可以在产生cookie的应用cas下面获取cookie了

6)有多条cookie.setPath(“XXX”);语句的时候,起作用的以最后一条为准。

6)设置多个path的方法???

2.跨域共享cookie的方法:设置cookie.setDomain(".jszx.com");

A机所在的域:home.langchao.com,A有应用cas

B机所在的域:jszx.com,B有应用webapp_b

1)在cas下面设置cookie的时候,增加cookie.setDomain(".jszx.com");,这样在webapp_b下面就可以取到cookie。

2)这个参数必须以“.”开始。

3)输入url访问webapp_b的时候,必须输入域名才能解析。比如说在A机器输入:http://lc-bsp.jszx.com:8080/webapp_b,可以获取cas在客户端设置的cookie,而B机器访问本机的应用,输入:http://localhost:8080/webapp_b则不可以获得cookie。

4)设置了cookie.setDomain(".jszx.com");,还可以在默认的home.langchao.com下面共享。

cookie技术原理分析在这里插入图片描述
给cookie添加数据的时候需要注意数据的内容
在cookie值中不能使用分号(;)、逗号(,)、等号(=)以及空格
如果存入的数据不合法,会出现一个错误

java.lang.IllegalArgumentException:
An invalid character [32] was present in the Cookie value

那么如果我们一定要保存非法数据在cookie中,该如何操作呢
答:cookie对于基本符号、数字、和字母是可以存储的,因此,我们只需要将非法数据转换成符号、数字、和字母形式存储,要使用的时候再转换成正常的中文(解码)即可。
那么,我们如何对中文数据进行编码和解码呢?
有两个类。可以进行编码和解码。

URLEncoder类:
static String encode(String s, String enc) 将指定的字符串,按指定的编码表编码

URLDecoder类:
static String decode(String s, String enc) 将指定的字符串,按指定的编码表解码
public void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
//第一次访问操作
// 1 获取用户当前访问的时间
Date date = new Date();
// 2 格式化时间数据(时间转换成含有非法字符形式)
SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 ;,= hh时mm分ss秒");
String format1 = format.format(date);
System.out.println(format1);
// 3 将数据进行编码
String encode = URLEncoder.encode(format1, "utf-8");
// 4 将数据存入cookie
Cookie cookie = new Cookie("time",encode );
cookie.setMaxAge(60*60*24);
// 5 将数据发送给浏览器
response.addCookie(cookie);
//第二次访问操作
//获取cookie数组
Cookie[] cookies = request.getCookies();
if(cookies != null) {
for (Cookie cookie2 : cookies) {
//选择获取名称为time的cookie
if("time".equals(cookie2.getName())) {
//由于数据之前经过编码,现在要还原的中文数据
String decode = URLDecoder.decode(cookie2.getValue(), "utf-8");
//将数据发送页面
//为了防止中文乱码
/*  通知服务器在响应数据时,使用utf-8编码
 * 也能通知浏览器使用utf-8接收服务器发送的数据 */
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(decode);
}
}
}
}

session

Session是借助Cookie技术来传递ID属性的

应用场景

  1. 保存购物车数据
  2. 保存用户浏览器记录数据
  3. 保存用户登录信息数据
  4. 保存验证码

保存在ServletContext中或者request中是否可以?
将数据存放到ServletContext,多个用户共享一个验证码
将数据存放到request作用域,多次请求不能共享数据

session的原理分析
在这里插入图片描述
session如何实现关闭浏览器继续可以访问数据
自定义一个cookie对象,保存session的id,注意cookie名称为"JSESSIONID",设置一个比较长的生存时间。发送给浏览器。

public void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
//获取session对象
HttpSession session = request.getSession();
System.out.println(session);
//自己创建一个cookie,要求被浏览器持久化保存起来(setMaxAge(10000))放便后期使用
Cookie cookie = new Cookie("JSESSIONID", session.getId());
//活的久一点
cookie.setMaxAge(10000);
response.addCookie(cookie);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值