转发不会更改浏览器地址栏中的URL

13

我刚开始使用Servlets/JSP/JSTL,我有以下代码:

<html>
<body>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<jsp:directive.page contentType="text/html; charset=UTF-8" />

<c:choose>
  <c:when test='${!empty login}'>
    zalogowany
  </c:when>
<c:otherwise>
   <c:if test='${showWarning == "yes"}'>
        <b>Wrong user/password</b>
    </c:if>
    <form action="Hai" method="post">
    login<br/>
     <input type="text" name="login"/><br/>
     password<br/>
     <input type="password" name="password"/>
     <input type="submit"/>
     </form>
  </c:otherwise>
</c:choose>
</body>
</html>

以及在我的doPost方法中

protected void doPost(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException 
{
    HttpSession session=request.getSession();
    try
    {
        logUser(request);
    }
    catch(EmptyFieldException e)
    {
        session.setAttribute("showWarning", "yes");
    } catch (WrongUserException e) 
    {
        session.setAttribute("showWarning", "yes");
    }
    RequestDispatcher d=request.getRequestDispatcher("/index.jsp");
    System.out.println("z");
    d.forward(request, response);
}

但是有些东西不起作用,因为我想要像这样的东西:

  1. 如果用户有活动会话并已登录到系统,则应显示“zalogowany”。
  2. 否则,登录表单

问题是无论我做什么,这些转发都没有将我放在我的项目的根文件夹中的index.jsp中,我仍然在我的地址栏中有Projekt/Hai。

1个回答

27

如果这确实是您唯一的问题

问题是无论我做什么,这些forwards都不能将我导向我的项目根文件夹中的index.jsp,我仍然在地址栏中保留着Projekt / Hai。

那么我不得不让您失望:这完全符合规范。转发基本上告诉服务器使用指定的JSP来呈现结果。它并没有告诉客户端在给定的JSP上发送新的HTTP请求。如果您希望在客户端的地址栏中看到更改,则必须告诉客户端发送新的HTTP请求。您可以通过发送重定向而不是转发来实现这一点。

因此,代替原文中的:

RequestDispatcher d=request.getRequestDispatcher("/index.jsp");
System.out.println("z");
d.forward(request, response);

response.sendRedirect(request.getContextPath() + "/index.jsp");

一个替代方案是完全摒弃/index.jsp URL,而始终使用/Hai URL。您可以通过将 JSP 存储在 /WEB-INF 文件夹中(以便最终用户无法直接打开它,并被迫使用servlet的URL)并实现servlet的doGet()来显示JSP,以实现这一目标:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.getRequestDispatcher("/WEB-INF/index.jsp").forward(request, response);
}

这样一来,您只需打开http://localhost:8080/Project/Hai,即可查看JSP页面的输出,表单将仅提交到完全相同的URL,因此浏览器地址栏中的URL基本上不会改变。我可能只会将/Hai更改为更合理的内容,例如/login

另请参阅:


好的,那我理解错了,如果我从servlet使用forward并从WEB-INF使用.jsp,那么URL仍将指向我的servlet,但是如果是这种情况,我如何检查某个用户是否首次访问页面,以便我只显示登录页面?因为一开始我认为我只需呈现.jsp页面并使用标签来确定他是否首次访问。 - Andna
3
为此,应使用过滤器:http://stackoverflow.com/tags/servlet-filters/info 简而言之:当登录成功时,将“用户”放入会话中。在过滤器中,您只需检查其是否存在,然后根据需要继续或重定向请求。 - BalusC
1
我使用 getServletContext().getRequestDispatcher("/message.jsp").forward(request, response); 从servlet重定向到jsp。但是在服务器上无法正常工作。我尝试了 response.sendRedirect(request.getContextPath() + "/message.jsp");,但是jsp没有显示我从servlet发送的消息。如何解决这个问题? - kamal
1
另一种解决方案是将转发的URL返回给客户端(例如,作为响应的自定义标头),并使用一些JavaScript来更新窗口位置历史记录 - window.history.pushstate或replacestate。这在旧版浏览器中无法正常工作(对于这些浏览器,请使用302重定向)。 - JeeBee
但请确保您不使用Web套接字,如果使用Web套接字,则会打开新会话。 - Bassel Kh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接