3

サーブレットは、ブラウザーを閉じたとき (Cookie を削除していないとき) 以外は期待どおりに動作しており、セッションが失われます。セッションを無効にするか、Cookie を削除するまで、セッションを無期限に保存するにはどうすればよいですか?

@WebServlet(name="ServletOne", urlPatterns={"/", "/ServletOne"})
public class ServletOne extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
        HttpSession session = request.getSession(true);
        String newValue = request.getParameter("newValue");

        if (session.isNew()) {
            session = request.getSession(true);
            session.setAttribute("myAttribute", "value");
        }

        if (newValue != null)
            session.setAttribute("myAttribute", newValue);

        RequestDispatcher rd = request.getRequestDispatcher("test.jsp");
        rd.forward(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
        doGet(request, response);
    }
}

私のJSP:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    val == <c:out value="${myAttribute}"></c:out><br>
    <form action="ServletOne" method="POST">
        <input type="text" name="newValue" />
        <input type="submit" />
    </form>
</body>
</html>

ブラウザを閉じて再度開くと、myAttribute常にデフォルトの「値」に設定されます。

4

1 に答える 1

6

セッション Cookie の仕組みを完全に誤解しているようです。

セッション Cookie は、ブラウザー インスタンスが存続している限り存続しpath、デフォルトのサーバー側セッションの有効期限 (デフォルトは 30 分) の前の時間内に、Cookie によってカバーされるターゲット URL で HTTP 要求を発行しています。

ブラウザー インスタンス (つまり、ブラウザー セッション) を閉じると、すべてのセッション Cookie が失われます。これは完全に規定された、予期される自然な動作です。Web ブラウザーは、何十年もの間、常にそのように機能してきました。HttpSessionCookie に関連付けられたインスタンスはサーバーにまだ存在することに注意してください。この関連する回答SessionTimeout: web.xml vs session.maxInactiveInterval()HttpSessionListenerに基づいて実装すると、ブラウザが閉じられたときにメソッドがすぐに呼び出されるのではなく、30 分強後にのみ呼び出されることがわかります。sessionDestroyed()

サーバー側の有効期限が切れる前にブラウザー インスタンスを再度開き、セッション ハイジャックHttpSession攻撃を実行すると、関連付けられたインスタンスを保持できます。

以下も参照してください。


ここで、ブラウザ セッションよりも長く Cookie を保持するという具体的な機能要件に戻ると、これは実際には非常に簡単です。セッション Cookieではない独自の Cookie を作成します。つまり、CookiemaxAge-1(デフォルト値) に設定するのではなく、指定された時間 (秒単位) に設定します。

Cookie cookie = new Cookie("someCommonName", "someUniqueValue");
cookie.setMaxAge(ageInSeconds); // Use e.g. 2952000 for 30 days.
response.addCookie(cookie);

次に、のsomeUniqueValueようなものにすることができますjava.util.UUID。その値をデータ ストレージ システム (SQL DB ?) のキーとして使用し、その値を保存することもできmyattributeます。後続のすべてのリクエストで、 を介して Cookie の存在を確認するだけrequest.getCookies()です。このようにして、それをクライアントに関連付けることができます。必要に応じて、HTTP セッションでキャッシュして、すべての HTTP 要求をチェックする必要がないようにします。

以下も参照してください。

于 2013-09-03T15:04:04.233 に答える