简体   繁体   English

Servlet 将响应转发给调用者/上一页

[英]Servlet forward response to caller/previous page

I'm trying to forward a servlet response to the same page from when it came from (aka: the previous page, or the "servlet" caller).我正在尝试将 servlet 响应转发到它来自时的同一页面(又名:上一页,或“servlet”调用者)。

I've seen many answers (like this and this ) but still can't make it work.我已经看到了很多答案(例如thisthis ),但仍然无法使其发挥作用。

I usually do the following to redirect the response of a servlet to another page:我通常执行以下操作来将 servlet 的响应重定向到另一个页面:

request.getRequestDispatcher("MyNewPage").forward(request, response);

But I've tried to change "MyNewPage" for other options I've seen as solutions as:但是我尝试将“MyNewPage”更改为我认为作为解决方案的其他选项:

request.getRequestDispatcher((String)request.getAttribute("javax.servlet.forward.request_uri")).forward(request, response);
request.getRequestDispatcher(request.getHeader("referer")).forward(request, response);

and other options and can't make it work.和其他选项,不能让它工作。

What am I doing wrong?我究竟做错了什么?

First of all the request.getHeader("referer") returns a full URL but you have to strip off the http://server[:port]/ because what you pass to request.getRequestDispatcher() is added to the application context like this:首先request.getHeader("referer")返回一个完整的 URL,但你必须去掉http://server[:port]/因为你传递给 request.getRequestDispatcher() 的内容被添加到应用程序上下文中,比如这个:

/NameOfApp/http:/localhost:8084/NameOfApp/test.jsp

Which is not what you want because you just need to pass the following to the dispatcher method:这不是您想要的,因为您只需要将以下内容传递给调度程序方法:

test.jsp

If we take things from the start the first request starts from this URL:如果我们从头开始,第一个请求就从这个 URL 开始:

http://localhost:8084/RequestDispatcher/test.jsp

The forward works but the second time you are going make a request to your Servlet, the Servlet will forward to itself.转发有效,但是当您第二次向 Servlet 发出请求时,Servlet 将转发给自己。 So you will enter a loop with the Servlet calling itself.因此,您将进入一个循环,其中 Servlet 调用自身。 Why will this happen?为什么会发生这种情况? Since you call the Servlet from the form, this means that the URL address in your browser address box will change to that of your Servlet after the first request.由于您从表单中调用 Servlet,这意味着您的浏览器地址框中的 URL 地址将在第一次请求后更改为您的 Servlet 的地址。

http://localhost:8084/RequestDispatcher/NewServlet

The Servlet will forward the request back to the JSP page and the browser will display just that but the URL in the browser address box will still be the one containing the Servlet and not the JSP page: Servlet 会将请求转发回 JSP 页面,浏览器将仅显示该请求,但浏览器地址框中的 URL 仍将是包含 Servlet 而不是 JSP 页面的 URL:

http://localhost:8084/RequestDispatcher/NewServlet

So the next time you hit submit the Servlet will try to forward the request to itself.因此,下次您点击提交时,Servlet 将尝试将请求转发给它自己。 If I were you I would use a redirect.如果我是你,我会使用重定向。 It seems more appropriate for your purpose:它似乎更适合您的目的:

response.sendRedirect(request.getHeader("referer"));

This will always change the URL in your browser address box and prevent your Servlet from looping.这将始终更改浏览器地址框中的 URL 并防止 Servlet 循环。 This will have an impact on the request parameters but you can always add them on the redirect URL(if it's not sensitive information) or store them in session until you retrieve them on the next first request which will be made by the redirect.这将对请求参数产生影响,但您始终可以将它们添加到重定向 URL(如果它不是敏感信息)或将它们存储在会话中,直到您在重定向将发出的下一个第一个请求中检索它们。

A framework like JSF would save you from these issues.像 JSF 这样的框架可以帮助您避免这些问题。

The easiest solution that would allow you to use forward, is a hidden parameter in the form keeping the JSP(viewid) that called the Servlet instead of using the request.getHeader("referer").允许您使用 forward 的最简单的解决方案是保留调用 Servlet 的 JSP(viewid) 的表单中的隐藏参数,而不是使用 request.getHeader("referer")。 You will need to check for loops though, because someone could deliberately change the value to force your Servlet container to loop and eventually crash the VM.不过,您需要检查循环,因为有人可能会故意更改该值以强制您的 Servlet 容器循环并最终使 VM 崩溃。 But you can just use a request attribute to keep record of the previous request in the chain and if it's the same you respond with an error.但是您可以只使用请求属性来记录链中的前一个请求,如果相同,则以错误响应。 So in the servlet you would use the hidden field value in order to decide where to forward to:因此,在 servlet 中,您将使用隐藏字段值来决定转发到的位置:

request.getRequestDispatcher(request.getParameter("viewid")).forward(request, response);

and in your JSP:在您的 JSP 中:

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

I think this would cover your requirements.我认为这将满足您的要求。

Better strategy would be to add the caller attribute in the request.更好的策略是在请求中添加调用者属性。 So that after processing the callee servlet can forward its request back to the caller.这样在处理完被调用者 servlet 后,它就可以将其请求转发回调用者。

Something like,就像是,

Caller呼叫者

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

Callee被调用者

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

OR you can try adding the caller in the session and remove it after forwarding.或者您可以尝试在会话中添加呼叫者并在转发后将其删除。

I had the same problem and my solution was:我有同样的问题,我的解决方案是:

 String[] url = request.getHeader("referer").split("/"); response.sendRedirect(url[url.length-1]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM