对于遇到类似问题的任何人,这是对我有用的解决方案。
- 使用用户输入表单创建您的
login.jsp 页面(方法应为POST)
<form action="${pageContext.request.contextPath}/userAuth" method="POST">
...
</form>
- 创建一个过滤器类并将其映射到
login.jsp。在过滤器类中检查null,检索会话并检查它是否包含一个属性,这将表明用户已经登录(我使用了用户对象并将其映射为“用户”)
@WebFilter("/login.jsp")
public class AuthFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpSession session = ((HttpServletRequest) request).getSession();
if (session.getAttribute("user") != null) {
response.setContentType("text/html;charset=UTF-8");
request.getRequestDispatcher("homepage.jsp").forward(request, response);
}
chain.doFilter(request, response);
}
}
- 创建 servlet 类并将其映射到
login.jsp 内的表单操作。覆盖 doPost 和 doGet 方法:前者将包含用户凭据处理逻辑,后者将包含注销逻辑。
@WebServlet("/userAuth")
public class AuthServlet extends HttpServlet {
/**
* Log in
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String email = request.getParameter("email");
String password = request.getParameter("password");
try {
User user = UserDAO.getUser(email, password);
session.setAttribute("user", user);
response.sendRedirect(request.getContextPath() + "/login.jsp");
} catch (DAOException e) {
e.printStackTrace();
}
}
/**
* Log out
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
request.getSession().invalidate();
response.setContentType("text/html;charset=UTF-8");
response.sendRedirect("login.jsp");
}
}
- 创建您的
homepage.jsp 并添加将GET 发送到servlet 的注销按钮
<a href="${pageContext.request.contextPath}/userAuth">Logout</a>
现在这背后的逻辑如下:
servlet 实际上并没有重定向到用户主页。它所做的只是添加过滤器正在寻找的一个属性,并将请求重定向回login.jsp。 login.jsp 总是被过滤器拦截,如果该属性存在,过滤器会重定向到主页。
这样您将解决用户在会话开启之前保持登录的问题,以及用户在退出后能够返回或刷新页面(这将导致重新提交表单)的问题。不需要像“no-cache”这样的额外标头。