在RestController中处理之前,将RequestParams复制到RequestHeaders

时间:2017-07-07 13:05:33

标签: spring spring-boot interceptor

要替换遗留系统而不破坏界面,我正在寻找实现以下方案的方法:

如果REST客户端没有设置特定的HTTP标头(applicationId)但是将其作为查询参数(也称为RequestParameter)发送,则应将此值作为Spring Boot中的方法参数RestController。

目前的方法如下:

@RequestMapping(value = "/something", method = RequestMethod.GET)
    public void doSomething(@RequestHeader("applicationId") String applicationId) { }

我认为可能有两种可能的方式:

  1. 以某种方式注释方法 以将查询参数或标头映射到方法参数
  2. 编写Interceptor,其中读取请求的所有查询参数,并使用其值设置不存在的标头。这样,根本不需要触及该方法。
  3. 在这两种方式中,我都不确定如何实施它们(不知道 1。是否可行)。我尝试使用自己的HandlerInterceptor,它在preHandle中成功读取查询参数(但已成功),但在将请求转发到RestController之前无法在请求中设置标头。

1 个答案:

答案 0 :(得分:1)

使用Filter编写一个包含传入请求的HttpServletRequestWrapper。此包装器应覆盖getHeader方法。

public ParameterToHeaderWrappingRequestFilter extends OncePerRequestFilter {

    protected void doFilterInternal(
        HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {
        filterChain.doFilter(new ParameterToHeaderWrappingRequest(request), response, filterChain);
    }
}

在Spring Boot应用程序中将此过滤器注册为@Bean,它将自动应用。

public class ParameterToHeaderWrappingRequest extends HttpServletRequestWrapper {

    public String getHeader(String name) {
        String header = super.getHeader(name);
        if (header == null) {
            header = getParameter(name);
        }
        return header;
    }
}

这样的事情应该可以解决问题。根据您的需要,您可能希望/需要覆盖一些其他基于标头的方法,并且您可能希望限制要使用参数覆盖的标头数。

现在可以按原样编写其余代码。