CHAPTER 6

image

EJB and Web Services

This chapter will explain Web Services, introduce the core Web Services standards (SOAP, WSDL, UDDI, XML), and discuss the evolution of Web Services support in the Java EE platform. We will also drill down into how you can publish EJB stateless session beans as Web services. Finally, we will discuss how to invoke the published Web service from a command-line Java client program and a stateless session bean.

What Are Web Services?

Web services fundamentally constitute a kind of business logic or functionality available in an application or module and are exposed via a service interface to a client application (commonly known as service consumer). The consumer of the Web service doesn’t have to know any implementation details of the Web service—the client is able to access or invoke the Web service with the information provided in the service interface. This architecture fundamentally provides a loosely coupled model in which the consumer doesn’t have to be aware of technology or infrastructure details particular to the implementation of the business logic exposed as a Web service.

The Web Services Architecture Working Group of the W3C (World Wide Web Consortium) provides the following definition for a Web service:

A Web service is a software system designed to support interoperable machine-to-machine interaction over a network. It has an interface described in a machine-processable format (specifically WSDL). Other systems interact with the Web service in a manner prescribed by its description using SOAP messages, typically conveyed using HTTP with an XML serialization in conjunction with other Web-related standards.

While the concept of abstracting out details to an interface has been used in several languages and distributed architectures (for example, EJB and CORBA), the key difference in Web Services is the usage of standards to describe the abstraction, invocation, and registration of services.

Web Services architecture goes by the find-bind-execute model in which you find the required service in a registry (UDDI), get the description of the service, bind it to the service (create the message that will be sent to the service based on the description), and finally execute or invoke the service. Figure 6-1 shows the find-bind-execute model. UDDI, WSDL, and SOAP are the standards that make this find-bind-execute model ubiquitous and different from earlier computing models.

9781430246923_Fig06-01.jpg

Figure 6-1.  Web Services architecture

UDDI

Universal Description, Discovery, and Integration (UDDI) provides a standards-based approach to locating a Web service and information on invoking that service. It also provides additional metadata about the service. UDDI helps you dynamically bind Web services instead of having to hardwire them to an external interface, and it also helps to provide taxonomy. Businesses or service providers can provide basic contact information (including identification), categorization for the service, information that describes its behavior, and the actual location of the Web service.

UDDI, which is currently in version 3, has evolved over the last few years. Version 1 focused on providing a registry for services, while version 2 focused on aligning the specification with other Web services specifications and flexible taxonomies. The current version focuses on delivering support for secure interaction of private or public implementations of the services. Several companies, including Oracle, SAP, Microsoft, IBM, Cisco, Computer Associates, and Systinet are members of the UDDI technical committee for the Organization for the Advancement of Structured Information Standards (OASIS). Most of the application server vendors (such as Oracle and IBM) either provide a UDDI registry as a standard component that comes with their application server, or an OEM UDDI registry (from Systinet or other registry providers) as part of their middleware platform.

WSDL

Web Services Description Language (WSDL) is a technology that is used to describe the interface of a service using XML. WSDL is a standard developed by the W3C to which several vendors and individuals have contributed over the last few years. WSDL describes what a service does, how to invoke its operations, and where to find it.

WSDL details can be split into two categories: service interface definition details and service implementation definition details. The service interface definition is an abstract or reusable service definition that can be instantiated and referenced by multiple service implementation definitions. It contains the following WSDL elements, which comprise the reusable portion of the service description. We will use a credit check Web service as an example to introduce the service interface definition elements listed here:

<definitions>
<types>
<message>
<portType>
<binding>

The <definitions> Element

The <definitions> element allows you to specify global declarations of namespaces that are visible through the WSDL document. It acts as a container for service description. Listing 6-1 shows an example <definitions> element that defines a target namespace and other namespaces that are referred to by a credit service.

Listing 6-1.  The <definitions> Element in CreditService.wsdl

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions targetNamespace="http://www.apress.com/ejb3/credit"
name="CreditService" xmlns:tns="http://www.apress.com/ejb3/credit"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns=http://schemas.xmlsoap.org/wsdl//>

The <types> Element

The <types> element is used to define the data types for the <message> element. XML schema definitions (XSDs) are most commonly used to specify the data types. Listing 6-2 shows an example <types> element that provides the schema location for the credit service.

Listing 6-2.  The <types> Element in CreditService.wsdl

  <types>
    <xsd:schema>
