A RESTful web service is useful for applications which do not require the use of transactions, security and other features that can adversely impact its performance. JAX-RS supports the creation of RESTful applications. These types of services are typified through the use of HTTP commands such as GET and POST. In this recipe, we will use annotations that identify methods of a service corresponding to these commands.
The two basic steps involved in creating a JAX-RS web service include:
We will reuse the CustomerManager
class as described in the first recipe to provide our service's functionality.
The focus of this recipe is how to create the Web Service. To create a web service endpoint we need to:
We will create our JAX-RS web service by adding two classes to the jaxrs
package. The classes will use the two CustomerManager
methods. Start by creating a stateless session EJB called Customer
in the jaxrs
package.
Sometime during the process of creating the Customer
using NetBeans, you may be prompted with the following dialog box. When encountered, select the first option and proceed. In other development environments you may have to take different steps. The ApplicationConfig
class created here is detailed in a later section of this recipe.
In this version of the Customer
class, we will provide a simple method which responds to an HTTP GET request and returns an HTML string containing the number of customers returned by the CustomerManager's getCustomerCount
method.
Annotate the class with an @Path annotation as shown below. Inject an instance of the CustomerManager class as an instance variable and add a method called doGet
which uses this class. Annotate the method with a @GET and @Produces annotation.
@Path("customer") @Stateless public class Customer { @EJB private CustomerManager customerManager; @GET @Produces("text/html") public String doGet() { return "<h3>Customer Count: " + customerManager.getCustomerCount() + "</h3>"; } }
To test the service after it has been deployed, use the following URL in a browser: http://localhost:8080/CustomerApplication/resources/customer. The "resources" part of the URL will be explained shortly. The browser output should appear as shown in the following screenshot:
From this example, you can see how easy it is to respond to a user's request. When the use of an EJB is needed to support this type of interaction, JAX-RS provides a good solution.
The @Path annotation was used to designate the class as a web service endpoint. Its value, the string, "customer" was used as part of the path used to access this web page. This was reflected in the URL.
A JAX-RS application responds to standard HTTP commands such as GET and POST. To respond to a GET request, we added the doGet
method. The @GET annotation specified the method as the one to execute when the HTTP GET command arrived. The @Produces annotation means the data returned by the method is HTML. The body of the method returned a simple HTML string reflecting the return value of the getCustomerCount
method.
Notice in the URL the use of the string resources. JAX-RS uses an Application
derived class in support of applications. How this works is detailed next. In addition, we will look into the use of the GET command in more depth and also see how to use HTML FORM data.
As we saw earlier, NetBeans generated an ApplicationConfig
class which extends the javax.ws.rs.core.Application
class. The purpose of the class is to manage all of the resources used by the application. The ApplicationConfig
class provided by NetBeans provides default support for all the basic operations.
The ApplicationConfig
class is shown below and is annotated with the @ApplicationPath annotation. It is found under the Generated Sources (rest) folder of the application. The string used specifies the root name of the application as we saw reflected in the URL.
package org.netbeans.rest.application.config;
/**
* This class is generated by the Netbeans IDE,
* and registers all REST root resources created in the project.
* Please, DO NOT EDIT this class !
*/
@javax.ws.rs.ApplicationPath("resources")
public class ApplicationConfig extends javax.ws.rs.core.Application { }
The getCustomerCountByRegion
method is passed a string representing the region of interest. So how do we handle requests when parameters need to be passed? The answer involves using the @QueryParam and @DefaultValue annotations. The @QueryParam annotation associates the name of an HTML parameter with a parameter of the method responding to the GET command. The @DefaultValue annotation specifies a default value for the parameter.
Add a new stateless EJB called CustomerByRegion
to the jaxrs
package. Inject an instance of the CustomerManager
class.
@Path("customerByRegion") JAX-RS web serviceCustomerManager class@Stateless public class CustomerByRegion { @EJB private CustomerManager customerManager; ... }
Add a doGet
method using the @GET and @Produces annotations as we did with the Customer
class. However, use the following parameter list and inside of the method use the getCustomerCountByRegion
method.
@GET @Produces("text/html") public String doGet( @DefaultValue("East") @QueryParam("region") String region) { return "<h3>Customer Count: " + customerManager.getCustomerCountByRegion(region) + "</h3>"; }
The @QueryParam annotation associates the HTML parameter "region" with the methods parameter region
. A default value of "East" is also assigned using the @DefaultValue annotation.
To test the method, use the following URL. Notice the use of the name as specified by the @Path annotation. The question mark is used to indicate that a parameter is being passed. In this case, the parameter is region and is assigned a value of West.
http://localhost:8080/CustomerApplication/resources/customerByRegion?region=West
Your output should appear as shown in the following screenshot:
The POST command is an alternative to the GET command and is also used to send information to the server. The GET command encodes form data into the URL while the POST command places data within the HTTP message body. The POST command can also be used to retrieve information passed as part of an HTML FORM tag.
To illustrate the use of this command, create an index.html
file as shown below. This file contains a FORM tag with an input
element allowing the user to enter a region name. The FORM tag has two fields of interest. The first is the action
field. This specifies the URL to use when the user presses the submit button. In this case it specifies the Customer
class we developed at the beginning of this recipe. The second field is the method field. This specifies the HTTP command to use. Here we specify the use of the POST command.
<html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <form action="/CustomerApplication/resources/customer" method="post" > Region<input name="region" value="East"><br> <input type="submit"> </form> </body> </html>
However, in order to use the POST command we need to add a supporting method to the Customer
class. Add a doPost
method to the jaxr's Customer
class as shown below. In this simple method, we return the number of customers based on the region.
@POST @Produces("text/html") @Consumes("application/x-www-form-urlencoded") public String doPost(@FormParam("region") String region) { return "<h3>Customer Count: " + customerManager.getCustomerCountByRegion(region) + "</h3>"; }
This method uses the @Produces annotation as we had used earlier. It also uses a @Consumes annotation which determines the type of input accepted by the method. In this case we use "application/x-www-form-urlencoded". This means the method accepts data encoded by an HTML FORM. The server will generate an exception if the wrong type of data is sent.
The @FormParam annotation associates the FORM's
region parameter with the method's region
parameter. The region
parameter is used as an argument of the getCustomerCountByRegion
method.
Use the URL http://localhost:8080/CustomerApplication/index.html to test the application. The following screenshot shows the expected output:
Selecting the Submit button should result in output as shown in the following screenshot:
3.15.220.16