【问题标题】:Using Spring, Tomcat, and Java, how do I redirect a request with HTTP headers?使用 Spring、Tomcat 和 Java,如何使用 HTTP 标头重定向请求?
【发布时间】:2014-09-09 17:12:43
【问题描述】:

所以我有一个 org.springframework.stereotype.Controller,如果指定了 HTTP 标头 HA 和 HB,我想做的是正常处理请求。但是,如果请求指定了查询参数 QA 和 QB,我想重定向请求而不使用 QA 或 QB,但使用 HTTP 标头 HA 和 HB,这样 HA 的值为 QA,HB 的值为 QB。

例如,如果传入请求是带有 HTTP 标头 x-name=foo 和 x-date=bar 的 HTTP GET ~/rest/mortgage,我会按原样处理该请求。但是如果传入的请求是 HTTP GET ~/rest/mortgage?x-name=foo&x-date=bar,我想用请求 HTTP GET ~/rest 重定向到我自己em>/mortgage 带有 HTTP 标头 x-name=foo 和 x-date=bar。

通过这样做,我只需在控制器级别添加一个简单的检查,就可以拥有一个处理两种发出 HTTP 请求的样式的代码路径。这是因为我将 HttpServletRequest 传递给代码的各个部分,所以如果我始终保持 HA 和 HB 而不是 QA 和 QB 的一致性,它会降低代码的圈复杂度。

这可能吗?如果是这样,怎么办?

如果这是不可能的,我可以通过为 HttpServletRequest 定义自己的包装器来实现我想要的结果,该包装器为我完成转换,但这不是一个优雅的解决方案。

【问题讨论】:

  • 这听起来更像是 ServletFilter 应该处理的事情。
  • 这个可能的解决方案缺少的是如何添加 HA 和 HB(在转换后的请求中添加 HTTP 标头)。该解决方案为以其他方式转换请求提供了明显的答案。
  • 好的,你需要把两个想法结合在一起。我在下面发布了一个暂定答案,请检查它是否有效。

标签: java spring spring-mvc tomcat


【解决方案1】:

如果要拦截 HTTP 请求,则需要使用 Servlet Filter

为了替换 URL,您必须将新 URL 替换为 get the Dispatcher,然后使用 forward() 方法再次发送请求。

类似这样的:

servletRequest.getRequestDispatcher(modifiedURL)
              .forward(servletRequest, servletResponse);

但是,您不能明确地修改 HTTP 标头。解决这个问题的方法是通过扩展HttpServletRequestWrapper 来包装请求并拥有一个处理此问题的代理对象。它已经实现了HttpServletRequest,因此无论您在与原始 servlet 请求交互时使用它都不会有任何问题。

您可以简单地扩展它并添加您自己的方法,例如addHeader(),并保留一个内部Map 或您正在添加的额外人工标头。然后,您只需覆盖 getHeaderNames()getHeader() 即可将原始标题与您自己的额外标题结合起来。

您需要做的最后一件事是将原始servletRequest 包装在过滤器中的新wrappedServletRequest 中。所以像这样(WrappedServletRequest 是您扩展 HttpServletRequestWrapper 的新实现):

WrappedServletRequest wrappedServletRequest = 
                                     new WrappedServletRequest(servletRequest);
wrappedServletRequest.addHeader("yourHeader", "yourValue");

wrappedServletRequest.getRequestDispatcher(modifiedURL)
              .forward(wrappedServletRequest, servletResponse);

请记住将您的过滤器的<filter><filter-mapping> 添加到您的web.xml 中以使其正常工作。

您可能想查看this article 了解更多详情。它有更多信息说明为什么必须这样做。

我自己没有尝试过,所以请在下方评论并确认您是否设法让它工作。

【讨论】:

    猜你喜欢
    • 2015-11-09
    • 2014-04-21
    • 2014-08-30
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-29
    • 2010-10-14
    相关资源
    最近更新 更多