<xsd:import namespace="http://www.apress.com/ejb3/credit"
    schemaLocation="CreditServiceBeanService_schema1.xsd"/>
    </xsd:schema>
  </types>

The <message> Element

The <message> element is used to define the format of data exchanged between a Web service consumer and a Web service provider. Listing 6-3 shows an example of two <message> elements: CreditCheck and CreditCheckResponse.

Listing 6-3.  The <message> Element in CreditService.wsdl

  <message name="CreditCheck">
    <part name="parameters" element="tns:CreditCheck"/>
  </message>
  <message name="CreditCheckResponse">
    <part name="parameters" element="tns:CreditCheckResponse"/>
  </message>

The <portType> Element

The <portType> element is used to specify the operations of the Web service. Listing 6-4 shows the <portType> element for the credit service with the CreditCheck operation.

Listing 6-4.  The <portType> Element in CreditService.wsdl

<portType name="CreditCheckEndpointBean">
  <operation name="CreditCheck">
    <input message="tns:CreditCheck"/>
    <output message="tns:CreditCheckResponse"/>
  </operation>
</portType>

The <binding> Element

The <binding> element describes the protocol, data format, and security for a <portType> element. The standard bindings are HTTP or SOAP; or you can create one of your own.

The “bindings” part of the WSDL specification is flexible—it allows you to provide your own bindings environment instead of the default SOAP-over-HTTP model. This flexibility of the specification has been widely exploited by WSIF (Web Services Invocation Framework), which is an Apache open source project. WSIF provides a nice way to expose existing Java, EJB, JMS (Java Message Service), and JCA-based components as Web services with native bindings, which provide better performance and that support native transactions. Listing 6-5 shows the <binding> element for the credit service, using SOAP-over-HTTP.

Listing 6-5.  The <binding> Element in CreditService.wsdl

  <binding name="CreditCheckEndpointBeanPortBinding"
type="tns:CreditCheckEndpointBean">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document"/>
    <operation name="CreditCheck">
      <soap:operation soapAction=""/>
      <input>
        <soap:body use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
      </output>
    </operation>
  </binding>

The service implementation definition part of the WSDL document identifies a Web service. It contains the following elements:

<service>
<port>

The <service> Element

The <service> element contains a collection of <port> elements where each port is associated with an endpoint (a network address location or URL). Listing 6-6 shows an example of a <service> element for the credit service.

Listing 6-6.  The <service> Element in CreditService.wsdl

  <service name="CreditService">
    <port name="CreditCheckEndpointBeanPort"
binding="tns:CreditCheckEndpointBeanPortBinding">
      <soap:address location="http://localhost:64082/CreditService/CreditCheckEndpointBean"/>
    </port>
  </service>

Listing 6-7 shows the complete WSDL document for the credit service that we are going to develop later in the chapter.

Listing 6-7.  The Complete WSDL Document for CreditService.wsdl

  <?xml version='1.0' encoding='UTF-8'?>
  <definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.apress.com/ejb/credit" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://www.apress.com/ejb/credit" name="CreditService">
    <types>
    <xsd:schema>
      <xsd:import namespace="http://www.apress.com/ejb3/credit"
        schemaLocation="CreditServiceBeanService_schema1.xsd"/>
    </xsd:schema>
    </types>
    <message name="CreditCheck">
      <part name="parameters" element="tns:CreditCheck"/>
    </message>
    <message name="CreditCheckResponse">
      <part name="parameters" element="tns:CreditCheckResponse"/>
    </message>
    <portType name="CreditCheckEndpointBean">
      <operation name="CreditCheck">
        <input message="tns:CreditCheck"/>
        <output message="tns:CreditCheckResponse"/>
      </operation>
    </portType>
    <binding name="CreditCheckEndpointBeanPortBinding" type="tns:CreditCheckEndpointBean">
      <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
      <operation name="CreditCheck">
        <soap:operation soapAction=""/>
        <input>
          <soap:body use="literal"/>
        </input>
        <output>
          <soap:body use="literal"/>
        </output>
      </operation>
    </binding>
    <service name="CreditService">
      <port name="CreditCheckEndpointBeanPort" binding="tns:CreditCheckEndpointBeanPortBinding">
        <soap:address location="http://localhost:64082/CreditService/CreditCheckEndpointBean"/>
      </port>
    </service>
  </definitions>

SOAP

Simple Object Access Protocol (SOAP) is an XML-based protocol used for exchanging information in a decentralized and distributed environment using XML. SOAP is a standard developed by the W3C. Fundamentally, SOAP is the default transport layer for the Web services.

