[英]Using sendRedirect inside a servlet forwarded with request dispatcher
I have a filter that implements a custom convention for loading servlets and JSPs. 我有一个过滤器,该过滤器实现了用于加载servlet和JSP的自定义约定。 In that convention I am using the following code to include the servlet:
按照该约定,我使用以下代码包括servlet:
servletContext
.getRequestDispatcher( uriDispatcherLocator.getServletLocation( uri ) )
.include( request, response );
and the following code to include the JSP (in the same filter): 和以下代码以包含JSP(在同一过滤器中):
servletContext
.getRequestDispatcher( "/index.jsp" )
.include( request, response );
Everything works fine, the servlet executes, then it includes the JSP and some irrelevant custom rules take place. 一切正常,servlet执行,然后包括JSP,并发生了一些不相关的自定义规则。 As you can see, at the very moment I include a servlet with request dispatcher I cannot send an http header response to the client .
如您所见,此刻我在请求分配器中包含一个servlet,但我无法将HTTP标头响应发送到client 。 The problem is that I want the servlet to have full control of the response as if it was called from inside the filter (because the filter will do nothing else than dinamically mapping the servlets according to their respective Class/JSP location in the project file system).
问题是我希望Servlet能够完全控制响应,就好像从过滤器内部调用了该响应一样(因为该过滤器除了根据项目文件系统中各自的Class / JSP位置动态映射Servlet之外,不会做其他任何事情。 )。 I can use
.forward()
instead of .include()
, but if I do I will not be able to include a JSP after the servlet has been executed. 我可以使用
.forward()
而不是.include()
,但是如果执行了该操作,则在执行servlet之后将无法包含JSP。
So, how would I allow the servlet to execute the code below when being included through a filter via RequestDispatcher interface? 因此,当通过RequestDispatcher接口通过过滤器将其包含在其中时,如何允许servlet执行以下代码?
response.sendRedirect( "/somePath" );
No Javascript hacks, I am willing to send the proper HTTP response from the server to make the browser behave correctly. 没有Java技巧,我愿意从服务器发送正确的HTTP响应,以使浏览器正常运行。
-- -
EDIT: In other words: 编辑:换句话说:
I want to change the headers sent to the client from INSIDE an included servlet by using RequestDispatcher, but the docs states: 我想使用RequestDispatcher更改从INSIDE包含的servlet发送到客户端的标头,但是文档指出:
The included servlet cannot change the response status code or set headers; any attempt to make a change is ignored.
Your Filter includes your servlet 您的过滤器包括您的servlet
servletContext
.getRequestDispatcher( uriDispatcherLocator.getServletLocation( uri ) )
.include( request, response );
Your Servlet indicates it wants to redirect 您的Servlet表示它想要重定向
request.setAttribute ("sendRedirect", "/some/path");
or, wishes to add one or more response headers 或者,希望添加一个或多个响应头
Map<String, String> respHeaders = new HashMap<String, String>();
respHeaders.put("Expires", "0");
respHeaders.put("Cache-Control", "no-cache");
request.setAttribute("respHeaders", respHeaders);
Your Filter checks for these special requests 您的过滤器会检查这些特殊要求
Map<String, String> respHeaders =
(Map<String, String>) request.getAttribute("respHeaders");
for (String key : respHeaders.keySet()) {
response.setHeader(key, respHeaders.get(key)); // set response headers
}
String sendRedirect;
if ((sendRedirect = (String) request.getAttribute("sendRedirect")) != null) {
response.sendRedirect(sendRedirect); // redirect the client
}
EDIT : Perhaps some of your servlets are already driving the flow and setting response headers when called from outside an include. 编辑 :当您从include外部调用时,也许您的某些servlet已经在驱动流程并设置响应标头。 But, there's no way to reuse them as is.
但是,无法按原样重用它们。 You can't simply include them and expect the same behaviour because the goal of a RequestDispatcher#include() is to provide for server-side includes (SSI) only.
您不能简单地包含它们并期望相同的行为,因为RequestDispatcher#include()的目标是仅提供服务器端包含(SSI)。
Hence, we do not find any overloaded methods (or any setters that could modify this behaviour) in the API. 因此,我们在API中找不到任何重载的方法(或任何可以修改此行为的设置方法)。 If you want to include such servlets and retain their behaviour (like redirects) you would have to pass them a hint that they're running under an include context and so should submit their response requests.
如果要包括此类servlet并保留其行为(如重定向),则必须向它们传递一个提示,即它们正在include上下文中运行,因此应提交其响应请求。
request.setAttribute ("includeContext", true);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.