JavaWeb--Cookie&Session

Cookie&Session

1. 什么是Cookie?

Cookie 是一个保存在客户机中的简单的文本文件, 这个文件与特定的 Web文档关联在一起, 保存了该客户机访问这个Web 文档时的信息, 当客户机再次访问这个 Web 文档时这些信息可供该文档使用;这些信息以键值对的形式保存,每个Cookie的大小不能超过4kb

2. 如何创建Cookie?

如果本地客户端没有Cookie文件,服务器就会创建一个Cookie对象,并通过响应头Set-Cookie通知客户端保存Cookie;如果本地客户端有Cookie文件,服务器则通过响应头Set-Cookie通知客户端保存Cookie修改Cookie

Servlet程序中的代码:

protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //1. 创建Cookie对象
    Cookie cookie = new Cookie("key1", "value1");
    //2. 通知客户端保存cookie
    resp.addCookie(cookie);
    //1. 创建Cookie对象
    Cookie cookie1 = new Cookie("key2", "value2");
    //2. 通知客户端保存cookie
    resp.addCookie(cookie1);

    resp.getWriter().write("Cookie创建成功");
}

3. 服务器如何获取Cookie?

服务器通过HttpServletRequest对象的getCookies()方法获取Cookie,该方法返回一个Cookie[]数组

protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    Cookie[] cookies = req.getCookies();

    for (Cookie cookie : cookies) {
        //getName()返回Cookie的key(名)
        //getValue()返回Cookie的Value值
        resp.getWriter().write("Cookie:" + cookie.getName() + "-" + cookie.getValue() + "<br/>");
    }
}

由于寻找特定Cookie的操作很常用,所以将该方法编写成一个工具类的静态方法:

public class CookieUtils {
    /**
     * 查找指定名称的Cookie对象
     * @param name
     * @param cookies
     * @return
     */
    public static Cookie findCookie(String name, Cookie[] cookies){
        if(name == null || cookies == null || cookies.length == 0){
            return null;
        }

        for (Cookie cookie : cookies) {
            if(name.equals(cookie.getName())){
                return cookie;
            }
        }
        return null;
    }
}

使用工具类获取指定Cookie:

protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    Cookie[] cookies = req.getCookies();

    for (Cookie cookie : cookies) {
        //getName()返回Cookie的key(名)
        //getValue()返回Cookie的Value值
        resp.getWriter().write("Cookie:" + cookie.getName() + "-" + cookie.getValue() + "<br/>");
    }

    Cookie cookie = CookieUtils.findCookie("key1",cookies);

    //如果cookie不为null,说明找到了需要的cookie
    if(cookie != null){
        resp.getWriter().write("cookie已找到");
    }
}

4. 如何修改Cookie值?

方案一:

  1. 先创建一个要修改的同名(key相同)的Cookie对象
  2. 在构造器中赋予新的Cookie值
  3. 调用addCookie(cookie)方法保存Cookie
//方案一:创建一个同名的cookie,并修改值
Cookie cookie = new Cookie("key1", "newValue1");
resp.addCookie(cookie);

方案二:

  1. 先查找到需要修改的Cookie对象
  2. 调用SetValue()方法赋予新的Cookie值
  3. 调用addCookie(cookie)方法保存Cookie
//方案二:查找到需要修改的Cookie对象,调用setValue()赋予新值
Cookie cookie = CookieUtils.findCookie("key1", req.getCookies());
if(cookie != null){
    cookie.setValue("newValue1");
    resp.addCookie(cookie);
}

resp.getWriter().write("修改Cookie-key1的值");

5. Cookie生命周期控制

Cookie的生命周期控制指的是管理Cookie的生命周期,即Cookie什么时候被销毁(删除)

setMaxaAge(int expiry)

  • 参数为正数,表示Cookie将在指定的秒数之后过期
  • 参数为负数,表示Cookie将在浏览器关闭之后删除(默认为-1)
  • 参数为零,表示Cookie将被立刻删除
protected void liveCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    Cookie cookie = new Cookie("life3600", "life3600");
    cookie.setMaxAge(60 * 60);//设置Cookie一小时之后删除
    resp.addCookie(cookie);
    resp.getWriter().write("创建存活时间为一小时的cookie");
}

protected void deleteCookieNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    Cookie cookie = CookieUtils.findCookie("defaultLife", req.getCookies());
    if(cookie != null){
        cookie.setMaxAge(0);//0表示马上删除
        resp.addCookie(cookie);
        resp.getWriter().write("cookie已删除");
    }
}

protected void defaultLifeCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    Cookie cookie = new Cookie("defaultLife", "defaultLife");
    cookie.setMaxAge(-1);
    resp.addCookie(cookie);
}

