Jersey 2.25中@NameBinding过滤器未触发子资源方法问题
解决Jersey 2.25中@NameBinding过滤器在子资源方法不触发的问题
这个问题我之前也碰到过,本质是Jersey对子资源的处理特性导致的:当主资源方法返回子资源实例时,子资源的方法并不会自动继承主资源类上的@NameBinding注解。你的AuthorizationFilter是通过@Secured绑定的,只有直接标注了@Secured的资源类/方法才会触发这个过滤器,而子资源的getSubDetails()方法(或其所在类)并没有被@Secured标注,所以过滤器自然不会生效。
下面给你几个可行的解决方案,按推荐程度排序:
方案1:直接在子资源类/方法上添加@Secured注解
这是最直接、最符合@NameBinding设计初衷的方式,把@Secured注解加到子资源的类或者具体方法上,让过滤器明确绑定到子资源的方法上。
比如你的子资源类可以改成这样:
// 给子资源类加@Secured,所有方法都会触发过滤器 @Secured public class SubResource { @GET @Path("sub-details") public Response getSubDetails() { // 你的业务逻辑 return Response.ok("sub details").build(); } }
或者只给特定的子资源方法加注解:
public class SubResource { @Secured // 仅这个方法触发过滤器 @GET @Path("sub-details") public Response getSubDetails() { // 你的业务逻辑 return Response.ok("sub details").build(); } }
方案2:用DynamicFeature动态绑定过滤器到子资源
如果你的子资源数量很多,不想一个个手动加注解,可以用DynamicFeature来自动检测主资源的@Secured注解,然后给所有子资源方法绑定过滤器。
先写一个DynamicFeature的实现类:
@Provider public class SecuredDynamicFeature implements DynamicFeature { @Override public void configure(ResourceInfo resourceInfo, FeatureContext context) { Class<?> currentResourceClass = resourceInfo.getResourceClass(); Method currentMethod = resourceInfo.getResourceMethod(); // 先检查当前方法或类本身有没有@Secured boolean isSecured = currentResourceClass.isAnnotationPresent(Secured.class) || currentMethod.isAnnotationPresent(Secured.class); // 如果没有,检查它的父资源链(也就是主资源)有没有@Secured if (!isSecured) { // 用Jersey的ExtendedResourceInfo获取父资源信息(2.25版本可用) ExtendedResourceInfo extendedInfo = (ExtendedResourceInfo) resourceInfo; Resource parentResource = extendedInfo.getResource().getParent(); while (parentResource != null) { if (parentResource.getResourceClass().isAnnotationPresent(Secured.class)) { isSecured = true; break; } parentResource = parentResource.getParent(); } } // 如果判定需要拦截,就注册过滤器 if (isSecured) { context.register(AuthorizationFilter.class); } } }
把这个类标注为@Provider,Jersey启动时会自动扫描到它,然后动态给符合条件的子资源方法绑定过滤器。
额外检查点
最后再确认一下几个容易忽略的点:
- 你的
AuthorizationFilter已经正确标注了@Provider、@Secured和@Priority(Priorities.AUTHORIZATION),这部分你已经做对了。 - 确保Jersey的包扫描配置包含了过滤器和子资源所在的包,不然过滤器或子资源可能没被注册。
内容的提问来源于stack exchange,提问作者Kevin Day
相关产品推荐
相关产品推荐

