当在两个Tomcat之间转发时,请求参数被复制

quhf5bfb  于 2021-10-10  发布在  Java
关注(0)|答案(1)|浏览(298)

我们有一个运行在tomcat 8.5.32上的控制器,它接收一个带有查询参数/{path_param}/issue?title=4&description=5的post请求,请求主体为空
然后控制器使用tomcat 9.0.27将此请求重定向到spring boot microservice。排队

CloseableHttpResponse result = httpClient.execute(request);
``` `request.getURI().getQuery()` 等于 `&title=1&description=2` 但是当它到达微服务时,参数是重复的(title=[4,4]&description=[5,5])。
这是将请求重定向到microservice的代码

private static <T, U> T executePostRequest(String url, U body, HttpServletRequest httpServletRequest, Function<String, T> readValueFunction) {

try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
    URIBuilder uriBuilder = new URIBuilder(url);
    httpServletRequest.getParameterMap().forEach((k, v) -> Arrays.stream(v).forEach(e -> uriBuilder.addParameter(k, e)));
    HttpPost request = new HttpPost(uriBuilder.build());

    CloseableHttpResponse result = httpClient.execute(request);
    String json = EntityUtils.toString(result.getEntity(), "UTF-8");

    handleResultStatus(result, json);

    return readValueFunction.apply(json);
} catch (IOException | URISyntaxException e) {
    ...
}

}

我发现jetty也有类似的问题,它已经被修复了,但没有发现任何与tomcat相关的东西——以及如何修复它。我也看到了这个主题,其中建议如何在spring boot中处理重复的参数,但我想知道是否还有其他人遇到过同样的问题,如果是的话,您是如何解决的。
8dtrkrch

8dtrkrch1#

这不是一个bug,而是每个servlet容器中的一个特性。
servlet api不要求请求参数具有唯一的名称。如果你发一封信 POST 请求 http://example.com/app/issue?title=1&description=2 包括:

title=3&description=4

然后每个参数将有多个值: title 会有价值 13 虽然 description 会有价值 24 按此顺序:
来自查询字符串和post正文的数据聚合到请求参数集中。查询字符串数据显示在post正文数据之前。例如,如果请求的查询字符串为a=hello,帖子正文为a=bye&a=world,则生成的参数集的顺序为a=(hello,bye,world)。
(servlet规范,第3.1节)
如果只想复制参数的第一个值,请使用:

httpServletRequest.getParameterMap()//
                  .forEach((k, v) -> uriBuilder.addParameter(k, v[0]));

相关问题