3

I am writing some code to figure out metadata about classes implemented with JAX-RS and I'm writing a method that takes a Method and returns the HTTP Verb related to that method, basically figure out if it's annotated with @POST, @GET, @PUT or @DELETE.

What I currently have is this:

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";
    }
}

It works fine, but I figured out that all those annotations are annotated with @HttpMethod and have a value with it's name as a String. Example:

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

So I was wondering. Is there a way for me to figure out from my reference of Method if it's annotated by an annotation which in turn is annotated with another specific annotation?

Something like:

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

PS: I know that method doesn't exist, it's just to illustrate what I'm looking for.

Rodrigo Sasaki
  • 7,048
  • 4
  • 34
  • 49

1 Answers1

2

Annotations are represented by Classes, just like any other objects. And just like Methods, Classes can be reflected on to check for annotations. For example

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

To put it all together into one method, you could do something like the following, which still requires you to traverse all the annotations on the method

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);

If what you were trying to do was clean up your method, you could do something like

public static String extractHttpVerb(Method method) {
    for (Annotation annotation: method.getAnnotations()) {
        if (annotation.annotationType().isAnnotationPresent(HttpMethod.class)) {
            return annotation.annotationType().getSimpleName();
        }
    }
    return null;
}
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720