Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Application developers can define resources and the HTTP methods to manipulate them very quickly by using regular plain old Java objects and JAX-RS annotations.

Define a Root Resource (@Path on Java class)

Developers can use POJOs to define a resource. Root resources have a @Path annotation at the class declaration level. JAX-RS matches an incoming request's URL with the @Path annotation on all of an application's root resources to determine which initial Java class will handle the request.

To create Java methods that will be invoked with specific HTTP methods, implement a regular Java method and annotate it with one of the JAX-RS @HttpMethod annotated annotations (namely, @GET, @POST, @PUT, and @DELETE).

...

Any incoming GET request that has the URL of "/welcome" would be handled by WelcomeMessage class's returnWelcomeMessage() method. A string is returned which represents the response body. To return more complex response entities, see the Request/Response entities page.

HTTP Methods (@GET, @POST, @PUT, @DELETE)

There are well-defined HTTP methods that can be issued. The 4 most common are GET, POST, PUT, and DELETE.

...

Notice that the updateWelcomeMessage has an unannotated parameter which represents an incoming request's body. See the Request/Response entities page for more details on how request/response entities are handled.

Subresource Methods (@Path and @GET, @POST, @PUT, @DELETE on Java method)

Sometimes it is easier having a root resource resolve a generic URL path and to have @Path annotated methods further resolve the request. For instance, suppose that a HTTP GET to "/administrator" returned generic information about an administrator. However, sometimes it is better to return smaller bits or more detailed information about the resource using a slightly different URL identifier. Suppose that a HTTP GET to "/administrator/name" should return the name. Instead of creating many root resource classes for each URL, you can have the root resource initially resolve the beginning of the URL request and then further resolve the request against subresource methods.

Subresource methods are Java methods with a @Path annotation and a @HttpMethod annotated annotation (@GET, @POST, @PUT, @DELETE).

Code Block
titleAdministratorResourceWithSubresourceMethod
borderStylesolid

@Path("/administrator")
public class Administrator{

    @GET
    public String findUserInfo() {
        String userInfo = null;
        /* build user info */
        return userInfo;
    }

    @GET
    @Path("/name")
    public String getJustUserName() {
        String userName = "";
        /* get the user name */
        return userName;
    }

    @GET
    @Path("/id")
    public String getUserId() {
        String userId = "";
        /* get the user id */
        return userId;
    }
}

A HTTP URL request to "/administrator" would resolve to Administrator#findUserInfo(). A HTTP URL request to "/administrator/name" would invoke the Administrator#getJustUserName() method. Finally a HTTP URL request to "/administrator/id" would resolve to Administrator#getUserId().

Subresource Locators (@Path on Java method)

In more complicated scenarios, subresource locators are needed. Subresource locators are particularly useful when requests must be further resolved by other objects.

Subresource locators are Java methods which have only an @Path annotation. They are different than subresource methods because they do not have any HTTP method annotation on them.

A subresource locator returns an object that has JAX-RS annotations on its methods (or inherits them). The object is used to further resolve the incoming requests by dynamically inspecting the object for JAX-RS annotations.

This scenario uses @PathParams which are discussed on the parameters page.

Code Block
titleUsersResourcesWithSubresourceLocators
borderStylesolid

@Path("/users")
public class UsersCollection {

    @Path("{userid}")
    public Object findUserInfo(@PathParam("userid") String userId) {
        if(userId.equals("superuser")) {
            return new SuperUser();
        }
        return User.findUserInDatabase(userId);
    }
}

public class Superuser { 
    @GET
    public String getUserInfo() {
       String userInfo = /* get the user info */;
       return userInfo;
    }

    @GET
    @Path("/contactinfo")
    public String getContactInfo() {
      String contactInfo = /* get the user contact info */;
      return contactInfo;
    }
}

public class User {
    protected String name;

    protected User() {
        /* subresource locator object lifecycles are controlled by the developer */
    }

    public static User findUserInDatabase(String userName) {
        User u = /* get user from database with assigned field values */
        return u;
    }

    @GET
    public String getInfo() {
        String info = /* get the user info */;
        return info;
    }

    @GET
    @Path("/name")
    public String getMyUserName() {
        return name;
    }
}

A HTTP GET to "/users/superuser" would result in User#findUserInfo() being invoked first. The method inspects the "userId" path parameter (which resolves to "superuser" for this request) so a Superuser object is returned. The request is then further resolved against the Superuser object. In the simple "/users/superuser" case, the request invokes Superuser#getUserInfo();

If a HTTP GET to "/users/superuser/contactinfo" was made, then User#findUserInfo() is invoked and again returns a Superuser object. The Superuser object is then used to resolve the "/contactinfo" portion of the request which invokes Superuser#getContactInfo.

If a HTTP GET to "/users/user1/name" was made, then User#findUserInfo() is again invoked but it would go and look up the user from the database and return a User object. The User object is then used to resolve the "/name" portion and results in the User#getMyUserName() method being invoked on the User object returned.