java - 在 Jersey 1.18.1 请求过滤器中获取资源注释

标签 java rest annotations jersey dropwizard

我正在实现一个用户授权模块,该模块将使用(新)注释应用于资源方法。
为此,我创建了一个 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());

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

最佳答案

您可以实现 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());

关于java - 在 Jersey 1.18.1 请求过滤器中获取资源注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30673667/

相关文章:

java - 来自 json 字符串的 PHP REST API 类生成器

java - Cassandra 中的 IN 关系对查询不利吗?

java - 是否可以从非所有者的 Android 设备上读取记录?

java - Java中有没有一种方法可以使按钮默认在点击时获得焦点

.net - RESTful服务特定场景的最佳实践

mysql - 如何创建具有 OnetoMany 和 ManytoOne 关系的实体?

java - 如何将curl调用转换为java HttpPost : curl --form "archive=@test.pdf;type=application/pdf"

java - SmartGWT RestDateSource 和分页(大数据集)动态数据

android - 如何在 Eclipse 中获取支持注解?

java - 为什么 Spring 的 @Configurable 有时有效,有时无效?