import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Test extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie[] cookies = request.getCookies(); Cookie cookie = null; if (cookies != null) { for (int i = 0; i < cookies.length; i++) { if ("counter".equals(cookies[i].getName())) { cookie = cookies[i]; response.getWriter().write(cookie.getValue()); break; } } } if (cookie == null) { cookie = new Cookie("counter", "0"); cookie.setPath("/"); cookie.setMaxAge(60*60); } else { int counter = Integer.valueOf(cookie.getValue()); counter++; cookie.setValue(Integer.toString(counter)); } response.addCookie(cookie); } }実は上のプログラムだと、クッキーが2つできてしまいます。
設定したい名前のクッキーが存在するときは、その値をインクリメントして値を更新して、レスポンスに書く。という処理をしていますが、これだけでは足りません。
int counter = Integer.valueOf(cookie.getValue()); counter++; cookie.setPath("/"); cookie.setMaxAge(60*60); cookie.setValue(Integer.toString(counter));のように最大寿命、パスを再設定してあげないといけません。 最初のソースコードでは、newしたクッキーのパスは"/"、更新するときのクッキーのパスはnullとなっていて、パスが異なるため同じ名前のクッキーが2つ出来てしまいます。
「なんだこの仕様面倒くさいなー。何でパスとか最大寿命とか再設定しないといけないの?サーブレットコンテナの中で管理してよ。」と思いましたが、よくよく考えるとHTTPリクエストのヘッダーにはクッキーの名前、値しか乗らないので、あたり前の仕様ですね。
[Request Headers]
Cookie: counter=5
[Response Headers]
Set-Cookie:counter=6; Expires=Fri, 08-Feb-2013 18:05:16 GMT; Path=/
のようにサーバーからのレスポンスには最大寿命とかパスが乗りますが、UAからのリクエストには乗らないので、getCookiesしたときにこれらの値はとれるはず無いですと。なるほど。
0 件のコメント:
コメントを投稿