• servlet学习(四)--HttpSession


    HttpSession概述
    什么是HttpSesssion
    javax.servlet.http.HttpSession接口表示一个会话,我们可以把一个会话内需要共享的数据保存到HttSession对象中!

    获取HttpSession对象
    l  HttpSession request.getSesssion():如果当前会话已经有了session对象那么直接返回,如果当前会话还不存在会话,那么创建session并返回;

    l  HttpSession request.getSession(boolean):当参数为true时,与requeset.getSession()相同。如果参数为false,那么如果当前会话中存在session则返回,不存在返回null;

    HttpSession是域对象
    我们已经学习过HttpServletRequest、ServletContext,它们都是域对象,现在我们又学习了一个HttpSession,它也是域对象。它们三个是Servlet中可以使用的域对象,而JSP中可以多使用一个域对象,明天我们再讲解JSP的第四个域对象。

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

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

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

    下载是session的域方法:

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

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

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

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

    登录案例
    需要的页面:

    l  login.jsp:登录页面,提供登录表单;

    l  index1.jsp:主页,显示当前用户名称,如果没有登录,显示您还没登录;

    l  index2.jsp:主页,显示当前用户名称,如果没有登录,显示您还没登录;

    Servlet:

    l  LoginServlet:在login.jsp页面提交表单时,请求本Servlet。在本Servlet中获取用户名、密码进行校验,如果用户名、密码错误,显示“用户名或密码错误”,如果正确保存用户名session中,然后重定向到index1.jsp;

      当用户没有登录时访问index1.jsp或index2.jsp,显示“您还没有登录”。如果用户在login.jsp登录成功后到达index1.jsp页面会显示当前用户名,而且不用再次登录去访问index2.jsp也会显示用户名。因为多次请求在一个会话范围,index1.jsp和index2.jsp都会到session中获取用户名,session对象在一个会话中是相同的,所以都可以获取到用户名!

    login.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    <html>

      <head>

        <title>login.jsp</title>

      </head>

      <body>

        <h1>login.jsp</h1>

        <hr/>

        <form action="/day06_4/LoginServlet" method="post">

        用户名:<input type="text" name="username" /><br/>

            <input type="submit" value="Submit"/>

        </form>

      </body>

    </html>

    index1.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    <html>

      <head>

        <title>index1.jsp</title>

      </head>

      <body>

    <h1>index1.jsp</h1>

    <%

        String username = (String)session.getAttribute("username");

        if(username == null) {

           out.print("您还没有登录!");

        } else {

           out.print("用户名:" + username);

        }

    %>

    <hr/>

    <a href="/day06_4/index2.jsp">index2</a>

      </body>

    </html>

    index2.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    <html>

      <head>

        <title>index2.jsp</title>

      </head>

      <body>

    <h1>index2.jsp</h1>

    <%

        String username = (String)session.getAttribute("username");

        if(username == null) {

           out.print("您还没有登录!");

        } else {

           out.print("用户名:" + username);

        }

    %>

    <hr/>

    <a href="/day06_4/index1.jsp">index1</a>

      </body>

    </html>

    LoginServlet

    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");

          

           String username = request.getParameter("username");

          

           if(username.equalsIgnoreCase("cloud")) {

               response.getWriter().print("用户名或密码错误!");

           } else {

               HttpSession session = request.getSession();

               session.setAttribute("username", username);

               response.sendRedirect("/day06_4/index1.jsp");

           }

        }

    }

    session的实现原理
    session底层是依赖Cookie的!我们来理解一下session的原理吧!

    当我首次去银行时,因为还没有账号,所以需要开一个账号,我获得的是银行卡,而银行这边的数据库中留下了我的账号,我的钱是保存在银行的账号中,而我带走的是我的卡号。

    当我再次去银行时,只需要带上我的卡,而无需再次开一个账号了。只要带上我的卡,那么我在银行操作的一定是我的账号!

    当首次使用session时,服务器端要创建session,session是保存在服务器端,而给客户端的session的id(一个cookie中保存了sessionId)。客户端带走的是sessionId,而数据是保存在session中。

    当客户端再次访问服务器时,在请求中会带上sessionId,而服务器会通过sessionId找到对应的session,而无需再创建新的session。

    session与浏览器
    session保存在服务器,而sessionId通过Cookie发送给客户端,但这个Cookie的生命不-1,即只在浏览器内存中存在,也就是说如果用户关闭了浏览器,那么这个Cookie就丢失了。

    当用户再次打开浏览器访问服务器时,就不会有sessionId发送给服务器,那么服务器会认为你没有session,所以服务器会创建一个session,并在响应中把sessionId中到Cookie中发送给客户端。     

    你可能会说,那原来的session对象会怎样?当一个session长时间没人使用的话,服务器会把session删除了!这个时长在Tomcat中配置是30分钟,可以在${CATALANA}/conf/web.xml找到这个配置,当然你也可以在自己的web.xml中覆盖这个配置!

    web.xml

        <session-config>

            <session-timeout>30</session-timeout>

        </session-config>

    session失效时间也说明一个问题!如果你打开网站的一个页面开始长时间不动,超出了30分钟后,再去点击链接或提交表单时你会发现,你的session已经丢失了!

    session其他常用API
    l  String getId():获取sessionId;

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

    l  void setMaxInactiveInterval(int interval):设置session允许的最大不活动时间(秒),如果设置为1秒,那么只要session在1秒内不被使用,那么session就会被移除;

    l  long getCreationTime():返回session的创建时间,返回值为当前时间的毫秒值;

    l  long getLastAccessedTime():返回session的最后活动时间,返回值为当前时间的毫秒值;

    l  void invalidate():让session失效!调用这个方法会被session失效,当session失效后,客户端再次请求,服务器会给客户端创建一个新的session,并在响应中给客户端新session的sessionId;

    l  boolean isNew():查看session是否为新。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新。

    URL重写
    我们知道session依赖Cookie,那么session为什么依赖Cookie呢?因为服务器需要在每次请求中获取sessionId,然后找到客户端的session对象。那么如果客户端浏览器关闭了Cookie呢?那么session是不是就会不存在了呢?

    其实还有一种方法让服务器收到的每个请求中都带有sessioinId,那就是URL重写!在每个页面中的每个链接和表单中都添加名为jSessionId的参数,值为当前sessionid。当用户点击链接或提交表单时也服务器可以通过获取jSessionId这个参数来得到客户端的sessionId,找到sessoin对象。

    index.jsp

      <body>

    <h1>URL重写</h1>

    <a href='/day06_5/index.jsp;jsessionid=<%=session.getId() %>' >主页</a>

    <form action='/day06_5/index.jsp;jsessionid=<%=session.getId() %>' method="post">

        <input type="submit" value="提交"/>

    </form>

      </body>

    也可以使用response.encodeURL()对每个请求的URL处理,这个方法会自动追加jsessionid参数,与上面我们手动添加是一样的效果。

    <a href='<%=response.encodeURL("/day06_5/index.jsp") %>' >主页</a>

    <form action='<%=response.encodeURL("/day06_5/index.jsp") %>' method="post">

        <input type="submit" value="提交"/>

    </form>

    使用response.encodeURL()更加“智能”,它会判断客户端浏览器是否禁用了Cookie,如果禁用了,那么这个方法在URL后面追加jsessionid,否则不会追加。

    转自:https://blog.csdn.net/dzy21/article/details/51871154

    个人理解,如有错误,欢迎指正!
  • 相关阅读:
    vue form dynamic validator All In one
    TypeScript api response interface All In One
    closable VS closeable All In One
    macOS 如何开启 WiFi 热点 All In One
    vue css inline style All In One
    vs2010里面 新建网站里面的 asp.net网站 和 新建项目里面的 asp.net Web应用程序 的区别 (下)
    牛腩新闻 59 整合添加新闻页 FreeTextBox 富文本编辑器,检测到有潜在危险的 Request.Form 值,DropDownList 的使用
    牛腩新闻 61尾声: error.aspx的使用 防止报错
    vs2010里面 新建网站里面的 asp.net网站 和 新建项目里面的 asp.net Web应用程序 的区别 (上)
    牛腩新闻 62:尾声续2 asp.net的编译和发布
  • 原文地址:https://www.cnblogs.com/gllegolas/p/11804046.html
Copyright © 2020-2023  润新知