session

  因为Http的无接连,无状态,所以造就了Cookie,Session的诞生。怎样让http看上去有连接呢,需要浏览器和服务器商量建立一个唯一标识代表一个会话(即sessionId).

  1. sessionId 需要服务端创建session, 否则服务器不会自己创建session,也不会返回JSESSIONID给浏览器的cookie。 即需要程序员通过request.getSession(true)去创建。

  2.当程序员在应用里创建session后,服务器会把sessionId(key) 和 session对象 (value) put到hashMap里面

  最后返回请求时,tomcat会通过HttpResponseBase返回JSESSIONID给浏览器的cookie

 /**
     * Send the HTTP response headers, if this has not already occurred.
     */
    protected void sendHeaders() throws IOException {

        if (isCommitted())
            return;

        // Check if the request was an HTTP/0.9 request
        if ("HTTP/0.9".equals(request.getRequest().getProtocol())) {
            committed = true;
            return;
        }

        // Prepare a suitable output writer
        OutputStreamWriter osr = null;
        try {
            osr = new OutputStreamWriter(getStream(), getCharacterEncoding());
        } catch (UnsupportedEncodingException e) {
            osr = new OutputStreamWriter(getStream());
        }
        final PrintWriter outputWriter = new PrintWriter(osr);

        // Send the "Status:" header
        outputWriter.print(this.getProtocol());
        outputWriter.print(" ");
        outputWriter.print(status);
        if (message != null) {
            outputWriter.print(" ");
            outputWriter.print(message);
        }
        outputWriter.print("\r\n");
        // System.out.println("sendHeaders: " +
        //                    request.getRequest().getProtocol() +
        //                    " " + status + " " + message);

        // Send the content-length and content-type headers (if any)
        if (getContentType() != null) {
            outputWriter.print("Content-Type: " + getContentType() + "\r\n");
            // System.out.println(" Content-Type: " + getContentType());
        }
        if (getContentLength() >= 0) {
            outputWriter.print("Content-Length: " + getContentLength() +
                               "\r\n");
            // System.out.println(" Content-Length: " + getContentLength());
        }

        // Send all specified headers (if any)
        synchronized (headers) {
        Iterator names = headers.keySet().iterator();
        while (names.hasNext()) {
            String name = (String) names.next();
            ArrayList values = (ArrayList) headers.get(name);
            Iterator items = values.iterator();
            while (items.hasNext()) {
                String value = (String) items.next();
                    outputWriter.print(name);
                    outputWriter.print(": ");
                    outputWriter.print(value);
                    outputWriter.print("\r\n");
                    // System.out.println(" " + name + ": " + value);
                }
            }
        }

        // Add the session ID cookie if necessary
        HttpServletRequest hreq = (HttpServletRequest) request.getRequest();
        HttpSession session = hreq.getSession(false);

        if ((session != null) && session.isNew() && (getContext() != null)
            && getContext().getCookies()) {
            Cookie cookie = new Cookie(Globals.SESSION_COOKIE_NAME,
                                       session.getId());

            cookie.setMaxAge(-1);
            String contextPath = null;
            if (context != null)
                contextPath = context.getPath();
            if ((contextPath != null) && (contextPath.length() > 0))
                cookie.setPath(contextPath);
            else
                cookie.setPath("/");
            if (hreq.isSecure())
                cookie.setSecure(true);
            addCookie(cookie);
        }

        // Send all specified cookies (if any)
        synchronized (cookies) {
            Iterator items = cookies.iterator();
            while (items.hasNext()) {
                Cookie cookie = (Cookie) items.next();
                outputWriter.print(CookieTools.getCookieHeaderName(cookie));
                outputWriter.print(": ");
                outputWriter.print(CookieTools.getCookieHeaderValue(cookie));
                outputWriter.print("\r\n");
                //System.out.println(" " +
                //                   CookieTools.getCookieHeaderName(cookie) +
                //                   ": " +
                //                  CookieTools.getCookieHeaderValue(cookie));
            }
        }

        // Send a terminating blank line to mark the end of the headers
        outputWriter.print("\r\n");
        outputWriter.flush();
        // System.out.println("----------");

        // The response is now committed
        committed = true;

    }
View Code

3.当浏览器有sessionId的cookie后,以后的请求都会把sessionid的cookie传给服务器。

服务器获取到请求的sessionId数据后, 会去内存到(保持session的hashMap)里面通过sessionId去获取session。

原文地址:https://www.cnblogs.com/shapeOfMyHeart/p/5887227.html