A SOAP message is an ordinary XML document containing the following elements:

  • The required Envelope element identifies the XML document as a SOAP message. Envelope is the top-level element in the document. The envelope is required, and it basically marks the start and end of the SOAP message (although messages can contain links to objects outside the envelope). The envelope contains the Header and the Body elements.
  • The optional Header element contains header information. When the SOAP protocol is used over HTTP, the HTTP headers provide information about the content type, content length, and recipient of the message. A header is included to add features to a SOAP message without prior agreement between the communicating parties.
  • The required Body element contains call-and-response information. Body is a mandatory element that contains the information for the recipient of the message.
  • The optional Fault element provides information about errors that occur while the message is processed. The Body element can contain an optional Fault element to report errors.

Figure 6-2 illustrates the elements of a SOAP message.

9781430246923_Fig06-02.jpg

Figure 6-2.  A SOAP Message

REST

REST (REpresentational State Transfer) is a software architecture pattern that uses HTTP (Hyper Text Transfer Protocol) to discover, query, and manipulate resources in a decentralized and distributed environment. In recent times, REST has gained popularity compared to WSDL-SOAP-based implementation because of its simplicity.

Using REST, the client accesses a resource on the server, using the URI (Universal Resource Identifier) and the standard set of HTTP methods (GET, POST, PUT, and DELETE). In response, the server returns a representation of the resource, which is nothing but a document that contains the current or intended state of the resource. After each access invocation and a corresponding new resource representation response, the client is said to transfer state, hence the name Representational State Transfer. The REST architectural pattern mandates the following six constraints:

  1. Client–server Architecture: Clients and servers should be separate and can only interact via a uniform interface. This separation means that clients are not concerned with the data-storage internals of the server, and the server is not concerned with the user interface of the clients.
  2. Stateless Interaction: Clients and server can only interact using a stateless protocol like HTTP. A server cannot store a client context between requests. All requests must contain all of the information required for those requests.
  3. Cacheable: Server responses must identify themselves as cacheable or non-cacheable. This can be used to prevent clients from using stale data, and it can also help in improving the performance and scalability.
  4. Layered System: Clients should be able to connect to an intermediary system seamlessly rather than directly to the end server. Intermediary systems provide facilities like load balancing and shared caching that improve scalability of the system.
  5. Named Resources: Clients must be able to identify individual server resources in each request using URIs.
  6. Uniform Interface: A uniform interface between clients and servers allow them to evolve independently.

RESTful Web Services

RESTful Web services are services that are built based on the above-mentioned REST principles. RESTful Web services use HTTP and implement operations that map to common HTTP methods as shown in Table 6-1.

Table 6-1. HTTP Method to CRUD operation mapping

HTTP Method CRUD Operation
POST create
GET retrieve
PUT update
DELETE delete

Listing 6-8 shows a simple RESTful Web service named CreditCheck that takes a credit card number as an input and returns true or false based on its validity. For simplicity sake, our method always returns true.

Listing 6-8.  CreditCheck.java

package com.apress.ejb.chapter06.services;
import javax.ws.rs.Consumes;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

@Path("creditCheck")
public class CreditCheck {
    @PUT
    @Consumes("text/plain")
    @Produces("text/plain")
    @Path("isValid")
    public boolean isValid(@PathParam("cardNumber")String ccNumber) {
        return true;
    }
}

Users can invoke the isValid method in CreditCheck as follows, and ccNumber will be assigned the value 12345.

<host>:<port>/<resource>/creditCheck/isValid/12345">http://<host>:<port>/<resource>/creditCheck/isValid/12345

RESTful vs. SOAP-Based Web Services

Table 6-2 lists the important difference and similarities between RESTful Web service and SOAP-based Web service.

Table 6-2. RESTful vs. SOAP-Based Web Services

Criteria SOAP RESTful
Specification JAX-WS JAX-RS
Simple/Complex Complex Simple
Message Size Large (XML markup) Small (no extra XML markup)
Standards Based Yes No
Transport HTTP, SMTP, JMS HTTP
Caching No GET operations can be cached
Protocols JMS, SMTP, HTTP HTTP
Human Readable Payload No Yes
Language and Platform Independent Independent

When Do You Use Web Services?

Web Services provides a standard way to expose existing or new applications and data to external parties—including customers, suppliers, and partners—or across departments in an enterprise, using industry standards. Web services can also be used to integrate heterogeneous applications and data.

