您的位置:首页 > 其它

cookie,session

2015-12-21 00:00 260 查看
一次会话:打开浏览器 -> 访问一些服务器内容 -> 关闭浏览器

用户登录后在一次会话中用户信息有效。
商品加入购物车,关闭浏览器,打开浏览器进入购物车,查看上次的商品。

会话管理: 管理浏览器客户端 和 服务器端之间会话过程中产生的会话数据。

context域对象是所有用户的公共资源,会覆盖数据,不适用。
request域对象一定要使用转发技术跳转页面,不适用。

Cookie 会话数据保存在浏览器客户端;
Session 会话数据保存在服务器端;

Cookie://servletAPI.chm javax.servlet.http
API:
1、构造Cookie对象:Cookie(String name,String value)
2、设置Cookie:
void setPath(String uri) 设置cookie的有效访问路径
void setMaxAge(int expiry) 设置有效时间
void setValue(String newValue)
3、发送cookie到浏览器端保存,服务器端不会保存cookie数据
void response.addCookie(Cookie cookie)
4、服务器接收cookie
Cookie[] request.getCookies()
示例1、
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1、服务器创建cookie对象,把会话数据存储到cookie对象中
//2、浏览器得到服务器发送的cookie,然后保存在浏览器端
//3、服务器发送cookie信息到浏览器
//4、浏览器在下次访问服务器时,会带着当前web应用下的cookie信息
//5、服务器接收到浏览器带来的cookie信息
Cookie cookie=new Cookie("name","MrL");//不能存放中文
Cookie cookie2=new Cookie("age","11");
//cookie.setPath("/day11");设置cookie有效路径,默认是当前web应用下,
cookie.setMaxAge(20);//20秒,从最后不调用cookie开始计算
//正整数:表示cookie数据保存浏览器的缓存目录(硬盘中)
//-1, 负整数 表示cookie数据保存浏览器的内存中。浏览器关闭cookie就丢失了
//零:表示删除同名的cookie数据
response.addCookie(cookie);//自动拼接cookie 隐藏发送了一个set-cookie名称的响应头 //手动拼接 response.setHeader("set-cookie","name=mrl,age=11");
response.addCookie(cookie2);
Cookie[] cookies=request.getCookies();
if(cookies!=null){
for(Cookie c:cookies){
System.out.println(c.getName()+"="+c.getValue());
}
}else{
System.out.println("没有接收到cookie数据");
}
}
浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB

//ProductDao.java
public class ProductDao {
// 该类存放对Product对象CRUD方法
private static List<Product> data=new ArrayList<Product>();
/*
* 初始化商品数据
*/
static{
//只执行一次
for(int i=0;i<=10;i++){
data.add(new Product(""+i,"笔记本"+i,"LN00"+i,34.0+i));
}
}
/*
* 查询到所有商品
*/
public List<Product> findAll(){
return data;
}
/*
* 根据编号查找商品
*/
public Product findById(String id){
for(Product p:data){
if(p.getId().equals(id));
return p;
}
return null;
}
}
//Product.java
public class Product{
private String id,name,proType;
provate double Price;
//getter setter
public Product(){super();}
public Product(String id,String name,double price){
super();
this.id=id;
this.price=price;
}
public String toString(){
return     "Product[id="+id+",price"+price+"]";
}
}
//ListServlet.java
public class ListServlet extends HttpServlet{
public void doGet(request,response) throws Exception{
response.setContentType("text/html;charset=utf-8");
ProductDao dao=new ProductDao();
List<Product> list=dao.findAll();
String html="<html><body><table>";
if(list!=null){
for(Product p:list){
html+="<td><a
href='"+request.getContextPath()+"/DetailServlet?id="+p.getId()+"'>"+p.getName()+"</td>";
}
}
}
//浏览过的商品
html += "最近浏览过的商品:<br/>";
//取出prodHist的cookie
Cookie[] cookies = request.getCookies();
if(cookies!=null){
for (Cookie cookie : cookies) {
if(cookie.getName().equals("prodHist")){
String prodHist = cookie.getValue(); // 3,2,1
String[] ids = prodHist.split(",");
//遍历浏览过的商品id
for (String id : ids) {
//查询数据库,查询对应的商品
Product p = dao.findById(id);
//显示到浏览器
html += ""+p.getId()+" "+p.getName()+" "+p.getPrice()+"<br/>";
}
}
}
}

response.getWriter().append(html);
}
//DetailServlet.java,
Cookie cookie=new Cookie("prodHist",createVal(request,id));
private String createVal(HttpServletRequest request,String id){
Cookie[] cookies = request.getCookies();//cookie去掉重复值,id放到前面,只存放最近3个浏览记录
String prodHist = null;
if(cookies!=null){
for (Cookie cookie : cookies) {
if(cookie.getName().equals("prodHist")){
prodHist = cookie.getValue();
break;
}
}
}
if(cookies==null || prodHist==null){
return id;
}
String[] ids=prodHist.split(",");
Collection colls = Arrays.asList(ids); //<3,21>
// LinkedList 方便地操作(增删改元素)集合
// Collection -> LinkedList
LinkedList list = new LinkedList(colls);
if(list.contains(id)){
list.remove(id);
}
list.addFirst(id);
if(list.size()>3){
list.removeLast();
}
StringBuffer sb = new StringBuffer();
for (Object object : list) {
sb.append(object+",");
}
String result = sb.toString();
result = result.substring(0, result.length()-1);
return result;
}


