会话跟踪技术----cookie和session

Cookie

什么叫Cookie
Cookie 是网站用来在客户端保存识别用户的一种小文件
一般用Cookie可以保存用户登录信息、购物数据信息等一系列微小信息。

其实Cookie就是一个键和一个值构成的,随着服务器端的响应发送给客户端浏览器。然后客户端浏览器会把Cookie保存起来,当下一次再访问服务器时把Cookie、再发送给服务器。

注意,不同浏览器之间是不共享Cookie的。

Cookie与HTTP头

Cookie是通过HTTP请求和响应头在客户端和服务器端传递的:
Cookie:请求头,客户端发送给服务器端;
格式:Cookie: a=A; b=B; c=C。即多个Cookie用分号离开;
Set-Cookie:响应头,服务器端发送给客户端;
一个Cookie对象一个Set-Cookie:
Set-Cookie: a=A
Set-Cookie: b=B
Set-Cookie: c=C

Cookie的覆盖
如果服务器端发送重复的Cookie那么会覆盖原有的Cookie,
如客户端的第一个请求服务器端发送的Cookie是:Set-Cookie: a=A;第二请求服务器端发送的是:Set-Cookie: a=AA,那么客户端只留下一个Cookie,即:a=AA。

Cookie示例(Servlet)
服务端ServletA将一个键值对 以Cookie的形式响应给客户端,客户端存储在本地,然后再访问ServletB,ServletB得到请求中的所有Cookie ,并在控制台打印出来。
我们这个案例是,客户端访问AServlet,AServlet在响应中添加Cookie,浏览器会自动保存Cookie。然后客户端访问BServlet,这时浏览器会自动在请求中带上Cookie,BServlet获取请求中的Cookie打印出来。

注:
使用repsonse.addCookie()方法向浏览器保存Cookie
使用request.getCookies()方法获取浏览器归还的Cookie

代码实现:
AServlet.java

/**
 * 给客户端发送Cookie
 * @author Administrator
 *
 */
public class AServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        
        String id = UUID.randomUUID().toString();//生成一个随机字符串
        Cookie cookie = new Cookie("id", id);//创建Cookie对象,指定名字和值
        response.addCookie(cookie);//在响应中添加Cookie对象
        response.getWriter().print("已经给你发送了ID");
    }
}

BServlet.java

/**
 * 获取客户端请求中的Cookie
 * @author Administrator
 *
 */
public class BServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        
        Cookie[] cs = request.getCookies();//获取请求中的Cookie
        if(cs != null) {//如果请求中存在Cookie
            for(Cookie c : cs) {//遍历所有Cookie
                if(c.getName().equals("id")) {//获取Cookie名字,如果Cookie名字是id
                    response.getWriter().print("您的ID是:" + c.getValue());//打印Cookie值
                }
            }
        }
    }
}

Cookie的生命

**setMaxAge(int)**来设置Cookie的有效时间, 以秒为单位
**cookie.setMaxAge(60)**表示这个Cookie会被浏览器保存到硬盘上60秒。
cookie.setMaxAge(-1):cookie的maxAge属性的默认值就是-1,表示只在浏览器内存中存活。一旦关闭浏览器窗口,那么cookie就会消失。
cookie.setMaxAge(0)cookie生命等于0是一个特殊的值,它表示cookie被作废!也就是说,如果原来浏览器已经保存了这个Cookie,那么可以通过Cookie的setMaxAge(0)来删除这个Cookie。无论是在浏览器内存中,还是在客户端硬盘上都会删除这个Cookie。

创建Cookie,名为lasttime,值为当前时间,添加到response中;
在AServlet中获取请求中名为lasttime的Cookie;
如果不存在输出“您是第一次访问本站”,如果存在输出“您上一次访问本站的时间是xxx”;

public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        
        //创建Cookie对象,名为lasttime,值为当前时间
        Cookie cookie = new Cookie("lasttime", new Date().toString());
        //设置Cookie在客户端的有效时间为1小时
         cookie.setMaxAge(60 * 60);
         //添加Cookie到response中
        response.addCookie(cookie);
        
        //获取请求中的Cookie
        Cookie[] cs = request.getCookies();
        String s = "您是首次访问本站!";
        if(cs != null) {//如果请求中存在Cookie
            for(Cookie c : cs) {//循环遍历请求中的Cookie
                //如果Cookie名为lasttime
                if(c.getName().equals("lasttime")) {
                    s = "您上次的访问时间是:" + c.getValue();
                }
            }
        }
        //打印s到客户端
        response.getWriter().print(s);
    }

Cookie中保存中文
Cookie的name和value都不能使用中文,如果希望在Cookie中使用中文,那么需要先对中文进行URL编码,然后把编码后的字符串放到Cookie中。
向客户端响应中添加Cookie

//使用URL编码
String name = URLEncoder.encode("姓名", "UTF-8");
String value = URLEncoder.encode("张三", "UTF-8");
//编码后的字符串保存到Cookie中
Cookie c = new Cookie(name, value);
c.setMaxAge(3600);
response.addCookie(c);

从客户端请求中获取Cookie

