我做了一个非常简单的 登录和会话 结构,可以在将来的基于JSP的应用程序中重用。就像这样:
web.xml (1分钟超时是为了测试我的问题):
<session-config> <session-timeout>1</session-timeout> </session-config> <filter> <filter-name>Access</filter-name> <filter-class>com.app.Access</filter-class> </filter> <filter-mapping> <filter-name>Access</filter-name> <url-pattern>*</url-pattern> </filter-mapping> <servlet> <servlet-name>Login</servlet-name> <servlet-class>com.app.Login</servlet-class> </servlet> <servlet-mapping> <servlet-name>Login</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping>
Access.java 过滤器:
// Check if the page's the login or if the user logged, else asks login public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { HttpServletRequest httpRequest = (HttpServletRequest) request; boolean logged = httpRequest.getSession(false) != null && httpRequest.getSession().getAttribute("user") != null; if (httpRequest.getServletPath().equals("/login") || logged) chain.doFilter(request, response); else ((HttpServletResponse) response).sendRedirect(httpRequest.getContextPath() + "/login"); }
Login.java Servlet(认证缩短了测试的时间):
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) request.setAttribute("failure", "session timeout"); request.getSession().setAttribute("user", null); request.getRequestDispatcher("login.jsp").forward(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getSession().setAttribute("user", new User()); response.sendRedirect(""); }
WebContent根目录的 login.jsp 页面具有一个<form action="login" method="post">表单,该表单带有用于身份验证的适当innerHTML和一个 $ {failure} 字段,用于接收 会话超时 或 登录失败 消息。
<form action="login" method="post">
这种结构非常适合我。它会拦截,询问登录,检查会话和身份验证等,但是存在一个小缺陷: 如果您在登录页面上并在超时后刷新(F5或按URL上的Enter),该页面会收到并在$ {failure}中显示“会话超时”消息。
我没有找到一种真正的工作方法来使它知道上一页是登录页面。尝试了五种不同的方法但没有成功,包括request.getHeader("Referer")和lastWish标签库。
request.getHeader("Referer")
lastWish
一种方法是让可公开访问的JSP(例如登录页面) 根本不 创建会话。默认情况下,请求JSP页面即隐式创建会话。这可以通过在JSP的顶部添加以下行来实现:
<%@page session="false" %>
这种方式request.getRequestedSessionId()将返回null,因此将跳过超时检查。然后,仅当您实际登录用户时才创建会话。我只会从servlet中删除以下行,因为这没有任何意义,并且仍然会创建会话:
request.getRequestedSessionId()
null
request.getSession().setAttribute("user", null);