时间:2016-11-17 22:33

——HttpSession

一、HttpSession概述
    1、HttpSession是由JavaWeb提供的,用来进行会话跟踪的类。
    2、session和cookie的区别
        session是服务器端对象,保存在服务器端,是由JavaWeb提供的,只有JavaWeb有。
        cookie保存在客户端,是由HTTP协议提供的。
    3、HttpSession是Servlet三大域对象之一,所以它也有setAttribute()、getAttribute()和removeAttribute()方法。
    4、HttpSession底层依赖Cookie或是URL重写。

二、HttpSession的作用
    1、会话范围
        会话范围是某个用户从首次访问服务器开始,到该用户关闭浏览器结束。

    2、会话
        一个用户对服务器的多次连贯性请求,所谓连贯性请求,就是该用户多次请求中间没有关闭浏览器。

    3、服务器会为每个客户端创建一个session对象,它们被服务器保存到一个Map中,这个Map被称为session缓存。
        *   Servlet中得到session对象:HttpSession session = request.getSession();
        *   JSP中得到session对象:session是JSP内置对象,不需要创建就可以直接使用。

    4、session域的相关方法:
        void setAttribute(String name,Object value)
        Object getAttribute(String name)
        void removeAttribute(String name)

三、案例1
    演示session中会话的多次请求中共享数据
    *   AServlet:向session域中保存数据
        a.jsp:

            <h1>向Session域保存数据</h1>
            <%
                //如果需要自己手动获取session对象,代码如下
                //HttpSession session = request.getSession();
                session.setAttribute("aaa","AAA");
           %>

*   BServlet:从session域中获取数据
        b.jsp:

            <h1>获取session中的数据</h1>
            <%
                String s = (String)session.getAttribute("aaa");
            %>
            <%=s %>

*   演示
        第一个请求:访问AServlet
        第二个请求:访问BServlet
    *   此时如果不关闭当前浏览器再打开新的浏览器窗口,则也能访问到b.jsp中的session对象,即也可以输出“AAA”

四、案例2
    演示保存用户登录信息(必须掌握)
    问题:
        为什么请求重定向需要包含完整Servlet路径?
            因为重定向是客户端根据URL重新发送请求,所以需要重写URL。 

1、案例相关页面和Servlet
    *   login.jsp:登录页面
    *   successful1.jsp:只有登录成功才能访问的页面
    *   successful2.jsp:只有登录成功才能访问的页面
    *   LoginServlet.java:校验用户是否登录成功

2、各页面和Servlet内容
    *   login.jsp:提供登录表单,提交表单请求LoginServlet
    *   LoginServlet:获取请求参数,校验用户是否登录成功
        成功:保存用户信息到session域中,重定向到successful1.jsp页面,显示session域中的用户信息。
            重定向是客户端请求,必须加项目名。
        失败:保存错误信息到request域中,转发到login.jsp(login.jsp显示request域中的错误信息)
        如果需要进行跨请求获取参数,就是用session,如果只需要一个请求,则使用request,尽量使用范围小的域对象。
    *   successful1.jsp:从session域中获取用户信息,如果不存在,显示“您还没有登录”,存在则显示用户信息。
    *   successful2.jsp:从session域中获取用户信息,如果不存在,显示“您还没有登录”,存在则显示用户信息。

    只要用户没有关闭浏览器,session就一直存在,那么保存在session中的用户信息也就存在,那么用户
    访问successful1.jsp和successful2.jsp就会成功。

代码如下:
------------------------------------------------------------------------------------------------------------------------------------------
login.jsp


<body>
    <%-- 本页面提供登录表单,还要显示错误信息 --%>
    <h1>登录</h1>
    <%
        //读取名字为cusername的Cookie
        //如果为空显示:""
        //如果不为空显示:cookie的值
        String cusername = "";
        //获取请求中所有的Cookie
        Cookie[] cs = request.getCookies();
        if(cs != null)//如果存在cookie
        {
            for(Cookie c : cs)//循环遍历所有的cookie
            {
                if("cusername".equals(c.getName()))//查找名为cusername的cookie
                {
                    cusername = c.getValue();//获取这个cookie的值,赋给cusername变量
                }
            }
        }
    %>

    <%--输出错误信息 --%>
    <%
        String errorMessage = "";
        //获取request域中的错误信息
        String message = (String)request.getAttribute("errorMessage");
        if(message != null)
        {
            errorMessage = message;
        }
    %>
    <font color="red"><b><%=errorMessage %></b></font>
    <%--把cookie中的用户名显示到用户名文本框中 --%>
    <form action="/day11_3/LoginServlet" method="post">
        用户名:<input type="text" name="username" value="<%=cusername%>"/><br/>
        密    码:<input type="password" name="password" /><br/>
        <input type="submit" vale="登录" />
    </form>
</body>

------------------------------------------------------------------------------------------------------------------------------------------

