通过反射识别 JAX-RS 上的 HTTP 动词

Identify HTTP Verb on JAX-RS via Reflection

我正在编写一些代码来找出关于 类 的元数据,这些元数据是通过 JAX-RS 实现的,并且我正在编写一个采用 Method 和 returns HTTP 的方法与那个方法相关的动词,基本上搞清楚是用@POST@GET@PUT还是@DELETE.

注解

我目前拥有的是:

private static String extractHttpVerb(Method method) {
    if(method.getAnnotation(GET.class) != null) {
        return "GET";
    } else if (method.getAnnotation(POST.class) != null) {
        return "POST";
    } else if (method.getAnnotation(PUT.class) != null) {
        return "PUT";
    } else if (method.getAnnotation(DELETE.class) != null){
        return "DELETE";
    } else {
        return "UNKNOWN";
    }
}

它工作正常,但我发现所有这些注释都用 @HttpMethod 注释并且有一个 value 其名称为字符串。示例:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@HttpMethod("POST")
@Documented
public @interface POST {
}

所以我想知道。有没有办法让我从我对 Method 的引用中找出它是否由一个注释注释,而该注释又由另一个特定注释注释?

类似于:

boolean annotated = method.hasAnnotationsAnnotatedBy(HttpMethod.class);

PS: 我知道那个方法不存在,它只是为了说明我在找什么。

Annotations 由 Classes 表示,就像任何其他对象一样。就像 Methods 一样,Classes 可以反映出来以检查注释。例如

 Annotation anno = method.getAnnotation(...);
 Class<? extends Annotation> cls = anno.annotationType();
 boolean annotHasAnnotation = cls.isAnnotationPresent(...);

把它们放在一个方法中,你可以像下面那样做,这仍然需要你遍历方法上的所有注释

public static boolean hasSuperAnnotation(Method method, Class<? extends Annotation> check) {
    for (Annotation annotation: method.getAnnotations()) {
        if (annotation.annotationType().isAnnotationPresent(check)) {
            return true;
        }
    }
    return false;
}

[...]
boolean hasHttpMethod = hasSuperAnnotation(method, HttpMethod.class);

如果你想做的是清理你的方法,你可以做类似的事情

public static String extractHttpVerb(Method method) {
    for (Annotation annotation: method.getAnnotations()) {
        if (annotation.annotationType().isAnnotationPresent(HttpMethod.class)) {
            return annotation.annotationType().getSimpleName();
        }
    }
    return null;
}