一 什么是绘话
会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。
二 什么是Cookie
2.1什么是cookie
Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。
如上图所示,浏览器首次访问服务器的时候是不带cookie的,到服务器端以后,客户端创建cookies之后,随着请求的响应流带到客户端浏览器,浏览器把回来的cookie放到缓存中,当下一次请求同样基地址路径的时候,客户端会带着cookies到服务器,服务器就可以通过浏览器缓存技术取到客户端首次访问的值。
2.2 Cookie的传输媒介
javax.servlet.http.Cookie类用于创建一个Cookie,response接口中定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。 同样,request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie。
2.3 Cookie的API
public Cookie(String name,String value)
setValue与getValue方法
setMaxAge与getMaxAge方法 (秒)
setPath与getPath方法
setDomain与getDomain方法
getName方法
2.4 Cookie详解
(1) 一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。
(2) 一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
(3) 浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
(4) 如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
(5) 删除cookie时,path必须一致,否则不会删除
2.5 案例一 Cookies记录时间
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置到达客户端的输出数据的编码格式
response.setContentType("text/html;charset=utf-8");
//获得界面的Cookies
Cookie[] cookies = request.getCookies();
PrintWriter writer = response.getWriter();
for(Cookie co:cookies){
if(co.getName().equals("lastTime")){
String value = co.getValue();
writer.write("上次访问时间是:"+value);
}
}
Date date = new Date();
Cookie cookie=new Cookie("lastTime",date.toString());
Cookie.setPath(“/”);
Cookie.setMaxAge(1000*30);
response.addCookie(cookie);
}
如上代码所示,我们先获取上次页面中的cookies,如果没有的话生成一个cookies返回到页面,下一次就可以获取到cookies到页面进行输出。
如上图所示是上面的代码,返回到页面之后形成的cookies的样例,一个cookie是由
Name cookies的名称。
Value cookies的值。
Domain cookies所属的主机域。
Path cookies的路径,下一个再请求同样的地址的时候,就会带上对应的cookie。当前访问路径如果是以cookies path开头的就带上cookies,否则就不带cookies,可以在服务端返回cookie的时候就手动给cookie设置路径,这样的话等到cookie访问设置的路径的时候,它就会自动的带上cookie了。
cookie.setPath("/");
Expires/max-age cookie的最大存活时间。setMaxAge() 正数cookie保存指定时间,负数cookie永久保存,直到关闭当前会话,0表示立即删除cookie。
2.7 案列二 cookie浏览记录
实现思路:把浏览的列表的id的集合,用一个cookie的字段做记录
每浏览一个记录往cookie的id集合中添加一个,当大于制定值的时候
把cookie中的第一个删掉,添加当前值,如果集合中包含当前值,先删除
当前浏览的值,再重复上面的判断。
Size cookies 的指定大小。
2.7.1 列表
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
Map allCollege = DBUtils.getAllCollege();
Set entrySet = allCollege.entrySet();
Iterator it = entrySet.iterator();
StringBuffer buffer=new StringBuffer();
buffer.append("大学列表如下所示:");
while(it.hasNext()){
Map.Entry<Integer, String> next = (Entry<Integer, String>) it.next();
Integer key =(Integer) next.getKey();
String name = next.getValue();
buffer.append("<br>");
buffer.append("<a href="+request.getContextPath()+"/ServletDetails?key="+key+">"+name+"</a>");
buffer.append("<br>");
}
buffer.append("最近浏览的历史记录:<br>");
Cookie[] cookies = request.getCookies();
for(int i=0; cookies!=null&&i<cookies.length;i++){
if(cookies[i].getName().equals("history")){
String value = cookies[i].getValue();
String[] split = value.split("-");
for(String str:split){
String byId = DBUtils.getById(Integer.valueOf(str));
buffer.append("<br>");
buffer.append("<a href="+request.getContextPath()+"/ServletDetails?key="+str+">"+byId+"</a>");
buffer.append("<br>");
}
}
}
String string = buffer.toString();
PrintWriter writer = response.getWriter();
writer.write(string);
writer.close();
}
2.7.2详细
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
String key = request.getParameter("key");
String byId = DBUtils.getById(Integer.valueOf(key));
Cookie[] cookies = request.getCookies();
String history=null;
for(int i=0;cookies!=null&&i<cookies.length;i++){
if(cookies[i].getName().equals("history")){
history=cookies[i].getValue();
}
}
Cookie cookies2 = getCookies(key, history);
response.addCookie(cookies2);
ServletOutputStream outputStream = response.getOutputStream();
byte[] bytes = byId.getBytes();
outputStream.write(bytes);
outputStream.close();
}
private Cookie getCookies(String key, String history) {
if(null!=history){
String[] split = history.split("-");
LinkedList<String> lik=new LinkedList<String>(Arrays.asList(split));
if(lik.contains(key)) lik.remove(key);
if(lik.size()==3) lik.removeFirst();
lik.addLast(key);
StringBuffer buf=new StringBuffer();
for(int i=0;i<lik.size();i++){
if(i>0){
buf.append("-");
}
buf.append(lik.get(i));
}
return new Cookie("history", buf.toString());
}
return new Cookie("history", key);
}
2.7.3 DB
public class DBUtils {
private static Map map=new HashMap();
static{
map.put(1, "中国人民大学");
map.put(2, "上海交通大学");
map.put(3, "华东师范大学");
map.put(4, "北京理工大学");
}
public static String getById(int id){
return (String) map.get(id);
}
public static Map getAllCollege(){
return map;
}
}
2.7.4 结果
2.6 删除cookie
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
Cookie cookie=new Cookie("lastTime","");
cookie.setPath("/");
cookie.setMaxAge(0);
response.addCookie(cookie);
}
如上图所示第一次访问的时候还可以看到如上图所示的cookie的返回值,并可以清晰的看到cookie的相关信息,当我点击clear执行上面的代码的时候
如上图所示cookie已经被清理了,此时我们再访问,原绘画的路径
发现首次访问的时候,已经拿不到cookie中的信息了,原因是我点clear的时候执行相应的代码删除掉了。
三 什么是session
Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的HttpSession对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。
如上图所示是一个session的放映,如上图所示客户端每开启一个浏览器默认对服务器产生了一个唯一的绘话,直到客户端关闭浏览器会话才算结束。如上图服务器为客户端的每一个绘画开启了一个存储介质。也就是我们所说的session技术。简单的说每一个打开一个浏览器就相当于创建了一个session。
3.1 session传值原理
如上图所示的session原理图,当浏览器第一次放问服务器的时候,浏览器是不待有jsessionid的cookies的所以,在调用request.getSession()的时候,实际上是先创建了一个session,然后再把session的id返回到客户端做记录,当客户端浏览器再次访问服务器的时候,将通过浏览器中cookies中时候存在session再做是否创建session的判断,所以很多用户,打开很多浏览器,各自的数据存储在了各自的session里面,并不会错乱。
3.2 session API
void setAttribute(String name,Object value); 向session中填值
Object getAttribute(String name); 向session中取值
void removeAttribute(String name); 删除session中的值
HttpSession.getId():获取session对应的id值
setMaxInactiveInterval(int interval) 设置session的存活时间
invalidate() 使此会话无效
3.3 getSession() 原理
HttpSession request.getSession():内部执行原理
1、获取名称为JSESSIONID的cookie的值。
2、没有这样的cookie,创建一个新的HttpSession对象,分配一个唯一的SessionID,并且向客户端写了一个名字为JSESSIONID=sessionID的cookie
3、有这样的Cookie,获取cookie的值(即HttpSession对象的值),从服务器的内存中根据ID找那个HttpSession对象:
找到了:取出继续为你服务。
找不到:从2开始。
HttpSession request.getSession(boolean create):
参数:
true:和getSession()功能一样。
false:根据客户端JSESSIONID的cookie的值,找对应的HttpSession对象,找不到返回null(不会创建新的,只是查询)。
3.4案例一session购物车
3.4.1列出所有的物品
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
request.getSession();
out.print("本网站有以下好书:<br/>");
Map<String, Book> books = DBUtil.findAllBooks();
for (Map.Entry<String, Book> book : books.entrySet()) {
String url = request.getContextPath()+"/servlet/addCart?id="+book.getKey();
out.print("<a href='"+response.encodeURL(url)+"' >"+book.getValue().getName()+"</a><br/>");
}
String url2 = request.getContextPath()+"/servlet/showCart";
out.print("<a href='"+response.encodeURL(url2)+"'>查看购物车</a>");
}
3.4.2添加购物车
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//根据id得到书
String id = request.getParameter("id");
Book book = DBUtil.findBookById(id);
//得到session对象
HttpSession session = request.getSession();
//从session中取出list(购物车)
List<Book> list = (List<Book>)session.getAttribute("cart");
if(list==null){
list = new ArrayList<Book>();
}
list.add(book);
session.setAttribute("cart", list);//把list放回到session域中
out.print("购买成功!");
String url = request.getContextPath()+"/servlet/showAllBooksServlet";
}
3.4.3展示购物车
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.print("购物车有以下商品:<br/>");
HttpSession session = request.getSession();
//得到session对象
List<Book> books = (List<Book>)session.getAttribute("cart");
if(books==null){
out.print("你还什么都没买呢");
response.setHeader("refresh", "2;url="+request.getContextPath()+"/servlet/showAllBooksServlet");
//response.sendRedirect(request.getContextPath()+"/servlet/showAllBooksServlet");
return;
}
for (Book book : books) {
out.write(book.getName()+"<br/>");
}
//session.setMaxInactiveInterval(10);
}