Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find a list of all Jersey resource methods in my app?

Does Jersey provide any way to list all of the resources it exposes? That is, given the resource class:

package com.zoo.resource

@Path("/animals")
public class AnimalResource {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("dog")
    public Dog getDog(){
    ...
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("cat")
    public Cat getCat(){
    ...
    }
}

Does Jersey provide any way for me to get the information:

  • GET at the path /animals/dog returns type Dog
  • GET at the path /animals/cat returns type Cat

(And furthermore, does it provide a way for me to know that AnimalResource is a resource?)

I would like to have this information available to me in a unit test so that I can check that every resource I expose conforms to what an external system expects. I know that there is automagic that exposes the application.wadl, but I don't see that showing me return types and I don't know how to access it from within my tests.

like image 883
PotataChipz Avatar asked Nov 21 '12 00:11

PotataChipz


1 Answers

[update - example is the same but I have reworded my caveats]

It can be done. Try the following:

import com.sun.jersey.api.model.AbstractResource;
import com.sun.jersey.api.model.AbstractSubResourceMethod;
import com.sun.jersey.server.impl.modelapi.annotation.IntrospectionModeller;

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

public class AnimalsTest
{
   public static void main(String [] args)
   {
      AbstractResource resource = IntrospectionModeller.createResource(AnimalResource.class);
      System.out.println("Path is " + resource.getPath().getValue());

      String uriPrefix = resource.getPath().getValue();
      for (AbstractSubResourceMethod srm :resource.getSubResourceMethods())
      {
         String uri = uriPrefix + "/" + srm.getPath().getValue();
         System.out.println(srm.getHttpMethod() + " at the path " + uri + " return " + srm.getReturnType().getName());
      }
   }
}

class Dog {}

class Cat {}

@Path("/animals")
class AnimalResource {
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("dog")
    public Dog getDog(){
      return null;
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("cat")
    public Cat getCat(){
       return null;
    }
}

These introspection classes are in jersey-server.

Note that the example above uses some Jersey classes that have "impl" in the package name which suggests that these Jersey classes are not intended for public consumption and may very well have breaking changes in the future. I am just speculating here - I am not a Jersey committer. Just a random user.

Also everything above I figured out by perusing the source code. I have never seen any documentation of an approved way to introspect JAX-RS annotated classes. I agree that an officially supported API to do this kind of thing would be very helpful.

like image 157
Guido Simone Avatar answered Nov 13 '22 05:11

Guido Simone