我不明白为什么这个方法以以下方式实现:
/**
* Creates a {@code uri} tag based on the URI of the given {@code exchange}. Uses the
* {@link HandlerMapping#BEST_MATCHING_PATTERN_ATTRIBUTE} best matching pattern if
* available. Falling back to {@code REDIRECTION} for 3xx responses, {@code NOT_FOUND}
* for 404 responses, {@code root} for requests with no path info, and {@code UNKNOWN}
* for all other requests.
* @param exchange the exchange
* @return the uri tag derived from the exchange
*/
public static Tag uri(ServerWebExchange exchange) {
PathPattern pathPattern = exchange.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
if (pathPattern != null) {
return Tag.of("uri", pathPattern.getPatternString());
}
HttpStatus status = exchange.getResponse().getStatusCode();
if (status != null) {
if (status.is3xxRedirection()) {
return URI_REDIRECTION;
}
if (status == HttpStatus.NOT_FOUND) {
return URI_NOT_FOUND;
}
}
String path = getPathInfo(exchange);
if (path.isEmpty()) {
return URI_ROOT;
}
return URI_UNKNOWN;
}
我觉得奇怪的是,他们使用exchange.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE)
,这导致我的许多请求返回null并默认为未知。但是,在检查交换机时,request.path
包含我想要使用的路径。
为什么不使用总是有值的request.path?
exchange.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE)
是如何工作的。我甚至不明白它是干什么的?
为什么我的一些请求为exchange.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE)
返回null,所有控制器都以相同的方式实现?
当收到请求时,它被映射到一个特定的处理程序,无论是@RequestMapping
方法、路由器函数还是其他什么。此映射过程包括根据路径模式进行匹配。与匹配的处理程序相关联的路径模式存储在交换机的BEST_MATCHING_PATTERN_ATTRIBUTE
中。
当为请求-响应交换创建标签时,BEST_MATCHING_PATTERN_ATTRIBUTE
用于防止uri
标签具有一组无限制的值。例如,如果URI为/users/123456
的请求已与模式/users/{id}
匹配,则BEST_MATCHING_PATTERN_ATTRIBUTE
的值将为/users/{id}
。如果使用了请求的路径,那么每个用户都会得到不同的uri
标记值。有了数百万用户,uri
标签最终会有数百万个值,这对监控系统是有害的。
即使没有数百万用户,攻击者也可能试图对监控系统进行拒绝服务攻击。通过用不同的id值向/users/{id}
发出数百万个请求,他们可以用数百万个uri
标签值淹没监控系统。
不幸的是,我不能确定为什么有些请求具有null
BEST_MATCHING_PATTERN_ATTRIBUTE
。可能是没有匹配的处理程序,并且响应将是404。你的问题的这个特定方面可能会在一个单独的问题中得到更好的解决,并附上一个例子。