如果客户端不接受 cookie,如何进行会话?了解 Servlet 中的 response.encodeURL()

How to do sessions if client doesn't accept cookies? Understanding response.encodeURL() inside Servlet

我正在练习维护客户端和服务器之间的会话。为此,我使用了简单的解决方案,将 JSESSIONID 存储在 cookie 中。所以我的小程序是这样工作的:

index.html:

<html><body>
    
    <form action="testing">
        <input type="text" name="animal">
        <button>Go</button>
    </form>
    
</body></html>

MyServlet.java(在 XML 中映射为 /testing):

public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        String name = req.getParameter("animal");
        PrintWriter pw = resp.getWriter();

        pw.print("Welcome " + name + "<br>");

        HttpSession session = req.getSession();

        if (session.isNew()) {
            pw.print("New session: " + session.getId() + "<br>");
        } else {
            pw.print("Old session: " + session.getId() + "<br>");
        }

        pw.print("<a href=\'index.html\'> Home </a>");
    }
}

因此,如果我从 FORM 提交内容超过两次,服务器应该“找到”我存储在堆中的 JSESSIONID。这是提交 FORM 时的外观图片(我在输入中键入 'parrot'):

但后来我在浏览器中禁用了 cookie。之后,我的服务器再也找不到用户的 JSESSIONID 因为用户实际上从未将它存储在任何地方。请记住,之前 JSESSIONID 存储在 cookie 中,但由于我禁用了它们,它不可能再存储在那里。所以现在,我卡住了。

遇到这种情况我该怎么办?我遇到了使用 URL 并将其 JSESSIONID 附加到 URL 的 response.encodeURL()。但是我很难理解如何实现它以及它在内部是如何工作的。有人可以告诉我如何使用 encodeURL() 解决这个问题,并实际解释代码在实现后如何工作吗?

这是您可以做的事情。这用于将您的 JSESSIONID 附加到您将检索给用户的 url,以便他们可以在其中导航并维护他们是谁的信息。关于了解它的内部工作原理如您所见很简单,它只是将 id 附加到您传递的 url ,用户信息如何存储,是您在服务器端的功能,您将使用由给定的 id用户在下一个请求中向他们检索信息。

/**
* Almost minimal processing for a servlet.
*
* @param nextUrl The url the caller would like to go to next. If
*                supplied, put an encoded url into the returned
*                html page as a hyperlink.
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
   throws ServletException, IOException {

   resp.setContentType("text/plain");
   PrintWriter out = resp.getWriter();
   out.print("OK");

   String param = req.getParameter("nextUrl");
   if (param!=null) {
       // append an encoded url to carry the sessionids
       String targetUrl = resp.encodeURL(param);
       out.print(". You want to go <a href=\"");
       out.print(targetUrl);
       out.print("\">here next</a>.");
   }
}

编辑: 你把它放在你代码的这一部分

pw.print("<a href=\'" + resp.encodeURL("index.html") + "\'>Home</a>");

根据 the specification,服务器应支持几种跟踪会话的方法:使用 cookie、SSL 会话或 URL 重写。

您问的是 URL 重写,其工作方式如下:

URL rewriting is the lowest common denominator of session tracking. When a client will not accept a cookie, URL rewriting may be used by the server as the basis for session tracking. URL rewriting involves adding data, a session ID, to the URL path that is interpreted by the container to associate the request with a session.

The session ID must be encoded as a path parameter in the URL string. The name of the parameter must be jsessionid. Here is an example of a URL containing encoded path information:

http://www.myserver.com/catalog/index.html;jsessionid=1234

URL rewriting exposes session identifiers in logs, bookmarks, referer headers, cached HTML, and the URL bar. URL rewriting should not be used as a session tracking mechanism where cookies or SSL sessions are supported and suitable.

请注意,它是路径参数,而不是查询参数。您的查询参数将遵循该参数,如下所示:

http://www.myserver.com/catalog/index.html;jsessionid=1234?param1=value1&param2=value2&...

服务器自动支持此机制来跟踪会话,但很明显您需要向服务器提供帮助。您可以通过确保所有链接都包含 jsessionid 来做到这一点,否则您的服务器将无法通过会话识别您的请求。

您可以在 Java 代码中使用 encodeURL

Encodes the specified URL by including the session ID, or, if encoding is not needed, returns the URL unchanged. The implementation of this method includes the logic to determine whether the session ID needs to be encoded in the URL. For example, if the browser supports cookies, or session tracking is turned off, URL encoding is unnecessary.

For robust session tracking, all URLs emitted by a servlet should be run through this method. Otherwise, URL rewriting cannot be used with browsers which do not support cookies.

您需要在 JSP 文件中执行相同的操作。这通常是通过类似 <c:url> 的方式完成的,而不是直接将 URL 写入文件:

[...] You can use the url tag to rewrite URLs returned from a JSP page. The tag includes the session ID in the URL only if cookies are disabled; otherwise, it returns the URL unchanged. Note that this feature requires that the URL be relative. [...]