While many enterprises use Web services internally, there are numerous examples of external Web services that are available. Some of the popular ones are package-tracking services (provided by shippers like FedEx, UPS, and USPS). E-commerce websites, like www.amazon.com, www.yahoo.com, www.ebay.com, and www.google.com expose their core functionality using Web services. Developers can subscribe and use the Web services provided by these e-commerce providers to develop applications that add value to, or provide seamless integration with, back-end systems.

Java EE and Web Services

The Java EE platform has evolved over the last few years to become a mature, stable, reliable, and available platform for enterprise applications. While technologies like JDBC (Java Database Connectivity), JMS, and EJB have been in the Java EE platform right from the start, however, only in J2EE 1.4 has the development and deployment of Web services assumed better shape as they’ve been standardized to make the Web services in the Java EE platform more portable across application servers and interoperable with .NET Web Services. The common goal for the Java EE specifications was to provide ease of development and deployment for applications and services. Some of the key specifications in Java EE that are related to Web services are JAX-WS, JAXB, JAXR, SAAJ, and the JSR 181 annotations. In the following sections, we will show what these specifications are and how they can be used with EJB. Figure 6-3 shows how EJB interacts with different Web service-related specifications under the Java EE platform.

9781430246923_Fig06-03.jpg

Figure 6-3.  EJB and Web Services

JAX-WS

JAX-WS (Java API for XML Web Services) defines Java APIs and annotations for accessing Web services from Java applications and Java EE components like EJBs. JAX-WS provides mapping facilities between WSDL and Java interfaces, or from Java interfaces to WSDL. WSDL-mapped interfaces are called service endpoint interfaces. JAX-WS also provides the client-side and server-side APIs and annotations to send and receive Web service requests via SOAP. The JAX-WS specification in Java EE depends on other relevant specifications of the Java EE platform, including JSR 175 (related to annotations), JSR 181 (related to Web Services), and JAXB. It also provides support for the latest Web services standards like SOAP 1.2 and WSDL 2.0. Figure 6-4 shows a simplified diagram of a Web service invocation.

9781430246923_Fig06-04.jpg

Figure 6-4.  Web service invocation internals

JAX-RS

JAX-RS (JAX-RS: Java API for RESTful Web Services) defines Java APIs and annotations for creating Web services based on the REST architectural pattern. JAX-RS version 1.1 became an integral part of Java EE 6 through JSR-311. JAX-RS provides annotations like @PATH, @GET, @PUT, @POST, @DELETE, @HEAD, @PRODUCES, @CONSUMES, and so forth that help in mapping a POJO (plain old java objects) as a Web resource.

JAXB

Web services consumers and providers use XML messages to send requests and responses. These messages can be something like a purchase order that has an XSD, which allows the parties involved (provider and consumer) to understand the purchase order. Working with XML documents using low-level language APIs can be time consuming and can involve complex code. The JAXB (Java Architecture for XML Binding)specification, in context of Java EE, provides standard APIs for representing XML documents as Java artifacts so that developers can work off Java objects that represent the XML documents based on schemas (XSD). The JAXB specification facilitates unmarshalling XML documents into sets of Java objects and marshalling sets of Java objects back into XML documents. The JAXB specification provides full support for XML schemas and binding support for JAX-WS, and it leverages other Java EE specifications, such as JSR 175.

JAXR

UDDI is the standard for Web services registry. The JAXR (Java API for XML Registries) specification defines a standard set of APIs that allow Java clients to access the registry. These APIs can also be used against XML registries other than UDDI ones.

SAAJ

Similar to the attachments that you can use in e-mail messages, you can send attachments to the SOAP messages that invoke Web services. SAAJ (SOAP with Attachments API for Java)Java API for XML Registries defines a standard set of APIs that allow Java SE or EE components to construct SOAP messages with attachments.

JSR 181

JSR 181 (Web Services Metadata for the Java Platform) defines a standard set of annotations that can be used to simplify Web services development. These annotations can be used with Java classes or EJB session beans that can be JAX-WS components.

EJB Stateless Session Beans as Web Services

Web services endpoints that are described using WSDL are stateless in nature. Stateless session beans also share the same statelessness and are well suited for developing Web services. The EJB specification relies on other Web services specifications in the Java EE platform, including JAX-WS, JAXB, and JSR 181, either to consume Web services or publish stateless session beans as Web services.

A service endpoint interface (SEI) is one that is mapped to a Web service. JAX-WS provides this mapping layer. In order to develop a new Web service, you can take either the bottom-up or top-down approach, both of which are described below.

