Creating an EJB-based web service using JAX-RS

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.

Getting ready

The two basic steps involved in creating a JAX-RS web service include:

  1. Creating an EJB which provides the application's functionality
  2. Creating a Web Service (JAX-RS) which utilizes the EJB

    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:

  1. Use the @Path annotation to designate a class as an endpoint
  2. Annotate the methods of the service with one of several annotations depending on the service provided by the method
  3. Use a supporting EJB to implement the desired functionality of the service

How to do it...

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.

How to do it...

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:

How to do it...

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.

How it works...

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.

There's more...

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.

Understanding the Application class

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 {
}

Using the GET command with parameters

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:

Using the GET command with parameters

Using the POST command with form data

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:

Using the POST command with form data

Selecting the Submit button should result in output as shown in the following screenshot:

Using the POST command with form data
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.220.16