LoginServlet.java
    //1、获取表单数据
    //处理编码问题
    request.setCharacterEncoding("utf-8");
    //获取参数
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    //2、验证用户名和密码
    if("admin".equalsIgnoreCase(username) && "admin".equalsIgnoreCase(password))
    {
        //将用户名保存到cookie中,发送给客户端浏览器
        //当再次打开login.jsp时,login.jsp会读取request中的cookie,把它显示到用户名文本框中
        Cookie cookie = new Cookie("cusername",username);//创建Cookie
        cookie.setMaxAge(60*60);
        response.addCookie(cookie);//保存cookie,最终会变成设置Set-Cookie的头
        //3、登录成功,保存信息到session
        HttpSession session = request.getSession();//获取Session对象
        session.setAttribute("username", username);//在session域中保存用户名
        //重定向到successful1.jsp
        response.sendRedirect("/day11_3/session2/successful2.jsp");
    }
    else
    {
        //登录失败
        //保存错误信息到request域中
        request.setAttribute("errorMessage", "用户名或密码不正确");
        //转发到login.jsp
        RequestDispatcher rd = request.getRequestDispatcher("/session2/login.jsp");//得到转发对象
        rd.forward(request, response);
    }

-----------------------------------------------------------------------------------------------------------------------------------------

successful.jsp

<body>
    <h1>Successful1</h1>
    <%
        String username = (String)session.getAttribute("username");
        if(username == null)
        {
            //向request域中保存错误信息,转发到login.jsp
            request.setAttribute("errorMessage","请先登录");
            request.getRequestDispatcher("/session/login.jsp").forward(request, response);
            return;
        }
    %>
    <%=username %>登录成功  
</body>

五、HttpSession原理

    session保存在服务器,通过Cookie将SessionID传递给客户端。

    request.getSession()方法
    1、获取Cookie中的JSESSIONID:
        *   如果sessionId不存在,就创建session,把session保存起来,把新创建的sessionId(JSESSIONID)保存到Cookie中。
        *   如果sessionId存在,通过sessionId查找session对象,如果没有查找到,创建session对象,把新创建的sessionId保存到Cookie中。
        *   如果sessionId存在,通过sessionId查找到session对象,那么就不会再创建session对象了。
        *   返回session对象。
    2、如果创建了新的session,浏览器会得到一个包含了sessionId的Cookie,这个Cookie的生命为-1,即只在浏览器内存中存在,如果不关闭浏览器,那么Cookie就一直存在。
    3、下次请求再执行request.getSession()方法时,因为可以通过Cookie中的sessionId找到session对象,所以与上一次请求使用的是同一session对象。
    4、服务器不会马上创建session,而是在第一次获取时(getSession()),才会创建Session对象。
    5、如果访问JSP页面,则会自动创建SESSION对象,因为Session对象是JSP内置对象。

    getSession(false)、getSession(true)、getSession()方法的区别:
        getSession(false):如果session缓存中(Cookie中)不存在session,那么返回null,而不会创建session对象。
    
六、HttpSession其他方法
    String getId()
        获取sessionId。

        UUID:生成一个随机的、不重复的、32位长度的、16进制字符串。
        UUID代码:
            //获取UUID对象

            UUID uuid = UUID.randomUUID();
            //将UUID对象转换成字符串
            String string = uuid.toString();
            //去掉“-”字符
            string = string.replace("-", "");
            //将字母转换成大写
            string = string.toUpperCase();

        sessionId的获取方式就是通过UUID来获取的。
        sessionId可以放到cookie中发送给客户端。 

        问题:sessionId的作用是什么? 

int getMaxInactiveInterval()
        获取session的最大不活动时间(秒),默认为30分钟,当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session。

    void invalidate()
        让session失效,调用这个方法session会失效,当session失效后,客户端再次请求,服务器会为此次会话创建一个新的session,并在响应中给客户端新session的sessionId。可以用作退出登录按钮。

    boolean isNew()
        查看session是否是新的,当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时的session的状态为新。
        只要请求中不带cookie,那么session就是新的。当把sessionId放到cookie发送给客户端后,客户端再发送请求,那么session就是旧的。
        该方法可以用来判断是创建session还是返回session:request.getSession().isNew();

七、web.xml中配置session的最大不活动时间
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

八、URL重写

    就是把页面中所有的超链接路径,都使用response.encodeURL("....")进行处理。
 
    1、session依赖cookie,目的是让客户端发出请求时归还sessionId,这样才能找到它对应的session。
    2、如果客户端禁用了Cookie,那么就无法得到sessionId,所以session也就无法使用了。
    3、也可以使用URL重写来替代Cookie
        *   这让网站的所有超链接、表单中都添加一个特殊的请求参数,即sessionId。
        *   这样服务器可以通过获取请求参数得到sessionId,从而找到session对象。
    4、response.encodeURL(String url)
        *   该方法会对URL进行智能的重写:当请求中没有归还sessionId这个cookie,那么该方法会重写URL,否则不重写。
        *   URL必须是指向本站的URL。