Session:会话数据保存在服务器内存中,一个浏览器独占一个session对象
cookie的局限:cookie不能保存中文,不能保存对象只能保存字符串,1个cookie容量不能超过4k
1)创建或得到session对象
HttpSession getSession()
HttpSession getSession(boolean create)
2)设置session对象
void setMaxInactiveInterval(int interval) : 设置session的有效时间
void invalidate() : 销毁session对象
java.lang.String getId() : 得到session编号
3)保存会话数据到session对象
void setAttribute(java.lang.String name, java.lang.Object value) : 保存数据
java.lang.Object getAttribute(java.lang.String name) : 获取数据
void removeAttribute(java.lang.String name) : 清除数据
http请求中Set-Cookie:JSESSIONID=*

1)创建或得到session对象
HttpSession getSession()
HttpSession getSession(boolean create)
2)设置session对象
void setMaxInactiveInterval(int interval) : 设置session的有效时间
void invalidate() : 销毁session对象
java.lang.String getId() : 得到session编号
3)保存会话数据到session对象
void setAttribute(java.lang.String name, java.lang.Object value) : 保存数据
java.lang.Object getAttribute(java.lang.String name) : 获取数据
void removeAttribute(java.lang.String name) : 清除数据
代码解读:HttpSession session = request.getSession();
1)第一次访问创建session对象,给session对象分配一个唯一的ID,叫JSESSIONID
new HttpSession();
2)把JSESSIONID作为Cookie的值发送给浏览器保存
Cookie cookie = new Cookie("JSESSIONID", sessionID);
response.addCookie(cookie);//有效时间 为负数 浏览器关闭清空cookie
3)第二次访问的时候,浏览器带着JSESSIONID的cookie访问服务器
4)服务器得到JSESSIONID,在服务器的内存中搜索是否存放对应编号的session对象。
5)如果找到对应编号的session对象,直接返回该对象
6)如果找不到对应编号的session对象,创建新的session对象,继续走1的流程

1)java.lang.String getId() : 得到session编号
2)两个getSession方法:
getSession(true) / getSession() : 创建或得到session对象。没有匹配的session编号,自动创建新的session对象。
getSession(false): 得到session对象。没有匹配的session编号,返回null
3)void setMaxInactiveInterval(int interval) : 设置session的有效时间
session对象销毁时间:
3.1 默认情况30分服务器自动回收
3.2 修改session回收时间
3.3 全局修改session有效时间
<!-- 修改session全局有效时间:分钟 -->
<session-config>
<session-timeout>1</session-timeout>
</session-config>
3.4.手动销毁session对象 void invalidate(): 销毁session对象
4)如何避免浏览器的JSESSIONID的cookie随着浏览器关闭而丢失的问题
手动发送一个硬盘保存的cookie给浏览器
Cookie c = new Cookie("JSESSIONID",session.getId());
c.setMaxAge(60*60);
response.addCookie(c);

禁用Cookie后servlet共享数据导致的问题。
解决方案:URL重写
response. encodeRedirectURL(java.lang.String url)
用于对sendRedirect方法后的url地址进行重写。
response. encodeURL(java.lang.String url)
用于对表单action和超链接的url地址进行重写 <a href=“<%=response.encodeURL(“maillogin.jsp“)%>“>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  cookie session