如何在从 servlet 过滤器执行 HTTP 重定向时保留请求正文

Posted

技术标签:

【中文标题】如何在从 servlet 过滤器执行 HTTP 重定向时保留请求正文【英文标题】:How to preserve request body on performing HTTP redirect from servlet filter 【发布时间】:2013-02-02 19:29:27 【问题描述】:

我有一个 Java Web 应用程序部署在 2 台主机上,前面有一个 servlet 过滤器。我向一台主机上的应用程序发送了一个 POST 请求,该请求被过滤器拦截并重定向到另一台主机:

public void doFilter (ServletRequest request, ServletResponse response,
       FilterChain filterChain)

    ...
    if(shouldRedirect) 
        httpResponse.sendRedirect(redirectLocation);
    

在第二台机器上,请求通过过滤器并由资源类中的 REST API 处理。

@POST
public Response handleRequest(InputStream stream)

    ...

stream 对象作为 POST 请求正文的一部分发送。重定向后,请求正文未发送过来,stream 为空。重定向后如何保留请求正文(或至少是其中的这一部分)?

谢谢。

【问题讨论】:

【参考方案1】:

我发现另一种可行的方法是 307(临时重定向)。这保留了原始请求的主体,因此它适用于这种情况。正如 here 所详述的那样,307 重定向具有一些安全隐患,但没有原始主机充当阻塞 HTTP 请求的代理的好处。

public void doFilter(...)

    ...
    httpResponse.setStatus(TEMPORARY_REDIRECT);
    httpResponse.setHeader("Location", redirectLocation);
    return;

【讨论】:

谢谢你,这真的像魅力一样解决了我的问题。 thx,这是一个很好的答案,符合我的要求,也有一些数据的正文【参考方案2】:

我会改为向redirectLocation 发帖。 sendRedirect 告诉客户端更改其位置,以便您在该点开始新的 HTTP 请求。

当您执行重定向时,您可以让客户端向新 URL 发起原始 POST 请求。

【讨论】:

【参考方案3】:

sendRedirect() 重新访问用户的浏览器,并从浏览器访问重定向的 url。

话虽如此,POST 数据仅在收到first request 的初始主机上可用。即在这种情况下过滤。

你可以做什么:

修改您的重定向网址以将 POST 数据包含为 Request Parameters in GET url

例如host2\servlet?param=one&param2=two

阅读更多关于URL Redirection

【讨论】:

以上是关于如何在从 servlet 过滤器执行 HTTP 重定向时保留请求正文的主要内容,如果未能解决你的问题,请参考以下文章

Servlet过滤器重定向:如何在chain.doFilter(request,resp)之后重定向;

如何在 java Servlet 过滤器中更改传入 URL 并将请求重定向到新 URL [重复]

Servlet过滤器登录重定向无限循环[重复]

我应该使用 servlet 还是过滤器来重定向 URL?

重定向是不是保证会延迟到所有 servlet 过滤器都已处理完毕?

Java Web 应用程序中的会话过期时如何重定向到登录页面?