JavaWeb之HttpSession的更多相关文章

  1. JavaWeb:HttpSession(一)

    Session机制: 1).session机制采用的是在服务器端保持 HTTP 状态信息的方案 . 2).当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否包含 ...

  2. JavaWeb 后端 <四> 之 Cookie HttpSession 学习笔记

    一.会话管理概述 1.什么是会话? 好比一次通话.打开浏览器,点击多次链接(发出多次请求和收到多次的响应),关闭浏览器,这个过程就是一次会话. 有功能 可以  文件 新建会话 2.解决的问题是什么? ...

  3. Javaweb学习笔记——(十一)——————JSP、会话跟踪、Cookie、HttpSession

    JSP1.什么是JSP jsp即java server pages,它是Javaweb的动态资源. jsp = html + java脚本 + jsp动态标签(包含EL表达式)2.JSP中java脚本 ...

  4. 超全面的JavaWeb笔记day11<JSP&Session&Cookie&HttpSession>

    1.JSP 2.回话跟踪技术 3.Cookie 4.HttpSession JSP入门 1 JSP概述 1.1 什么是JSP JSP(Java Server Pages)是JavaWeb服务器端的动态 ...

  5. JavaWeb学习笔记——开发动态WEB资源(八)cookies和httpsession

    会话: cookies: (1)cookies是WEB服务器发送到浏览器的简短文本信息 (2)cookies可以禁用 httpsession: 一次会话是从你打开浏览器开始到你关闭浏览器结束 提供一种 ...

  6. JavaWeb学习笔记-使用HttpSession对象跟踪会话

    使用HttpSession接口开发的步骤: 1.获取HttpSession对象 2.对HttpSession对象进行读写 3.手工终止HttpSession,或者自动终止 常用方法: getId(): ...

  7. JavaWeb——Listener

    一.基本概念 JavaWeb里面的listener是通过观察者设计模式进行实现的.对于观察者模式,这里不做过多介绍,大概讲一下什么意思. 观察者模式又叫发布订阅模式或者监听器模式.在该模式中有两个角色 ...

  8. Javaweb学习笔记——上传下载文件

    一.前言 在Javaweb中,上传下载是经常用到的功能,对于文件上传,浏览器在上传的过程中是以流的过程将文件传给服务器,一般都是使用commons-fileupload这个包实现上传功能,因为comm ...

  9. HttpSession

    (Cookie是用来设置浏览器保存数据的时间的: Session是只要浏览器不关闭,数据则会存在,一旦关闭浏览器数据即消失 ) 1. HttpSession概述 * HttpSession是由Java ...

随机推荐

  1. ArrayList 深入浅出

    ArrayList 特点:按添加顺序排列.可重复.非线程安全: 底层实现:数组 扩容原理:初始化集合时,默认容量为 0,第一次添加元素时扩容为 10,容量不够时扩容为原来容量的 1.5 倍. 这里扩容 ...

  2. 【LeetCode】933.最近的请求次数

    933.最近的请求次数 知识点:队列: 题目描述 写一个 RecentCounter 类来计算特定时间范围内最近的请求. 请你实现 RecentCounter 类: RecentCounter() 初 ...

  3. 【并查集模板】并查集模板 luogu-3367

    题目描述 简单的并查集模板 输入描述 第一行包含两个整数N.M,表示共有N个元素和M个操作. 接下来M行,每行包含三个整数Zi.Xi.Yi 当Zi=1时,将Xi与Yi所在的集合合并 当Zi=2时,输出 ...

  4. Win10离线安装.net3.5

    起因 工作原因需要安装vs2008,但是依赖.net3.5,寻找可以离线安装的版本 尝试 下载.net framework sp1完整包 dotnetfx35.exe 可选下载 语言包 dotnetf ...

  5. 【Azure API 管理】在APIM中使用客户端证书验证API的请求,但是一直提示错误"No client certificate received."

    API 管理 (APIM) 是一种为现有后端服务创建一致且现代化的 API 网关的方法. 问题描述 在设置了APIM客户端证书,用户保护后端API,让请求更安全. 但是,最近发现使用客户端证书的API ...

  6. Spring Security OAuth2 远程命令执行漏洞(CVE-2016-4977)

    影响版本: 2.0.0-2.0.9 1.0.0-1.0.5 poc地址 https://github.com/vulhub/vulhub/blob/master/spring/CVE-2016-497 ...

  7. 面试官:展开说说,Spring中Bean对象是如何通过注解注入的?

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 章节目录(手写Spring,让你了解更多) [x] 第 01 章:开篇介绍,我要带你撸 Spr ...

  8. 使用 C++ WinRT 组件

    创建 C++ WinRT 组件 通过 Cpp/WinRT 项目模板创建一个 WinRT 组件工程 CppWinrtComponent.vcxproj,主要接口定义如下: namespace CppWi ...

  9. 【SpringCloud技术专题】「原生态Fegin」打开Fegin之RPC技术的开端,你会使用原生态的Fegin吗?(上)

    前提介绍 Feign是SpringCloud中服务消费端的调用框架,通常与ribbon,hystrix等组合使用. 由于遗留原因,某些项目中,整个系统并不是SpringCloud项目,甚至不是Spri ...

  10. 《手把手教你》系列技巧篇(十六)-java+ selenium自动化测试-元素定位大法之By xpath下卷(详细教程)

    1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍定位倒数二个方法:By xpath.xpath 的定位方法, 非常强大.  使用这种方法几乎可以定位到页面上的任意元素. ...