Quarkus中FilterHTTP过滤器未按预期仅作用于指定接口问题
问题根源
你的FilterHTTP过滤器同时添加了@Provider和@PreMatching注解:
@Provider会让JAX-RS自动将它注册为全局容器请求过滤器,默认对所有请求生效,和@Interceptors的方法绑定逻辑完全无关;@PreMatching让过滤器在资源方法匹配之前执行,此时JAX-RS还未确定要调用哪个控制器方法,所以@Interceptors和@ExcludeDefaultInterceptors的配置根本无法生效。
解决方法(二选一,无需使用@Bindings)
方法1:移除全局注册,改为CDI拦截器绑定
将过滤器改为CDI拦截器,仅通过@Interceptors绑定到指定方法:
- 修改
FilterHTTP,移除@Provider和@PreMatching,实现CDI拦截器逻辑:
public class FilterHTTP { private static final Logger LOG = LoggerFactory.getLogger(FilterHTTP.class); @AroundInvoke public Object intercept(InvocationContext context) throws Exception { // 获取请求上下文(RESTEasy Reactive环境下通过CDI注入) ContainerRequestContext requestContext = CDI.current().select(ContainerRequestContext.class).get(); // 原有日志、参数处理逻辑 LOG.debug("Ingreso al metodo filter"); MultivaluedMap<String, String> headers = requestContext.getHeaders(); for( String headerName : headers.keySet()){ String headerValue = headers.getFirst(headerName); LOG.debug("HEADER - CLAVE : {} - VALOR : {}",headerName, headerValue); } UriInfo uriInfo = requestContext.getUriInfo(); MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters(); for (String paramName : queryParams.keySet()) { List<String> paramValues = queryParams.get(paramName); LOG.debug("QUERY PARAM : {}" , paramValues); } boolean valid = validateRequest(requestContext); if (!valid) { LOG.debug("Ingreso al metodo if del filter - BAD REQUEST"); Response response = Response.status(Response.Status.BAD_REQUEST).entity("Invalid request").build(); throw new WebApplicationException(response); } // 执行原控制器方法 return context.proceed(); } private boolean validateRequest(ContainerRequestContext requestContext) { return true; } }
- 保留控制器
hello()方法上的@Interceptors(FilterHTTP.class),此时只有调用该方法时才会触发拦截逻辑,getAllAccounts()不受影响。
方法2:保留容器过滤器,内部判断请求路径
如果不想修改过滤器类型,可在filter方法开头增加路径判断,仅处理目标请求:
修改FilterHTTP的filter方法:
@Override public void filter(ContainerRequestContext requestContext) throws IOException { // 仅匹配hello方法的请求路径 UriInfo uriInfo = requestContext.getUriInfo(); String requestPath = uriInfo.getPath(); if (!"/accounts/retrieve/hello".equals(requestPath)) { // 非目标请求,直接跳过过滤逻辑 return; } // 原有日志、参数处理、验证逻辑 LOG.debug("Ingreso al metodo filter"); MultivaluedMap<String, String> headers = requestContext.getHeaders(); for( String headerName : headers.keySet()){ String headerValue = headers.getFirst(headerName); LOG.debug("HEADER - CLAVE : {} - VALOR : {}",headerName, headerValue); } MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters(); for (String paramName : queryParams.keySet()) { List<String> paramValues = queryParams.get(paramName); LOG.debug("QUERY PARAM : {}" , paramValues); } boolean valid = validateRequest(requestContext); if (!valid) { LOG.debug("Ingreso al metodo if del filter - BAD REQUEST"); Response response = Response.status(Response.Status.BAD_REQUEST).entity("Invalid request").build(); requestContext.abortWith(response); } }
这种方式下,过滤器仍为全局注册,但只有请求路径匹配hello()方法时才会执行过滤逻辑。
内容的提问来源于stack exchange,提问作者BRUNO
相关产品推荐
相关产品推荐

