如何将新标头传递给 sendRedirect

Posted

技术标签:

【中文标题】如何将新标头传递给 sendRedirect【英文标题】:How to pass new header to sendRedirect 【发布时间】:2016-04-30 13:07:18 【问题描述】:

我觉得这应该很容易。我有一个应用程序,我想做的只是有一个表单页面(index.jsp),它调用一个servlet(CheckInfo.java),它设置一个新的标题(myHeader)并将用户重定向到另一个页面(redirect.jsp) .所有这些文件都在同一台服务器上。 index.jsp 正在发送请求,CheckInfo 正在处理和重定向,但 myHeader 没有显示在 redirect.jsp 上。我已经阅读了几篇关于 response.sendRedirect 发送不传递标头的 302 并且我应该使用 RequestDispatcher 的帖子,但似乎没有任何效果。有没有办法将标头从 servlet 发送到 jsp? 这是servlet代码:

response.setHeader("myHeader", "hey there");
response.sendRedirect("redirect.jsp");

我也试过这个:

response.setHeader("myHeader", "hey there");
RequestDispatcher view = request.getRequestDispatcher("redirect.jsp");
view.forward(request, response);

我在 redirect.jsp 中有这个:

System.out.println(request.getHeader("myHeader"));

这不会打印任何东西。

如果我的问题的答案是否定的......那么一旦我回到 jsp,我就会找到一种设置标题的方法。我的反向代理正在寻找特定的标头来确定是否执行操作。显然我在redirect.jsp上尝试了response.addHeader(),但是页面已经加载了,所以这让我觉得很愚蠢。

【问题讨论】:

【参考方案1】:
response.setHeader("myHeader", "hey there");
response.sendRedirect("redirect.jsp");

您将其添加为响应标头,它是 302 响应。浏览器在看到 302 响应时只会查找 Location 标头并向该位置发出新请求。响应中的自定义标头未受影响,而您希望这些自定义响应标头包含在未发送的请求中(到新的重定向位置)。

解决方案:- 1.您可以使用请求调度程序并转发请求而不是外部重定向。而且你需要在这里使用请求属性。 2.您可以使用 ajax 请求调用提交表单,可能类似于 jquery 并手动处理响应(对于 302 响应),但不建议您使用这种方法,因为它不是一种更清洁和直观的方法。只是提一下,以便您知道还有其他方法可以实现这一目标。

【讨论】:

我更新了我的问题以包括我为您的解决方案 1 尝试的内容。RequestDispatcher 也不起作用。 你需要使用请求属性。试试这个,让您知道您现在面临什么问题。 我不明白我应该如何使用请求属性。可以举个例子吗? 在调用请求调度程序转发之前使用 request.setAttribute('myHeader',String or object value) 。在您的 redirect.jsp 中,使用 request.getAttribute("myHeader") 。 type 将值转换为 String 或您使用的任何 Object 类型。【参考方案2】:

问题是响应的redirect() 方法完全发起了一个新请求,从而丢失了重定向之前设置的属性。幸运的是,仍然有一种流畅的方法可以解决这个问题。见下文

response.setHeader("myHeader", "hey there"); request.getRequestDispatcher("redirect.jsp").forward(request, response);

然后在你的目的地你可以做response.getHeaders("myHeader")

我已经测试了代码。

【讨论】:

【参考方案3】:

我希望在要求客户端重定向到另一个 URL 的情况下很清楚 - 浏览器不应接受 cookie。

但是,第二种方法 - 服务器转发请求是可行的。主要错误似乎是在我们应该更改请求时改变了response

再一次,不能直接改变 HttpServletRequest 对象。这是一种方法:

HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(request)
    public String getHeader(String name) 
        String value = super.getHeader(name);
        if(Strings.isNullOrEmpty(value)) 
            ...
            value = myNewHeader;
        
        return value;
    

    public Enumeration<String> getHeaders(String name) 
        List<String> values = Collections.list(super.getHeaders(name));
        if(values.size()==0) 
            ...
            values.add(myNewHeader);
        
        return Collections.enumeration(values);
    

    public Enumeration<String> getHeaderNames() 
        List<String> names = Collections.list(super.getHeaderNames());
        names.add(myNewHeaderName);
        ...
        return Collections.enumeration(names);
    

接着是:

RequestDispatcher view = request.getRequestDispatcher("redirect.jsp");
// OR (If you can get servletContext)
RequestDispatcher view = servletContext.getRequestDispatcher("redirect.jsp");

view.forward(requestWrapper, response);

参考:

https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequestWrapper.html 对于 headers 情况 - reqWrapper obj 中的 getHeader()、getHeaders() 和 getHeaderNames() fn 需要覆盖。 同样,您可以覆盖 cookie 和参数。 另见:Modify request parameter with servlet filter

注意:可能无法将请求转发到需要不同 MIME 类型的端点。

【讨论】:

【参考方案4】:

客户端重定向会创建一个新的 HTTP 请求/响应对。 此链接可能会在调试方面为您提供更多帮助 -

Sending Custom headers

【讨论】:

以上是关于如何将新标头传递给 sendRedirect的主要内容,如果未能解决你的问题,请参考以下文章

如何解决:上下文提供程序未将新的上下文值传递给子级

如何将参数和标头传递给 aiohttp ClientSession

如何将标头动态传递给 angularjs 的 $resource

如何将请求标头信息传递给 Angular6 应用程序(JWT 通过请求标头发送)

如何在 ASP .NET MVC 5 中使用 select2 将新值动态添加到列表框并将其传递给控制器​​?

如何将请求标头传递给 graphql 解析器