How To Get Resource Method Information With ResourceInfo In Jakarta REST

Jakarta EE

Oftentimes in a Jakarta REST application, you may need to access some metadata about a given resource method matched by the Jakarta REST runtime, outside of a resource class. This could be so as to dynamically alter the client’s request based on some custom business requirement, or for informative purposes. For example, in a Jakarta REST component like an exception mapper, you might want to get the currently matched resource method and get its HTTP method. 

The Jakarta REST API has the ResourceInfo interface for just such a situation. This interface is a container managed component that you can inject into other Jakarta REST components with the jakarta.ws.rs.core.Context annotation. The interface has two methods, getResourceMethod and getResourceClass that return a java.lang.reflect.Method and Class<?>, respectively. 

With the getResourceMethod, you can get metadata about the currently matched resource method. It’s important to note that the methods on the ResourceInfo object can return null if they are invoked in a situation where the Jakarta REST runtime has not yet matched a given request to a resource method.

The code snippet below shows the use of the ResourceInfo in an exception mapper to get the matched HTTP method.

@Provider
public class ValidationExceptionMapper implements ExceptionMapper<ValidationException> {
    @Context
    UriInfo uriInfo;

    @Context
    ResourceInfo resourceInfo;

    @Override
    public Response toResponse(final ValidationException exception) {
        var httpMethods = List.of(POST.class, GET.class, PUT.class, DELETE.class, PATCH.class, OPTIONS.class, HEAD.class);

        Annotation[] declaredAnnotations = resourceInfo.getResourceMethod().getDeclaredAnnotations();

        String httpMethod = Arrays.stream(declaredAnnotations)
                .filter(d -> httpMethods.contains(d.annotationType())).findFirst()
                .map(a -> a.annotationType().getSimpleName()).orElse("");

        final var jsonObject = Json.createObjectBuilder()
                .add("host", uriInfo.getAbsolutePath().getHost())
                .add("resource", uriInfo.getAbsolutePath().getPath())
                .add("resourceMethod", httpMethod)
                .add("title", "Validation Errors");

        final var jsonArray = Json.createArrayBuilder();

        JsonObjectBuilder errorObject = Json.createObjectBuilder()
                .add("message", "A validation exception occurred")
                .add("reason", exception.getLocalizedMessage());
        jsonArray.add(errorObject);
        JsonObject errorJsonEntity = jsonObject.add("errors", jsonArray.build()).build();

        return Response.status(Response.Status.BAD_REQUEST).entity(errorJsonEntity).build();
    }
}

The ConstraintViolationExceptionMapper injects both the ResourceInfo and UriInfo components with the @Context annotation. The toResponse method gets the matched resource method, then gets an array of declared annotations with the getDeclaredAnnotations method. This array is then streamed and filtered for an annotation that matches one of any in the pre-declared list of annotations in the httpMethods list. Using this construct, rather than, for instance relying on the index of the methods in the array makes our code portable across vendors. It also ensures it works the same for future releases of the specification. 

The rest of the method creates JSON objects to return meaningful messages to the client. A typical call to a resource method in the application that triggers a ConstraintViolationException will resource in a JSON message such as shown below.

{
  "host": "localhost",
  "resource": "/jee-mongo/api/employee/HR-05",
  "resourceMethod": "POST",
  "title": "Validation Errors",
  "errors": [
    {
      "message": "A validation exception occurred",
      "reason": "No department found for department code HR-05"
    }
  ]
}

Notice the resourceMethod element. This is what we got from using the ResourceInfo object. Of course there are different scenarios where you will need to know the HTTP method, as stated above. But in all cases, the ResourceInfo is your go to object for getting such information. A small caveat, with the release of Jakarta EE 10, is that the @Context annotation will be deprecated and eventually removed in favor of the more ubiquitous Jakarta CDI @Inject. This is part of the long term goal of aligning the platform and making the CDI the core “glue” that binds all the various parts together. But until then, you can use the @Context annotation to get an instance of the ResourceInfo component in your Jakarta REST artefacts. 

Found this useful?

Try some of our Jakarta EE guides:

Comments (2)

Post a comment

Your email address will not be published. Required fields are marked *

Payara needs the contact information you provide to us to contact you about our products and services. You may unsubscribe from these communications at any time. For information on how to unsubscribe, as well as our privacy practices and commitment to protecting your privacy, please review our Legal & Privacy Policy.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  1. Markus Karg

    Beware of assumptions like “HTTP method type is always first”. There is no guarantee about that, as this is undocumented behavior and might not be the case if future or on different vendor’s JREs. In production code, typically you would no use out-of-band knowledge like this, but treat instead check if a known / expected annotation type is found on the method. For example, if you like to introduce a logging level as an annotation, you would ask for the *existence* of “@DebugLevel” instead of assuming it to be there in a particular index position.

    1. Luqman Luqman

      Hi. Yes thanks for the pointer. I looked into the spec but didn’t find it explicitly stated. Like you mentioned, it might result in unexpected behaviour even on the same runtime across different versions. I’ll amend the text accordingly. Thanks.

Related Posts

SpringBoot Actuator Health for Microprofile Developers 7 minutes
Cloud & Microservices

Spring Boot Actuator Health for MicroProfile Developers

If you worked with MicroProfile Health, you already understand the value of exposing application health information through standardized endpoints. […]

Webinar banner for “High-Frequency Trading on Jakarta EE: GC Stress Testing with Azul C4 and Payara Micro,” March 25, 2026, 2 PM GMT. Features Azul and Payara Micro logos and speaker photos of Luqman Saeed, Jakarta EE Specialist, and Simon Ritter, Deputy CTO and Java Champion. 1 minute
Cloud & Microservices

High-Frequency Trading on Jakarta EE: Join Our Upcoming Live Webinar

Modern high-frequency trading (HFT) platforms operate under extreme performance constraints, processing tens of thousands of messages per second while […]

Illustration promoting the Payara Platform Community Survey, featuring bold text on a blue background alongside a clipboard with a checklist, star ratings, and check marks, with coral and fish graphics in an underwater theme. 1 minute
Community

Help Shape the Future of Payara Platform Community – Take Our 2026 Survey

Earlier this week, we’ve launched the 2026 Payara Platform Community Survey and we’d love to hear from you. If […]