Java Servlet向调用方/上一页转发响应

Java Servlet向调用方/上一页转发响应,java,jakarta-ee,servlets,servlet-3.0,Java,Jakarta Ee,Servlets,Servlet 3.0,我试图将servlet响应转发到来自同一页面的同一页面(也称为上一页面,或“servlet”调用者) 我已经看到了很多答案(如和),但仍然无法实现 我通常执行以下操作将servlet的响应重定向到另一个页面: request.getRequestDispatcher("MyNewPage").forward(request, response); 但我尝试将“MyNewPage”更改为我认为是解决方案的其他选项: request.getRequestDispatcher((String)req

我试图将servlet响应转发到来自同一页面的同一页面(也称为上一页面,或“servlet”调用者)

我已经看到了很多答案(如和),但仍然无法实现

我通常执行以下操作将servlet的响应重定向到另一个页面:

request.getRequestDispatcher("MyNewPage").forward(request, response);
但我尝试将“MyNewPage”更改为我认为是解决方案的其他选项:

request.getRequestDispatcher((String)request.getAttribute("javax.servlet.forward.request_uri")).forward(request, response);
request.getRequestDispatcher(request.getHeader("referer")).forward(request, response);
和其他选项,但无法使其工作


我做错了什么?

首先是
请求。getHeader(“referer”)
返回完整的URL,但您必须去掉
http://server[:port]/
因为传递给request.getRequestDispatcher()的内容被添加到应用程序上下文中,如下所示:

/NameOfApp/http:/localhost:8084/NameOfApp/test.jsp
这不是您想要的,因为您只需要将以下内容传递给dispatcher方法:

test.jsp
如果我们从一开始就采取行动,那么第一个请求将从以下URL开始:

http://localhost:8084/RequestDispatcher/test.jsp
转发可以工作,但是当您第二次向Servlet发出请求时,Servlet将转发到自身。因此,您将进入一个Servlet调用自身的循环。为什么会这样?由于从表单中调用Servlet,这意味着浏览器地址框中的URL地址将在第一次请求后更改为Servlet的URL地址

http://localhost:8084/RequestDispatcher/NewServlet
Servlet将请求转发回JSP页面,浏览器将仅显示该请求,但浏览器地址框中的URL仍然是包含Servlet的URL,而不是JSP页面:

http://localhost:8084/RequestDispatcher/NewServlet
因此,下次点击submit时,Servlet将尝试将请求转发给自己。如果我是你,我会使用重定向。这似乎更适合您的目的:

response.sendRedirect(request.getHeader("referer"));
这将始终更改浏览器地址框中的URL,并防止Servlet循环。这将对请求参数产生影响,但您始终可以将它们添加到重定向URL(如果不是敏感信息)上,或者将它们存储在会话中,直到您在重定向发出的下一个第一个请求中检索它们为止

像JSF这样的框架可以避免这些问题

允许您使用forward的最简单的解决方案是表单中的隐藏参数,该参数保留调用Servlet的JSP(viewid),而不是使用request.getHeader(“referer”)。不过,您需要检查循环,因为有人可能会故意更改该值以强制您的Servlet容器循环,最终导致VM崩溃。但是您可以只使用request属性来记录链中的前一个请求,如果是相同的,您将以错误响应。因此,在servlet中,您将使用隐藏字段值来决定转发到何处:

request.getRequestDispatcher(request.getParameter("viewid")).forward(request, response);
在JSP中:

<input type="hidden" name="viewid" value="test.jsp">


我认为这可以满足您的需求。

更好的策略是在请求中添加caller属性。因此,在处理被调用方之后,servlet可以将其请求转发回调用方

大概

呼叫方

request.setAttribute("caller", "/page/Foo.jsp");
被叫方

String uri = (String)request.getAttribute("caller");
getServletContext().getRequestDispatcher(uri).forward(request, response);

或者您可以尝试在会话中添加调用者,并在转发后将其删除。

您想向Servlet发出请求,然后将请求转发给自身吗?不,假设我有一个带有表单的test.jsp。提交时,它调用/MyServlet,如果出现错误,我希望MyServlet使用用户发送的值重定向到test.jsp。我不能只放test.jsp,因为这个页面是使用一些get参数自动生成的。例如,如果我为请求设置了一个属性error,那么当它到达jsp时,该属性error为null。而且,jsp有一个表单,该表单在执行此操作时被重置。我想保留用户发送的值。我在回答的底部为您添加了另一个解决方案。我可以想出许多解决方案,但这一个似乎是最容易实现的。