In the case of the bottom-up approach, you start with an SEI and an implementation that can be published as a Web service. In this process, Web service artifacts like WSDL documents are generated at deployment time or by the administrative tools or utilities provided by Java EE application servers.

In the top-down case, you start with a WSDL document and generate an SEI using tools that implement JAX-WS. Once you have an SEI, you can add the implementation behind it. In the case of EJB stateless session beans, you need to use the annotations provided in the JAX-WS and JSR 181 specifications to mark the business interfaces and/or bean classes so that the right set of Web services artifacts will be generated at deployment time. Java EE specifications require that the annotations added to components be processed at deployment time to generate the right set of artifacts. EJB stateless session beans with Web services annotations are no different; they are also processed at deployment time by the deployment utilities provided by the application servers. There will be one stateless session bean for each SEI.

Developing a New Web Service

Stateless session beans are implemented using the programming model described in Chapter 2. In case you want to make a stateless session bean as a Web service, you will need the following classes:

  • A bean class (implementation)
  • A Web service endpoint interface (optional)
  • Additional business interfaces if the bean class has local or remote clients

Creating a Bean Class

A stateless session bean class is any standard Java class that has a class-level annotation of @Stateless. Starting with version 3, the EJB specification doesn’t mandate the requirement of SEIs. Providing an SEI along with a bean class is optional. In the use case in which the bean class will be published as a Web service without any service endpoint interface, the bean class will have the additional class-level annotation @WebService (JSR 181). The @WebService annotation is in the javax.jws package, and it marks the bean class as an implementation for a SOAP-based Web service.

The @WebService annotation takes the parameters described in Table 6-3.

Table 6-3. The @WebService Annotation

Parameter Description Additional Info
name The name of the Web service that gets mapped to wsdl:portType. If not specified, the name of the Java class is taken.
targetNamespace The XML namespace used for the Web service. If not specified, the name of the Java class is taken.
serviceName The name of the Web service that gets mapped to wsdl:service. If not specified, the name of the Java class is taken.
wsdlLocation The location of the WSDL document, which comes in handy when the bean class is implementing existing Web service.

To illustrate a stateless session bean that gets published as a Web service, we will create a CreditServiceEndpointBean that will be published as CreditService.

In Listing 6-9, we have a Java class, CreditCheckEndpointBean, which has two class-level annotations: @Stateless and @WebService. The @Stateless annotation provides an additional parameter to mark the bean as CreditCheckEndpointBean. If the same class is exposed to remote or local clients, those clients will access the stateless session bean with that name. The @WebService annotation provides two additional parameters: one to mark the service name as CreditService and the other to specify the target namespace (instead of using the default Java package structure).

Listing 6-9.  CreditCheckEndpointBean.java

package com.apress.ejb.chapter06.services;
import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebService;

@Stateless(name = "CreditCheckEndpointBean")
@WebService(serviceName = "CreditService", targetNamespace = "http://www.apress.com/ejb/credit")
public class CreditCheckEndpointBean  {
    public CreditCheckEndpointBean() {
    }

}

The @WebMethod annotation defined in JSR 181 allows you to customize the method that is exposed as a Web service operation. If no @WebMethod annotations are specified in the bean class that has the @WebService annotation, then all public methods are exposed as Web service operations.

The @WebMethod annotation takes the parameters described in Table 6-4.

Table 6-4. The @WebMethod Annotation

Parameter Description Additional Info
operationName The name of the wsdl:operation that matches this method. By default, this is the name of the Java method.
action The action for this operation. In the case of SOAP bindings, it will be the value of the SOAP action header. By default, this is the name of the Java method.

In Listing 6-10, we have added the following method into the CreditCheckEndpointBean class, which will be exposed as a Web service operation. The operation name is customized as CreditCheck using @WebMethod parameters. The method takes a java.lang.String parameter (which is the credit card number) and returns a java.lang.boolean value of true or false, depending on whether the credit card is valid. For simplicity’s sake, we will always return true.

Listing 6-10.  The validateCC Method in CreditCheckEndpointBean.java

@WebMethod(operationName="CreditCheck" )
public boolean validateCC(String cc){
return true;
}

Web Service Endpoint Interface