6. Cookie有效路径Path的设置

Cookie的path属性可以通过请求的地址,有效地过滤哪些Cookie发送给服务器,哪些不发

Cookie A path=/工程路径

Cookie B path=/工程路径/abc

请求地址如下:

http://ip:port/工程路径/a.html

Cookie A发送;Cookie B不发送

http://ip:port/工程路径/abc/a.html

Cookie A发送;Cookie B发送

protected void testCookiePath(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    Cookie cookie = new Cookie("path1", "path1");
    //getContextPath():得到工程路径
    cookie.setPath(req.getContextPath() + "/abc");// 工程路径/abc
    resp.addCookie(cookie);
    resp.getWriter().write("创建了一个带有Path路径的Cookie");
}

7. Cookie练习--免用户名登录

在第一次请求创建包含用户名信息的Cookie,在之后的请求中利用该Cookie将用户名回显至页面上

登录:

<form action="http://localhost:8080/09_cookie_session/loginServlet" method="get">
    用户名:<input type="text" name="username" value="${cookie.username.value}"/><br/>
    密码:<input type="password" name="password"><br/>
    <input type="submit" value="登录">
</form>

Servlet程序:

public class LoginServlet extends BaseServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        if("th1024".equals(username) && "123456".equals(password)){
            //登录成功
            Cookie cookie = new Cookie("username", username);
            cookie.setMaxAge(60 * 60 * 24 * 7);//当前Cookie一周内有效
            resp.addCookie(cookie);
            System.out.println("登录成功");
        }else{
            //登录失败
            System.out.println("登录失败");
        }
    }
}

Session

1. 什么是Session?

Session在计算机中,尤其是在网络应用中,称为“会话控制”;Session对象存储特定用户会话所需的属性及配置信息,这样,当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去

2. 如何创建Session和获取?(id号是否为新)

创建Session:request.getSession()

第一次调用--创建Session会话

之后调用--获取之前创建的Session会话

判断是否为新创建的Session:isNew()

true--表示刚创建的Session会话

false--表示Session会话在之前就已经创建

获取Session会话的id:getId()

每个Session会话都有一个且仅有一个唯一的id

protected void createOrGetSession(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //创建和获取Session会话对象
    HttpSession session = req.getSession();
    //判断当前Session是否是新创建出来的
    boolean aNew = session.isNew();
    //获取Session对话的唯一标识id
    String id = session.getId();

    resp.getWriter().write("SessionId:" + id + "<br/>");
    resp.getWriter().write("是否为新创建的Session对象:" + aNew + "<br/>");
}

3. 如何存取Session域数据的值?

存:setAttribute(key,value);取:getAttribute(key)

protected void setAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    req.getSession().setAttribute("key1","value1");
    resp.getWriter().write("往Session域中保存了数据");
}

protected void getAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    Object key1 = req.getSession().getAttribute("key1");
    resp.getWriter().write("从Session域中提取了数据:" + key1);
}

4. Session生命周期控制

Session生命周期控制是指控制Session会话超时的时间

setMaxInactiveInterval(int i)

  • 参数为正数,表示Session将在指定的时间(以秒为单位)之后超时
  • 参数为负数,表示Session永不超时

getMaxInactiveInterval():获取Session的超时时间

invalidate():使当前Session会话立即超时无效

Session的默认超时时长为30分钟

protected void deleteSessionNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    HttpSession session = req.getSession();
    //设置当前Session马上超时
    session.invalidate();

    resp.getWriter().write("Session已超时");
}

protected void life3Session(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    HttpSession session = req.getSession();
    //设置当前Session3秒后超时
    session.setMaxInactiveInterval(3);

    resp.getWriter().write("设置当前Session3秒后超时");
}

protected void defaultLifeSession(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    int maxInactiveInterval = req.getSession().getMaxInactiveInterval();
    resp.getWriter().write("Session的默认超时时长为" + maxInactiveInterval);
}

5. 客户端浏览器和Session技术是如何关联的

Session技术与客户端浏览器的关联是基于Cookie技术实现的:

当客户端浏览器在没有Cookie的情况下发送一个请求到服务器时,服务器会创建一个Session对象返回至客户端浏览器,并为这个Session对象创建一个Cookie对象,该Cookie对象的key="JSESSIONID",value为Session对象的id值,这个Cookie对象会被保存至客户端浏览器;之后客户端浏览器每次发送请求至服务器时,保存有Session的id值的Cookie也会被发送到服务器,服务器就根据该id值在内存中寻找对应的Session对象并返回

上一篇:Ajax响应处理数据的三种格式


下一篇:response.getWriter.print()出现中文乱码的解决方法