获取ContainerRequestFilter中的资源类注释值 [英] Get resource class annotation values inside ContainerRequestFilter

查看:120
本文介绍了获取ContainerRequestFilter中的资源类注释值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力了解休息拦截器注释如何添加稍后在过滤器中可见的不同值。鉴于下面的代码,我希望在过滤器中,权限值将包含foo和bar,但它们是空的。任何帮助将不胜感激。

I'm struggling a bit with understanding how rest interceptor annotations can add different values that are later visible in the filter. Given the code below I would expect that once in the filter the permissions values would have foo and bar in them, however they are empty. Any help would be greatly appreciated.

注释

package edu.psu.swe.fortress.poc.interceptor;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.enterprise.util.Nonbinding;
import javax.ws.rs.NameBinding;

@NameBinding
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(value=RetentionPolicy.RUNTIME)
public @interface FortressProtected
{
  @Nonbinding String[] permissions() default {};
}

过滤器

package edu.psu.swe.fortress.poc.interceptor;

import java.io.IOException;
import java.lang.annotation.Annotation;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.ext.Provider;

@Provider
@FortressProtected
public class FortressAuthorizer implements ContainerRequestFilter
{

  @Override
  public void filter(ContainerRequestContext requestContext) throws     IOException
  {
    System.out.println("In the interceptor");
    Class<?> clazz = this.getClass();
    FortressProtected annotation = clazz.getAnnotation(edu.psu.swe.fortress.poc.interceptor.FortressProtected.class);

    System.out.println("Annotation? " + clazz.isAnnotation());

    for (Annotation a : clazz.getAnnotations())
    {
      System.out.println(a);
    }

    for (String s : annotation.permissions())
    {
      System.out.println(s);
    }
  }
}

App config

App config

package edu.psu.swe.fortress.poc.rest;

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

import edu.psu.swe.fortress.poc.interceptor.FortressAuthorizer;
import edu.psu.swe.fortress.poc.interceptor.FortressProtected;

@ApplicationPath("")
public class FortressTestApp extends Application
{
  private Set<Class<?>> clazzez_ = new HashSet<>();
  {
    clazzez_.add(ResourceImpl.class);
    clazzez_.add(FortressProtected.class);
    clazzez_.add(FortressAuthorizer.class);
  }
  public Set<Class<?>> getClasses()
  {
    return clazzez_;
  }
}

资源等级

package edu.psu.swe.fortress.poc.rest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import edu.psu.swe.fortress.poc.interceptor.FortressProtected;

@FortressProtected(permissions={"foo", "bar"})
@Path("tests")
public class ResourceImpl
{
  @GET
  @Produces("application/text")
  public String getHello()
  {
    FortressProtected annotation = this.getClass().getAnnotation(edu.psu.swe.fortress.poc.interceptor.FortressProtected.class);

    System.out.println(annotation.toString());

    return "hello";
  }
}

日志输出如下:


15:59:55,223 INFO [stdout](默认任务-9)@ edu.psu.swe.fortress.poc.interceptor.FortressProtected(permissions = [] )
15:59:55,229 INFO [stdout](默认任务-9)@ edu.psu.swe.fortress.poc.interceptor.FortressProtected(permissions = [foo,bar])

15:59:55,223 INFO [stdout] (default task-9) @edu.psu.swe.fortress.poc.interceptor.FortressProtected(permissions=[]) 15:59:55,229 INFO [stdout] (default task-9) @edu.psu.swe.fortress.poc.interceptor.FortressProtected(permissions=[foo, bar])

提前致谢。

推荐答案

在你的过滤器

Class<?> clazz = this.getClass();
FortressProtected annotation = clazz.getAnnotation(FortressProtected.class);

this.getClass()对应于过滤器类(其注释具有无值)。您需要在 ResourceImpl上获取注释

this.getClass() corresponds to the filter class (whose annotation has no values). You instead need to get the annotation on the ResourceImpl

两个选项。您可以显式使用 ResourceImpl.class.getAnnotation(...)。但问题是,一旦绑定了多个类,如何匹配哪个类对应于哪个请求。因此,下一个选项更可行。

A couple options. You could explicitly use ResourceImpl.class.getAnnotation(...). But the problem with this is that once you bind more than one class, how do you match which class corresponds to which request. For that reason, the next option is more viable.

你做的是注入 ResourceInfo中 。有了这个,你可以调用它的 getResourceMethod getResourceClass 方法。这些方法分别返回匹配的方法和类。然后,您可以在类级别以及方法级别检查注释(因为我们也允许在方法级别绑定)。所以你可能会有类似的东西:

What you do is inject ResourceInfo. With this, you can call it's getResourceMethod or getResourceClass methods. These methods return the matched method and class, respectively. You could then check for the annotation at the class level as well as the method level (as we are also allowed to bind at the method level). So you might have something more like:

@Provider
@FortressProtected
public class FortressAuthorizer implements ContainerRequestFilter {

  @Context
  ResourceInfo resourceInfo;

  @Override
  public void filter(ContainerRequestContext requestContext) throws IOException {

    Class<?> resourceClass = resourceInfo.getResourceClass();
    FortressProtected classAnnot = resourceClass.getAnnotation(FortressProtected.class);
    if (classAnnot != null) {
      // do something with annotation
    }

    Method resourceMethod = resourceInfo.getResourceMethod();
    FortressProtected methodAnnot = resourceMethod.getAnnotation(FortressProtected.class);
    if (methodAnnot != null) {
      // do something with annotation
    }
  }
}

这篇关于获取ContainerRequestFilter中的资源类注释值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