登录后重定向回页面

Jam*_* P. 15 java redirect servlets

我正在做一个简单的论坛,其中一系列Servlets代表一个家,主题,发布,登录和用户列表页面.在其中一些页面上,当用户未登录时会显示一个链接.

我想要实现的是在登录后触发重定向(在RequestDispatcher上使用forward()),以便浏览器在单击登录链接之前返回用户所在的页面.为了做到这一点,我看到两个解决方案.

第一个解决方案是Form使用带有登录按钮和不可见字段的HTML ,该字段将包含将要重定向到哪个页面的信息Parameter.这是可行的,但我想尝试其他的东西.

第二种解决方案是将添加Attributesession代表第一个"页"以某种方式.这可能包含一个String,但这与第一种方法没有什么不同.另一个转折是添加对HttpServlet的引用并使用instanceof或静态String变量,该变量可用于以某种方式标识Servlet.但是,这需要为所有人创建一个共同的祖先类Servlets.

或许有另一个简单的解决方案,你可以看到,这将形成一个良好的妥协?或者,上述解决方案中的一种可能完全可以接受?

Bal*_*usC 26

我更喜欢第二个解决方案之上的第一个.这是请求范围的信息,实际上不属于会话,它只会导致"wtf?" 在同一会话中打开多个窗口/选项卡时的体验.

在登录页面的链接上,只需将当前URL作为请求参数传递:

<a href="/login?from=${pageContext.request.requestURI}">Login</a>
Run Code Online (Sandbox Code Playgroud)

或者,如果它是登录页面的POST表单:

<input type="hidden" name="from" value="${pageContext.request.requestURI}">
Run Code Online (Sandbox Code Playgroud)

在登录表单中,将其作为隐藏变量传输到下一个请求:

<input type="hidden" name="from" value="${param.from}">
Run Code Online (Sandbox Code Playgroud)

在登录servlet中,使用它:

User user = userDAO.find(username, password);
if (user != null) {
    request.getSession().setAttribute("user", user);
    response.sendRedirect(request.getParameter("from"));
} else {
    // Show error.
}
Run Code Online (Sandbox Code Playgroud)

相当简单,不是吗?:)

有些人可能建议request.getHeader("referer")在登录前使用登录表单而不是request.getRequestURI()链接/按钮,但我不会这样做,因为这是客户端控制的,并不总是返回可靠的信息.有些客户已经禁用它或正在使用某些软件,这些软件使用无效值来欺骗它,例如大多数(咳嗽)赛门铁克产品都会这样做.


Boz*_*zho 5

建议的第一种方法是最好的方法。value=request.getRequestURI()登录后具有一个隐藏字段,并重定向到该URI。

使用referer不起作用,因为IE(至少其某些版本)未设置referer标头。

如果用户打开多个选项卡,则在会话中存储参数会导致奇怪的行为。

编辑:为了更好地说明问题:

some resource -> (requests protected resource) -> (gets forwarded to the login page) -> (should be redirected to the original resource)

大多数答案都假定单击“登录”链接/按钮,然后打开登录页面。这只是故事的一方面。在那种情况下,原始资源URL可以作为参数添加,并放置在登录表单中(在隐藏字段中)。

但是,如果从受保护的资源转发到登录页面,则隐藏字段应包含立即请求URL。

当然,这不是问题所在,但最终会作为一种情况出现,因此也应予以考虑。