当响应实体是字符串

时间:2017-05-18 15:48:50

标签: java jboss wildfly resteasy undertow

我需要在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。

我不知道我做错了什么,或者这是否是一个可能出现的反复出现的错误,或者是野生动物......

0 个答案:

没有答案