Inheritance with JAX-RS

17,593

What you've described above looks good. Here are the rules for JAX-RS inheritance which based on what you've provided you are adhering.

From JAX-RS spec §3.6:

JAX-RS annotations MAY be used on the methods and method parameters of a super-class or an implemented interface. Such annotations are inherited by a corresponding sub-class or implementation class method provided that method and its parameters do not have any JAX-RS annotations of its own. Annotations on a super-class take precedence over those on an implemented interface. If a subclass or implementation method has any JAX-RS annotations then all of the annotations on the super class or interface method are ignored. E.g.:

public interface ReadOnlyAtomFeed {
    @GET @Produces("application/atom+xml")
    Feed getFeed();
}

@Path("feed")
public class ActivityLog implements ReadOnlyAtomFeed {
    public Feed getFeed() {...}
}

In the above, ActivityLog.getFeed inherits the @GET and @Produces annotations from the interface. Conversely:

@Path("feed")
public class ActivityLog implements ReadOnlyAtomFeed {
    @Produces("application/atom+xml")
    public Feed getFeed() {...}
}

In the above, the @GET annotation on ReadOnlyAtomFeed.getFeed is not inherited by ActivityLog .getFeed

Share:
17,593
user489041
Author by

user489041

Updated on July 21, 2022

Comments

  • user489041
    user489041 almost 2 years

    I am using JAX-RS for my web services. I have common functionality and would like to use inheritance. I am providing simple CRUD operations. I have defined an interface like so:

    public interface ICRUD {
    
        @POST
        @Consumes("application/json")
        @Produces("application/json")
        @Path("create")
        public String createREST(String transferObject);
    
        @GET
        @Consumes("application/json")
        @Produces("application/json")
        @Path("retrieve/{id}")
        public String retrieveREST(@PathParam("id") String id);
    
        @POST
        @Consumes("application/json")
        @Produces("application/json")
        @Path("update")
        public void updateREST(@Suspended final AsyncResponse asyncResponse,
                               final String transferObject) ;
    
        @DELETE
        @Consumes("application/json")
        @Produces("application/json")
        @Path("delete/{id}")
        public String deleteREST(@PathParam("id") String id); 
    }
    

    I have an abstract class that implements this interface:

    public abstract class BaseREST implements ICRUD{
    
    private final ExecutorService executorService = Executors.newCachedThreadPool();
    
    @Override
    public String createREST(String transferObject) {
        return create(transferObject).toJson();
    }
    
    @Override
    public String retreiveREST(@PathParam("id") String id) {
        return retreive(id).toJson();
    }
    
    
    @Override
    public String deleteREST(
            @PathParam("id") String id) {
        return delete(id).toJson();
    }
    
    @Override
        public void updateREST(@Suspended final AsyncResponse asyncResponse, final String transferObject) {
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    asyncResponse.resume(doUpdateREST(transferObject));
                }
            });
        }      
    
    }
    

    And lastly, my implementing class simply provides a PATH for the resource:

    @Path("meeting")
    public class MeetingRestServices extends BaseREST {
    }
    

    When I try to access my resource at (assuming the context root is /):

    http://localhost:8080/webresources/meeting/retreive/0
    

    I get a 404, it says it can not find it. My thoughts are that somewhere in the inheritance, it is messing with the path of where I think the resource should be. Any thoughts on this?

    EDIT

    webresources is defined below. This class is added automatically by Netbeans.

    @javax.ws.rs.ApplicationPath("webresources")
    public class ApplicationConfig extends Application {
    
        @Override
        public Set<Class<?>> getClasses() {
            Set<Class<?>> resources = new java.util.HashSet<>();
            addRestResourceClasses(resources);
            return resources;
        }
    
        /**
         * Do not modify addRestResourceClasses() method.
         * It is automatically populated with
         * all resources defined in the project.
         * If required, comment out calling this method in getClasses().
         */
        private void addRestResourceClasses(Set<Class<?>> resources) {
            resources.add(com.dv.meetmefor.ws.impl.BinaryDataRestService.class);
            resources.add(com.dv.meetmefor.ws.impl.ImageRestServices.class);
            resources.add(com.dv.meetmefor.ws.impl.LocaleRestService.class);
            resources.add(com.dv.meetmefor.ws.impl.MeetUpRestServices.class);
            resources.add(com.dv.meetmefor.ws.impl.MeetingRestServices.class);
            resources.add(com.dv.meetmefor.ws.impl.UserAccountRestServices.class);
        }
    
    }