JAX-WS doesn’t mandate the requirement of an SEI to implement a Web service endpoint. You can use the annotations provided in JSR 181 to mark the bean class as a Web service and one or more business methods as Web service operations. In the use case in which an SEI is defined for a stateless session bean, the following should be observed:

  • The SEI must have a javax.jws.WebService annotation.
  • One or more methods can have a javax.jws.WebMethod annotation.
  • All method parameters and return types should be compatible with the JAXB XML schema mapping definition.
  • Arguments and return types of methods must be valid JAX-RPC value types, which include Java primitives (int, long, and so on), Java classes (String, Date, and so forth), Java Beans, and arrays.
  • throws clauses must include a java.rmi.RemoteException in addition to any other application exceptions.

image Note   Support for JAX-RPC has been made optional in Java EE 7. The Java EE 7 specification encourages new applications to use the facilities provided by JAX-WS that simplifies Web service development.

In our examples, we are adding annotations to the bean class itself, as shown in Listings 6-9 and 6-10.

Listing 6-11 illustrates a service endpoint interface for the use case in which an SEI is provided, and Listing 6-12 shows the CreditCheckEndpointBean class implementing the SEI.

Listing 6-11.  A Service Endpoint Interface for the Use Case

@WebService(serviceName="CreditService",targetNamespace="http://www.apress.com/ejb/credit")
public interface CreditCheckEndpoint {

    @WebMethod(operationName="CreditCheck")
      public boolean validateCC(String cc);
}

Listing 6-12.  The CreditCheckEndpointBean Class Implementing the SEI

@Stateless
public class CreditCheckEndpointBean implements CreditCheckEndpoint {
    public CreditCheckEndpointBean() {
    }
    //implementation goes here
}

Packaging, Deploying, and Testing Web Services

Stateless session beans that have Web service annotations need to be packaged into EJB Java Archive (JAR) files before they are deployed into EJB containers. For some EJB containers or application servers, they first need to be assembled into EAR [Enterprise Archive] files). Most EJB containers or application servers provide deployment utilities or Ant tasks to facilitate deployment of EJBs to their containers. Java-integrated development environments (IDEs) like JDeveloper, NetBeans, and Eclipse also provide deployment features that allow developers to package, assemble, and deploy EJBs to application servers. Packaging, assembly, and deployment aspects are covered in detail in Chapter 11.

In this chapter, we have developed one stateless session bean (CreditCheckEndpointBean) with Web service annotations. We will perform the following steps to compile, deploy, and test the stateless session bean to be published as a Web service.

Prerequisites

Before performing any of the steps detailed in the next sections, complete the “Getting Started” section of Chapter 1, which walks you through the installation and environment setup required for the samples in this chapter.

Compiling the Session Bean

Copy the Chapter06-WebServiceSamples directory and its contents into a directory of your choice. Run the NetBeans IDE, and open the Chapter06-WebServiceSamples project using the File -> Open Project menu. Make sure that the ‘Open Required Projects' checkbox is checked, as shown in Figure 6-5.

9781430246923_Fig06-05.jpg

Figure 6-5.  Opening the Chapter06-WebServiceSamples project

Expand the Chapter06-WebServiceSamples-ejb node, and observe that the session bean-based Web service that we created appears in com.apress.ejb.chapter06.services package. Similarly, the client servlet also appears under the Chapter06-WebServiceSamples-war node.

9781430246923_Fig06-06.jpg

Figure 6-6.   Verifying that the Session Bean and its clients are available in the project

Invoke the context menu on Chapter06-WebServiceSamples node, and build the application by selecting the Clean and Build menu option. The session bean-based Web service will compile without any errors, but the client in Chapter06-WebServiceSamples-war node will show compilation errors. We will ignore these errors in the client for now.

9781430246923_Fig06-07.jpg

Figure 6-7.   Building the application

Deploying the Session Bean-Based Web Service

Once we have compiled the session bean, we can deploy it to the GlassFish application server. Invoke the context menu on Chapter06-WebServiceSamples-ejb node, and deploy the application by selecting the Deploy menu option, as shown in Figure 6-8.

9781430246923_Fig06-08.jpg

Figure 6-8.  Deploying CreditService

Testing the Credit Service

After successful deployment, we can use the test harness to see if CreditService can be invoked properly or not. To invoke the test harness, expand the Web Services node under Chapter06-WebServiceSamples-ejb to expose the CreditCheckEndpointBean node, and select the Test Web Service menu option, as shown in Figure 6-9.

9781430246923_Fig06-09.jpg

Figure 6-9.  Testing CreditService

In the generated test harness page (shown in Figure 6-10), enter 12345 as the credit card number, and click the creditCheck button. You can also click on the WSDL File link to check its contents. Bookmark the WSDL File URL, as it will be used for creating a Web service client in the later sections.

9781430246923_Fig06-10.jpg