response.setContentType("text/html;charset=utf-8");
Cookie[] cs = request.getCookies();
if(cs != null) {
         for(Cookie c : cs) {
            //把Cookie的name和value使用URL解码后再打印
            String name = URLDecoder.decode(c.getName(), "UTF-8");
            String value = URLDecoder.decode(c.getValue(), "UTF-8");
            String s = name + ": " + value + "<br/>";
            response.getWriter().print(s);
 }
HttpSession

什么是HttpSesssion
javax.servlet.http.HttpSession是由JavaWeb提供的,用来会话跟踪的类。session是服务器端对象,保存在服务器端!!!
HttpSession接口表示一个会话,我们可以把一个会话内需要共享的数据保存到HttSession对象中!

获取HttpSession对象
HttpSession request.getSesssion():如果当前会话已经有了session对象那么直接返回,如果当前会话还不存在会话,那么创建session并返回;
HttpSession request.getSession(boolean):当参数为true时,与requeset.getSession()相同。如果参数为false,那么如果当前会话中存在session则返回,不存在返回null;

HttpSession是域对象

我们已经学习过HttpServletRequest、ServletContext,它们都是域对象,现在我们又学习了一个HttpSession,
它也是域对象。它们是Servlet的三大域对象。

HttpServletRequest:一个请求创建一个request对象,所以在同一个请求中可以共享request,
例如一个请求从AServlet转发到BServlet,那么AServlet和BServlet可以共享request域中的数据;

ServletContext:一个应用只创建一个ServletContext对象,
所以在ServletContext中的数据可以在整个应用中共享,只要不启动服务器,
那么ServletContext中的数据就可以共享

HttpSession:一个会话创建一个HttpSession对象,
同一会话中的多个请求中可以共享session中的数据;

HttpSession和HttpServletRequest、ServletContext 一样 有着如下域方法
void setAttribute(String name, Object value):用来存储一个对象,也可以称之为存储一个域属性,
例如:session.setAttribute(“xxx”,“XXX”),在session中保存了一个域属性,域属性名称为xxx,域属性的值为XXX。
请注意,如果多次调用该方法,并且使用相同的name,那么会覆盖上一次的值,这一特性与Map相同;

Object getAttribute(String name):用来获取session中的数据,当前在获取之前需要先去存储才行,
例如:String value = (String) session.getAttribute(“xxx”);,获取名为xxx的域属性;

void removeAttribute(String name):用来移除HttpSession中的域属性,
如果参数name指定的域属性不存在,那么本方法什么都不做;

Enumeration getAttributeNames():获取所有域属性的名称;

登录案例
需要的页面:
login.html:登录页面,提供登录表单;
Index1Serlvet:回写当前用户名称,如果没有登录,显示您还没登录;
index2Serlve回写当前用户名称,如果没有登录,显示您还没登录
LoginServlet:在login.html页面提交表单时,请求本Servlet。在本Servlet中获取用户名、密码进行校验,如果用户名、密码错误,显示“用户名或密码错误”,如果正确保存用户名session中,然后重定向到index1Servlet;
当用户没有登录时访问index1Servlet或index1Servlet,显示“您还没有登录”。如果用户在login.html登录成功后到达index1Servlet页面会显示当前用户名,而且不用再次登录去访问index2Servlet也会显示用户名。因为多次请求在一个会话范围,index1Servlet和index2Servlet都会到session中获取用户名,session对象在一个会话中是相同的,所以都可以获取到用户名!

public class LoginServlet extends HttpServlet {
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        
        //获取表单参数username
        String username = request.getParameter("username");
        
        //如果用户为root表示登录失败
        if(username.equalsIgnoreCase("scott")) {
            response.getWriter().print("用户名或密码错误!");
        } else {
            //获取session对象
            HttpSession session = request.getSession();
            //在session中保存用户名
            session.setAttribute("username", username);
            //重定向指定的页面。
            response.sendRedirect("/index1Servlet");
       }
    }
}

HTTP协议是无状态协议。JavaWeb服务器是无法记录客户端浏览器的身份的。若需要实现回话跟踪,也需要使用一个标识。
当客户端浏览器首次访问服务器端的时候,并且当服务器首次使用session 此时要创建session,session是保存在服务器端(这个Session中可以保存一些数据)。然后,响应客户端浏览器的时候,会将这个Session的ID以Cookie的形式返回给客户端浏览器,这个SessionID在客户端就以Cookie的形式保存了。
当客户端再次访问服务器时,在请求中会带上sessionId,而服务器会通过sessionId找到对应的session,而无需再创建新的session。这样,服务器就辨识出了哪个客户端回话了。

session与浏览器
session保存在服务器,而sessionId通过Cookie发送给客户端,但这个Cookie的生命为-1,即只在浏览器内存中存在,也就是说如果用户关闭了浏览器,那么这个Cookie就丢失了。
当用户再次打开浏览器访问服务器时,就不会有sessionId发送给服务器,那么服务器会认为你没有session,所以服务器会创建一个session,并在响应中把sessionId中到Cookie中发送给客户端。

session其他常用API

String getId():获取sessionId;
int getMaxInactiveInterval():获取session可以的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session;
**void setMaxInactiveInterval(int interval):**设置session允许的最大不活动时间(秒),如果设置为1秒,那么只要session在1秒内不被使用,那么session就会被移除;
**long getCreationTime():**返回session的创建时间,返回值为当前时间的毫秒值;
long getLastAccessedTime():返回session的最后活动时间,返回值为当前时间的毫秒值;
**void invalidate():让session失效!**调用这个方法会被session失效,当session失效后,客户端再次请求,服务器会给客户端创建一个新的session,并在响应中给客户端新session的sessionId;
**boolean isNew():**查看session是否为新。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新。

public void doGet(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
 
         response.setContentType("text/html;charset=UTF-8");
         //使用request对象的getSession()获取session,如果session不存在则创建一个
         HttpSession session = request.getSession();
         //获取session的Id
         String sessionId = session.getId();
         //判断session是不是新创建的
         if (session.isNew()) {
             response.getWriter().print("session创建成功,session的id是:"+sessionId);
         }else {
             response.getWriter().print("服务器已经存在该session了,session的id是:"+sessionId);
         }
     }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值