我需要在underow过滤器中的请求中识别@PathParam以忽略它们(度量目的)。
我的过滤器如下所示:
public class MetricsHandler implements HttpHandler {
private HttpHandler next;
public MetricsHandler(HttpHandler next) {
this.next = next;
}
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
MetricsListener listener = new MetricsListener();
exchange.addExchangeCompleteListener(listener);
next.handleRequest(exchange);
}
private class MetricsListener implements ExchangeCompletionListener {
@Override
public void exchangeEvent(HttpServerExchange exchange, NextListener nextListener) {
try {
String metric = exchange.getRequestURI();
UriInfo uriInfo = ResteasyProviderFactory.getContextData(UriInfo.class);
/*
* When the response entity is a String, this UriInfo is null at this point. If it's another type, the UriInfo is ok and i'm able to identify path parameters ...
*/
if(uriInfo != null) {
Collection<List<String>> pathParametersValues = uriInfo.getPathParameters(false).values();
for (List<String> list : pathParametersValues) {
for (String pathParameter : list) {
metric = metric.replace("/"+pathParameter, "");
}
}
}
Metrics.increment(metric);
} finally {
if (nextListener != null) {
nextListener.proceed();
}
}
}
}
}
此过滤器打包为wildfly模块,并在underow子系统内的domain.xml(Wildfly 10.1.0)中进行配置,如下所示:
<subsystem xmlns="urn:jboss:domain:undertow:3.1">
<buffer-cache name="default"/>
<server name="default-server">
<host name="default-host" alias="localhost">
<filter-ref name="metricsFilter"/>
</host>
</server>
<servlet-container name="default">
<jsp-config/>
<websockets/>
</servlet-container>
<filters>
<filter class-name="com.metrics.filter.MetricsHandler" module="com.metrics" name="metricsFilter"/>
</filters>
</subsystem>
以下是我的REST方法:
@GET
@Path("/path/num/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response pathNum(@PathParam("id") String id) {
return Response.ok(123).build();
}
@GET
@Path("/path/string/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response pathString(@PathParam("id") String id) {
return Response.ok("abc").build();
}
我在请求pathNum方法时能够识别“id”路径参数,但我不是为了pathString方法。在评论中,调用ResteasyProviderFactory.getContextData(UriInfo.class)为pathString方法返回null。
我已经针对resteasy 3.0.19.Final,3.0.20.Final和3.0.22.Final测试了这种行为,都具有相同的结果。
调试resteasy我发现,当响应实体是Integer或其他类型时,MessageBodyWriter是ResteasyJackson2Provider(我的其余@Produces json),并且只有在我的过滤器的ExchangeCompletionListener.exchangeEvent之后才调用SynchronousDispatcher.clearContextData。
但是,当响应实体是String时,MessageBodyWriter是一个StringTextStar,并且在MessageBodyWriter和之前我的ExchangeCompletionListener之后调用clearContextData,因此不再需要查看contextData。
我不知道我做错了什么,或者这是否是一个可能出现的反复出现的错误,或者是野生动物......