Figure 6-10.  The Web service test harness

In the generated page, you can test the results with a SOAP request and response, as shown in Figure 6-11.

9781430246923_Fig06-11.jpg

Figure 6-11.  SOAP request and response messages

So far, we have seen how to test the deployed Web services using the test harness. In the next section, we will discuss Web Services clients and how you can develop and run programs that can invoke Web services. In our case, we will be testing against the deployed credit service.

Web Service Client View

A stateless session bean that is published as a Web service can be accessed using the client view described by the WSDL document that gets generated during deployment (as shown in Listing 6-7). Since the stateless session bean is published as a Web service using standards such as WSDL, any type of client application that can send and receive SOAP messages (irrespective of technology or language) can invoke it. The client application can be written using .NET or Java EE, or scripting languages such as PHP, Python, or Ruby. From the client point of view, what it sees as a contract is a WSDL document. In order to access the Web service, programmatic interfaces should be generated from the WSDL document.

Web services are location independent, and they can be accessed remotely. If the client application invoking a Web service is a Java client or other Java EE component, such as an EJB, it uses JAX-WS client APIs or annotations to invoke the Web service via SOAP and HTTP.

Developing a Java Client That Accesses the Web Service

In order to access a Web service via a WSDL service contract, the client program needs programmatic interfaces (commonly known as stubs or proxies) generated from the WSDL document. Once the stubs have been generated from the WSDL document, we can use the JAX-WS annotations to get a reference to the Web service and invoke it.

Generating Web Service Proxy Classes

We will start by generating stubs for the CreditService WSDL document using the Web Service Client wizard provided by the NetBeans IDE. Invoke the Web Service Client wizard from the context menu of Chapter06-WebServiceSamples-ejb node, as shown in Figure 6-12.

9781430246923_Fig06-12.jpg

Figure 6-12.  Invoking the Web Service Client wizard

In the Web Service Client wizard, select the WSDL URL radio button, and enter the WSDL File URL that you had bookmarked in the earlier section (see Figure 6-10). We also need to specify the package where the client Java artifacts will be generated. We will generate these artifacts in the com.apress.ejb.chapter06.services.client package. Enter these details, as shown in Figure 6-13, and finish the wizard.

9781430246923_Fig06-13.jpg

Figure 6-13.  Creating a Web Service Client

Once the stubs are generated and compiled, we can see artifacts under Generated Sources (jax-ws) node.

9781430246923_Fig06-14.jpg

Figure 6-14.   Verifying the generated stub sources

image Note   GlassFish also provides the command-line utility wsimport.bat, which can generate Web service stubs given a valid WSDL document. In case you are deploying the Web service to other Java EE compatible servers, these servers might also provide some tools or utilities to generate the stubs for the Web service.

Once the stubs are generated and compiled, the next step is to create a client that will consume CreditService.

The JAX-WS specification provides the @WebServiceRef annotations that can be used to declare a reference to a Web service, which in our case is CreditService.

The @WebServiceRef annotation can take the parameters described in Table 6-5.

Table 6-5. The @WebServiceRef Annotation

Parameter Description Additional Info
name The name that identifies the Web service reference The name that is local to the application component using the resource
wsdlLocation The URL pointing to the location of the WSDL document
type The resource type
value The service type
mappedName The physical name of the resource used to map the resource to a vendor-specific container

Developing a Web Service Client Program

The @WebServiceRef annotation either provides a reference to the SEI generated by the container, or a reference to the SEI provided by the application developer. Listing 6-13 shows a servlet class that is going to be a Web service client. In this servlet class, CreditServiceClient, we are using dependency injection to inject the credit service that we have deployed earlier as a Web service. The @WebServiceRef annotation is used to inject the CreditService that has been generated as the proxy class. Once we have the injected the available resource, we use that proxy class to get the Web service port using the getCreditCheckEndpointBeanPort() method. After successfully getting the port, we can invoke the operations that are available on the port. In our case, we have defined only one operation, creditCheck. You can see that this is being invoked with a credit card number of 12345678.

Listing 6-13.  CreditServiceClient.java

package com.apress.ejb.chapter06.client;
import com.apress.ejb.chapter06.services.client.CreditCheckEndpointBean;
import com.apress.ejb.chapter06.services.client.CreditService;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.WebServiceRef;

