Servlet Cookie 获取不到问题
使用传统Servlet编写一个简单的用户登录Servlet发生一个奇怪的问题。我添加一个记住用户名的功能,结果怎么也没办法通过el表达式在本地获取设定好的cookie,找了半天才发现问题,写出来希望其它和我一样的初学者遇到这个坑能少走找到原因。有问题的代码如下:
项目中用到包版本如下:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!--servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--jsp -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!--jstl-->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
登录的servlet代码如下:
package com.hyq.sessionAndCookieStudy.web;
import com.hyq.sessionAndCookieStudy.pojo.User;
import com.hyq.sessionAndCookieStudy.service.UserService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/user/login")
public class LoginServlet extends HttpServlet {
//封装了Mybatis访问数据库的操作。这里的操作是没问题的我就不贴出相应代码
UserService userService;
public LoginServlet(){
userService = new UserService();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取Post传过来的参数
String username,password,rememberMe;
username = req.getParameter("username");
password= req.getParameter("password");
rememberMe= req.getParameter("rememberMe");
//在数据库中查用户名密码是否正确
User user = userService.login(username,password);
System.out.println(user);
if(user == null){
//用户名或密码错,返回登录页面并提供错误
req.setAttribute("login_msg","用户名或密码错");
req.getRequestDispatcher("/jsp/Login.jsp").forward(req,resp);
}
else{
//登录成功
if("1".equals(rememberMe)){
//用Cookie记住用户名
Cookie cookie = new Cookie("uname",username);
cookie.setMaxAge(60*60*24*7);
resp.addCookie(cookie);
}
//用Session记录用户信息并返回一个简单的欢迎页面
req.getSession().setAttribute("user",user);
resp.sendRedirect("/jsp/welcome.jsp");
}
}
}
登录页面Login.jsp代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1 style="color: red">${login_msg}</h1>
<form action="/user/login" method="post">
用户名: <input type="text" name="username" value="${cookie.uname.value}" /> <br />
密码: <input type="password" name="password" /> <br/>
<input type="submit" value="登录">
<a href="/jsp/reg.jsp" >注册用户</a><br />
<input type="checkbox" value="1" name="rememberMe" />记住我 <br />
</form>
</body>
</html>
用这个代码无论如何也不能获取到Cookie,用chorme的网络工具可以看到响应头明明是的set-cookie信息
查看chorme浏览器设置->安全和隐私设置中也可看到uname这个cookie已存放。
找了半天原因,最后发现不知道为什么存在本地的cookie路径写/user,这就是原因了,浏览器是通过域名和路径来确认哪些cookie是要写到header中给到服务器,而我的登录页面的地址在http://localhost:8080/jsp/login.jsp在jsp录,导致浏览器不识别没有将cookie发送出来。
解决方法:
问题找到了,那么解决方法就2个
- 把login.jsp的目录改到user下;
- 把cookies中的路径改掉;
方法1就不多说,移动一下文件目录 就好了。
方法2的话在LoginServlet中doPost中登录成功部份添加一代码如下:
//登录成功
if("1".equals(rememberMe)){
//用Cookie记住用户名
Cookie cookie = new Cookie("uname",username);
cookie.setMaxAge(60*60*24*7);
cookie.setPath("/");//设定目录为/
resp.addCookie(cookie);
}
//用Session记录用户信息并返回一个简单的欢迎页面
req.getSession().setAttribute("user",user);
resp.sendRedirect("/jsp/welcome.jsp");
扩展话题
后来经过测试发现Cookie如果设定path默认使用当前Servlet访问路径的目录做为Path。
比如一个Servlet的路径是/test/demo,在里边生成的cookie默认path值为/test。
所以网上学的很多教程都是在一个目录下处理的代码,看着别人不出问题,自己编写就出问题的原因是在这里
另外domain也有这问题。如果你用localhost访问,生成的cookie也是localhost,你再用127.0.0.1访问也不能获得localhost的cookie