MicroProfile REST Client外部Jar中过滤器未激活问题求助
在WildFly 25.0.1.Final中全局注册外部Jar里的MicroProfile REST Client认证过滤器
下面提供三种可行方案,帮你避免在每个WAR项目中重复配置过滤器:
方案一:将过滤器Jar封装为WildFly模块并全局注册
适合需要多个WAR共享过滤器,且希望统一控制的场景:
- 构建WildFly模块结构
在WildFly安装目录下,创建路径modules/system/layers/base/com/yourcompany/auth/main(替换com/yourcompany/auth为你的过滤器包路径),把过滤器Jar放入该目录,同时创建module.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <module name="com.yourcompany.auth" xmlns="urn:jboss:module:1.9"> <resources> <resource-root path="auth-filter.jar"/> <!-- 替换为你的过滤器Jar文件名 --> </resources> <dependencies> <module name="javax.ws.rs.api"/> <module name="org.eclipse.microprofile.rest.client"/> <module name="javax.annotation.api"/> </dependencies> </module>- 构建WildFly模块结构
- 全局注册JAX-RS提供者
修改WildFly的standalone/configuration/standalone.xml(集群环境用domain.xml),找到jaxrs子系统,在providers节点下添加过滤器的全类名:
<subsystem xmlns="urn:jboss:domain:jaxrs:1.0"> <providers> <provider>com.yourcompany.auth.AuthFilter</provider> <!-- 替换为你的过滤器全类名 --> </providers> <!-- 保留原有其他配置 --> </subsystem>- 全局注册JAX-RS提供者
- WAR项目中引入模块依赖
在每个WAR的WEB-INF/jboss-deployment-structure.xml中添加模块依赖:
<?xml version="1.0" encoding="UTF-8"?> <jboss-deployment-structure> <deployment> <dependencies> <module name="com.yourcompany.auth" export="true"/> </dependencies> </deployment> </jboss-deployment-structure>配置完成后,所有通过
@RestClient注入的客户端都会自动应用这个认证过滤器。- WAR项目中引入模块依赖
方案二:通过MicroProfile全局配置实现
无需修改WildFly全局配置,仅通过项目配置实现共享:
- 给过滤器添加
@Provider注解
在外部Jar的AuthFilter类上添加注解,标记为JAX-RS提供者:
@Provider @Priority(Priorities.AUTHENTICATION) // 可选,控制过滤器执行优先级 public class AuthFilter implements ClientRequestFilter { @Override public void filter(ClientRequestContext requestContext) throws IOException { // 这里写你的基础认证逻辑,比如添加Authorization头 String auth = "Basic " + Base64.getEncoder().encodeToString("user:pass".getBytes()); requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, auth); } }- 给过滤器添加
- WAR项目引入过滤器Jar依赖
在WAR的Maven pom.xml中添加依赖(Gradle项目对应调整):
<dependency> <groupId>com.yourcompany</groupId> <artifactId>auth-filter</artifactId> <version>1.0.0</version> <scope>provided</scope> <!-- 如果是WildFly模块用provided,否则用compile --> </dependency>- WAR项目引入过滤器Jar依赖
- 全局注册过滤器到MicroProfile REST Client
在WAR的META-INF/microprofile-config.properties中添加配置,让所有REST Client自动使用该过滤器:
org.eclipse.microprofile.rest.client.providers=com.yourcompany.auth.AuthFilter这个配置会覆盖单个客户端的
@RegisterProvider,确保所有@RestClient注入的实例都应用该过滤器。- 全局注册过滤器到MicroProfile REST Client
方案三:通过CDI扩展自动注册过滤器
适合需要动态控制过滤器注册逻辑的场景:
- 在过滤器Jar中编写CDI扩展类
这个扩展会自动给所有标记@RestClient的接口添加过滤器:
public class RestClientFilterExtension implements Extension { public void processRestClientTypes(@Observes ProcessAnnotatedType<?> pat) { AnnotatedType<?> type = pat.getAnnotatedType(); if (type.isAnnotationPresent(RestClient.class)) { // 包装原有类型,添加@RegisterProvider注解 pat.setAnnotatedType(new AnnotatedTypeWrapper<>(type, AuthFilter.class)); } } private static class AnnotatedTypeWrapper<T> implements AnnotatedType<T> { private final AnnotatedType<T> delegate; private final Class<?> filterClass; public AnnotatedTypeWrapper(AnnotatedType<T> delegate, Class<?> filterClass) { this.delegate = delegate; this.filterClass = filterClass; } @Override public Type getBaseType() { return delegate.getBaseType(); } @Override public Set<Type> getTypeClosure() { return delegate.getTypeClosure(); } @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) { if (annotationType == RegisterProvider.class) { return (A) new RegisterProvider() { @Override public Class<?> value() { return filterClass; } @Override public int priority() { return Priorities.AUTHENTICATION; } @Override public Class<? extends Annotation> annotationType() { return RegisterProvider.class; } }; } return delegate.getAnnotation(annotationType); } @Override public Set<Annotation> getAnnotations() { Set<Annotation> annos = new HashSet<>(delegate.getAnnotations()); annos.add(getAnnotation(RegisterProvider.class)); return annos; } @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) { return delegate.isAnnotationPresent(annotationType) || annotationType == RegisterProvider.class; } // 以下方法直接委托给原有AnnotatedType实现 @Override public AnnotatedConstructor<T> getConstructor(Constructor<T> c) { return delegate.getConstructor(c); } @Override public Set<AnnotatedConstructor<T>> getConstructors() { return delegate.getConstructors(); } @Override public AnnotatedMethod<T> getMethod(Method m) { return delegate.getMethod(m); } @Override public Set<AnnotatedMethod<T>> getMethods() { return delegate.getMethods(); } @Override public AnnotatedField<? super T> getField(Field f) { return delegate.getField(f); } @Override public Set<AnnotatedField<? super T>> getFields() { return delegate.getFields(); } } }- 在过滤器Jar中编写CDI扩展类
- 注册CDI扩展
在过滤器Jar的META-INF/services/javax.enterprise.inject.spi.Extension文件中添加扩展类的全类名:
com.yourcompany.auth.RestClientFilterExtension- 注册CDI扩展
- WAR项目引入过滤器Jar
同样在pom.xml添加依赖,后续所有@RestClient注解的接口都会自动带上该过滤器,无需手动添加@RegisterProvider。
- WAR项目引入过滤器Jar
内容的提问来源于stack exchange,提问作者grigouille
相关产品推荐
相关产品推荐