@WebServlet(name = "CreditServiceClient", urlPatterns = {"/CreditServiceClient"})
public class CreditServiceClient extends HttpServlet {
      @WebServiceRef(wsdlLocation = "http://localhost:64082/CreditService/CreditCheckEndpointBean?WSDL")
      CreditService service;
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet CreditServiceClient</title>");
            out.println("</head>");
            out.println("<body>");
            CreditCheckEndpointBean creditService = service.getCreditCheckEndpointBeanPort();
            out.println("<h1>Credit Check returned: " + creditService.creditCheck("12345678") + "</h1>");
            out.println("</body>");
            out.println("</html>");
        } finally {
            out.close();
        }
    }
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    public String getServletInfo() {
        return "Short description";
    }
}

Compiling the Client Class

Invoke the context menu on the Chapter06-WebServiceSamples-war node, and build the client by selecting the Clean and Build menu option, as shown in Figure 6-15.

9781430246923_Fig06-15.jpg

Figure 6-15.  Compiling the Web service client

Running the Web Service Client

Once we have compiled the client, we need to set CreditServiceClient as the run target. Open the Project Properties dialog by invoking the context menu on the Chapter06-WebServiceSamples node, and select the Properties menu option. Set CreditServiceClient as the run target, as shown in Figure 6-16.

9781430246923_Fig06-16.jpg

Figure 6-16.  Setting the run target as CreditServiceClient

To run the client servlet, invoke the context menu on the Chapter06-WebServiceSamples node, and select the Run menu option, as shown in Figure 6-17.

9781430246923_Fig06-17.jpg

Figure 6-17.  Running the client

Once the CreditServiceClient runs successfully, NetBeans will open your default browser and execute the selected servlet. Here is the output from CreditServiceClient servlet.

9781430246923_Fig06-18.jpg

Figure 6-18.   Checking the servlet output

Session Beans as Web Service Clients

A session bean can also be a client to a Web service. In the sample application that we will build in Chapter 7, the OrderProcessing session bean, which coordinates the workflow, can invoke the credit service to check the validity of the credit card before starting to process the order. To act as a client to a Web service, the OrderProcessing session bean would make use of the @WebServiceRef annotation, similar to what we have shown in the previous client sample.

Listing 6-14 shows the stateless session bean OrderProcessFacadeBean, which implements both local and remote business interfaces. The @WebServiceRef annotation is used to inject a reference to the CreditService WSDL document. The PerformCheckCredit() method in the OrderProcessFacadeBean session bean uses the injected reference to get the port in the CreditService and invokes the creditCheck operation. As you can see, the process of injecting the Web service, getting the port, and calling the operations from a session bean is similar to what we have done with the client that acted as a Web service client.

Listing 6-14.  OrderProcessFacadeBean.java

@Stateless(name="OrderProcessFacade")
public class OrderProcessFacadeBean implements OrderProcessFacade,
                                               OrderProcessFacadeLocal {
    @WebServiceRef(type=CreditService.class)
    CreditService service;
    public OrderProcessFacadeBean() {
    }

    private boolean PerformCreditCheck(Individual customer){
                String ccnum  = customer.getCcNum().toString();
                CreditCheckEndpointBean creditService =
                    service.getCreditCheckEndpointBeanPort();
                return creditService.creditCheck(ccnum);
           }
}

Conclusion

In this chapter, we introduced you to Web Services—the architecture that goes by the find-bind-execute model—and how standards like UDDI, WSDL, and SOAP have made Web Services ubiquitous as compared to earlier distributed computing models in terms of standardization and interoperability. We also briefly discussed the REST architectural pattern and RESTful Web services, which have simplified creation and use of Web services.

We looked into the details of the UDDI, SOAP, and WSDL standards, and we demonstrated how WSDL documents and SOAP messages are constructed with a simple credit service example.

We discussed some use cases for which Web services can be used, and we discussed how they fit into intranet and Internet models, including some examples of existing e-commerce sites that provide Web services.

We then dived into the Java EE platform and looked at different standards (JAX-WS, JAX-RS, JAXB, JAXR, SAAJ, and JSR 181) that are enabling developers to create Web services that are portable and interoperable within the .NET platform.

We then looked at how to publish EJB stateless session beans as Web services using simple Web Services Metadata annotations. We developed a credit service that can be invoked from Web service clients.

Finally, we looked at compiling, deploying, and testing Web services using the GlassFish application server and servlet clients, and we also looked at how this programming model is similar to invoking Web services with EJBs.

So far, we have discussed the individual components of the EJB specification: session beans, JPA entities, MDBs, and Web services. In the next chapter, we will discuss how you can integrate all of these components to build an enterprise application.

..................Content has been hidden....................

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