Just throw in another option. You can also use Sub-resource locators, which give us some control over the chosen resource (and is part of the JAX-RS spec). For example
@Path("contacts")
public class ContactsResource {
@Path("/")
public AbstractHeaderResource doSomething(@HeaderParam("X-Header") String xHeader) {
if ("RequiredValue".equals(xHeader)) {
return new WithHeaderResource();
}
return new WithOutHeaderResource();
}
public static abstract class AbstractHeaderResource {
@POST
@Consumes(MediaType.APPLICATION_JSON)
public abstract Response doSometing(Contact contact);
}
public static class WithHeaderResource extends AbstractHeaderResource {
@Override
public Response doSometing(Contact contact) {
return Response.ok("*** With Header ***").build();
}
}
public static class WithOutHeaderResource extends AbstractHeaderResource {
@Override
public Response doSometing(Contact contact) {
return Response.ok("*** WithOut Header ***").build();
}
}
}
Test
C:\>curl -v -X POST
-d "{\"name\":\"Peeskillet\"}"
-H "X-Header:RequiredValue"
-H "Content-Type:application/json"
http://localhost:8080/contacts
*** With Header ****
C:\>curl -v -X POST
-d "{\"name\":\"Peeskillet\"}"
-H "Content-Type:application/json"
http://localhost:8080/contacts
*** WithOut Header ****
The resource methods don't have to accept the same parameter type. I did it just for brevity. You can have the sub resource classes extend an empty abstract class or interface (just for typing), and create the methods however you want
UPDATE
If you need some objects injected into the sub resource, you can also return the sub resource class from the locator method or you can inject ResourceContext
into the main resource class and use that to create the sub resource instance and return that instance from the locator method. Both ways will support container injection as the container will create the instance instead of you just instantiating it.