【问题标题】:Getting resource annotations in Jersey 1.18.1 request filter在 Jersey 1.18.1 请求过滤器中获取资源注释
【发布时间】:2015-06-14 06:44:44
【问题描述】:

我正在实现一个用户授权模块,该模块将使用(新)注释应用于资源方法。
为了做到这一点,我创建了一个 Jersey(请求)过滤器,我需要在其中获取注释以允许/禁止资源操作。

我将 Dropwizard 0.7.1 与 Jersey 1.18.1 一起使用

资源类:

@Path("/v1/users/registration")
@Produces(MediaType.APPLICATION_JSON)
@Api(value = "/users/registration")
public class UserRegistrationResource {
    @POST
    @AuthorizedFor(Realm.SOCIAL) // The custom annotation class
    public SessionModel register(
            @Valid
            @ApiParam(value = "New user to be registered", required = true)
            NewUser user) throws Exception {

        // Some logic
    ...
    }
}

过滤器类:

@Provider
public class AuthorizationFilter implements ContainerRequestFilter {

    @Context
    AbstractMethod method;

    @Override
    public ContainerRequest filter(ContainerRequest request) {

    // At this point, the method parameter is null :(

    Realm realm = null;
        User user = Context.get(Session.class).getUser();
        for (Annotation annotation : method.getAnnotations()) {
            if (AuthorizedFor.class == annotation.annotationType()) {
                realm = ((AuthorizedFor) annotation).value();
            }
        }
        if (realm != null) {
            for (Realm userRealm : user.getRole().getAllowedRealms()) {
                if (userRealm.equals(realm)) {
                    return request;
                }
            }
        }
        throw new ApiException(ResponseCode.UNAUTHORIZED);
    }
}

提供者类:

@Provider
public class AbstractMethodProvider extends AbstractHttpContextInjectable<AbstractMethod> implements InjectableProvider<Context, Parameter> {

    @Override
    public Injectable<AbstractMethod> getInjectable(ComponentContext ic, Context context, Parameter parameter) {
        if (parameter.getParameterType() == AbstractMethod.class) {
            return this;
        }
        return null;
    }

    @Override
    public ComponentScope getScope() {
        return ComponentScope.PerRequest;
    }

    @Override
    public AbstractMethod getValue(HttpContext context) {
        return context.getUriInfo().getMatchedMethod();
    }
}

过滤器和提供者初始化代码:

environment.jersey().getResourceConfig().getContainerRequestFilters().add(new AuthorizationFilter());
environment.jersey().register(new AbstractMethodProvider());

我也尝试在过滤器中注入 HttpContext。它不为空,但 getUriInfo().getMatchedMethod() 为空。
有没有更好的方法在 Jersey 请求过滤器中获取资源方法注释?

【问题讨论】:

    标签: java rest annotations jersey dropwizard


    【解决方案1】:

    您可以实现 ResourceFilterFactory 来获取 AbstractMethod。

    public class AuthorizationFilterFactory implements ResourceFilterFactory {
    
        @Override
        public List<ResourceFilter> create(AbstractMethod abstractMethod) {
            return Arrays.asList(this.createAuthorizationFilter(abstractMethod));
        }
    
        private ResourceFilter createAuthorizationFilter(final AbstractMethod abstractMethod) {
            return new ResourceFilter() {
                @Override
                public ContainerRequestFilter getRequestFilter() {
                    return new AuthorizationFilter(abstractMethod);
                }
    
                @Override
                public ContainerResponseFilter getResponseFilter() {
                    return null;
                }
            };
        }
    }
    

    因此,您的 AuthorizationFilter 将如下所示:

    @Provider
    public class AuthorizationFilter implements ContainerRequestFilter {
    
        private final AbstractMethod method;
    
        public AuthorizationFilter(AbstractMethod method) {
            this.method = method;
        }
    
        @Override
        public ContainerRequest filter(ContainerRequest request) {
            Realm realm = null;
            User user = Context.get(Session.class).getUser();
            for (Annotation annotation : method.getAnnotations()) {
                if (AuthorizedFor.class == annotation.annotationType()) {
                    realm = ((AuthorizedFor) annotation).value();
                }
            }
            if (realm != null) {
                for (Realm userRealm : user.getRole().getAllowedRealms()) {
                    if (userRealm.equals(realm)) {
                        return request;
                    }
                }
            }
            throw new ApiException(ResponseCode.UNAUTHORIZED);
        }
    }
    

    注册你的工厂:

    environment.jersey().getResourceConfig().getResourceFilterFactories().add(new AuthorizationFilterFactory());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-23
      • 2015-06-20
      • 2015-06-18
      • 2015-07-11
      • 1970-01-01
      • 2015-05-17
      • 2014-09-19
      相关资源
      最近更新 更多