Monday, March 24, 2008

Simplify Your Web Services Development with JSR 181

Source

By Ayyappan Gandhirajan

Go to page: 1 2 3 Next

Web Services are a true interoperable technology that enables disparate systems talk to each other using a common protocol. After realizing the potentials of Web Services in Application Integration and Service Oriented Architecture (SOA), the list of companies that embraces Web Services to gain edge over competitors is growing steadily. For the standardization of Web Service description, invocation and management, there are several specifications and standards available from Consortiums like W3C and OASIS. However, there are still issues in developing portable Web Services, which could run in any J2EE runtime environment. Though J2EE 1.4 tried to standardize the Web Service deployment process, the developers still have to create the deployment configuration files, create the WSDL from the Java class and package them together.

In order to trim down the complexities involved in the configuration and deployment of Web Services, the Java Specification Request (JSR) community endeavors to solve the problem by presenting us two JSRs:

  • JSR 181 — Web Services Metadata for the JavaTM Platform
    • Standardize the development of Web Service interfaces
  • JSR 921 — Implementing Enterprise Web Services 1.1
    • Standardize the vendor implementation of Web Services

This article is an attempt to highlight the features of JSR 181 specification and show you how easily you can build and deploy JSR 181 Web Services in WebLogic application server.

JSR 181 Web Services

JSR 181 or Web Services Metadata for the Java Platform is a Java Specification Request that defines an annotated Java format that uses Java Language Metadata (JSR 175) to enable easy definition of Java Web Services in a J2EE container. To put simply, JSR 181 enables developers to create portable Java Web Services from a simple Plain Old Java Object (POJO) class by adding annotations.

This Web Service development model may be related to JSP model where a JSP file is translated into a Servlet that gets in turn compiled to a class file that finally runs inside the container. The JSP model frees the developers from manual compilation and deployment of Servlets into container. Similarly in this model too, Web Service developers defines only the annotated Java Web Service (JWS) file and leave the job of creating necessary deployment and configuration files to the vendor (who actually implements Web Services based on JSR 921 specification). For example, WebLogic application server provides an Ant task called jwsc to create the JSR 921 compliant Web Service implementations. As the generation of JSR 921 compliant Web Services is hidden to developers, they can focus on developing core business services rather than worrying on learning and implementing generalized APIs and deployment descriptors.

The annotated Web Service development model also provides fine-grained control over exposing the Web Services. It enables the developers to expose the entire class or only the selected methods as the Web Service. This feature may be of great help when the Java class contains core business methods bundled along with non-business methods and/or data service methods, which the developer might not want to expose as services. In this scenario, the developer may take advantage of the annotations to specify how a Web Service should be exposed to outside world.

Putting simply, JSR 181 is a specification to define standard and portable Web Services. It offers the following benefits:

  • Provide a simplified model for developing Web Services
  • Abstract the implementation details
  • Achieve robustness, easy maintenance, and high interoperability

Sample Web Service Development

This section adopts the incremental development approach to guide you through developing a sample JSR 181 Web Service and deploying in WebLogic application server 10.0.

In the example, you will build a "Zip Code Finder" Web Service that has a single operation namely getZipCode. For a given pair of city and state, the getZipCode operation will return the corresponding zip code. Following are the step-by-step instructions:

Step 1 — Service end point object

The service end point object here is a simple POJO class that is going to be exposed as Web Service. This POJO class is a mock implementation of Zip Code Finder Service that returns 08817 (i.e., the zip code for "Edison, NJ") for any input pair of city and state. Listing 1 shows the complete code implementation.

Listing 1: Service end point object

package service;

public class ZipCodeFinderService {
public String getZipCode( String city, String state ) {
return "08817";
}
}

Step 2 — Declare POJO as Web Service

JSR 181 API provides an annotation type called @WebService to mark the Java class as Web Service. The @WebService annotation type has five attributes, which can be optionally used to define the port type and service name of the Web Service. Some of the important attributes are given below:

  • Name — Maps to wsdl:portType in WSDL 1.1
  • Service name — Maps to wsdl:service in WSDL 1.1
  • Target name space — Maps to targetNamespace in WSDL 1.1

Listing 2 shows the complete code implementation with @WebService annotation type:

Listing 2: Declaring WebService

package service;
import javax.jws.WebService;

@WebService ( name = "ZipCodeFinder",
serviceName="ZipCodeFinder",
targetNamespace = "http://sampleweb.com/services")


public class ZipCodeFinderService {
public String getZipCode( String city, String state ) {
return "08817";
}
}

The highlighted lines in Listing 2 (and the highlighted lines in rest of the listings in this article) will show you the incremental change that is done to the code displayed in Listing 1.

Step 3 — Declare SOAP Binding

This @SOAPBinding annotation type is used to define the Web Service binding. The Web Service developer may assign proper values for message encoding and format. This annotation type has following important attributes:

  • Messaging Style
    • Encoding style for message that is transported in the wire
    • Possible values: RPC or DOCUMENT
    • Default: DOCUMENT
  • Messaging Use
    • Formatting style for message that is transported in the wire
    • Possible values: ENCODED or LITERAL
    • Default: LITERAL
  • Parameter Style
    • Decides whether operation name needs to be part of the SOAP body
    • Possible values: BARE or WRAPPED
    • Default: WRAPPED

Listing 3 shows the code implementation along with @SOAPBinding annotation type:

Listing 3: Define SOAP Binding

package service;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

@WebService( name = "ZipCodeFinder",
serviceName="ZipCodeFinder",
targetNamespace = "http://sampleweb.com/services")

@SOAPBinding( style = SOAPBinding.Style.DOCUMENT,
use = SOAPBinding.Use.LITERAL,
parameterStyle = SOAPBinding.ParameterStyle.WRAPPED )


public class ZipCodeFinderService {
public String getZipCode( String city, String state ) {
return "08817";
}
}

Step 4 — Optional Transport Declaration

You can use an optional WebLogic annotation type (not a standard) to refine the Web Service further. The @WLHttpTransport annotation type helps you change the context and service URI of the Web Service. The important attributes are:

  • Context Path — The context path of the Web Service URL
  • Service URI — Information next to context path in the Web Service URL

Listing 4 shows the implementation of the optional transport declaration:

Listing 4: Defining optional transport

package service;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import weblogic.jws.WLHttpTransport;

@WebService( name = "ZipCodeFinder",
serviceName="ZipCodeFinder",
targetNamespace = "http://sampleweb.com/services")

@SOAPBinding( style = SOAPBinding.Style.DOCUMENT,
use = SOAPBinding.Use.LITERAL,
parameterStyle = SOAPBinding.ParameterStyle.WRAPPED )

@WLHttpTransport( contextPath = "ZipCodeServices",
serviceUri = "ZipCodeFinderService" )


public class ZipCodeFinderService {
public String getZipCode( String city, String state ) {
return "08817";
}
}

Step 5 — Declare Web Method

This section will help you how to expose selectively the operations in the POJO class. For some scenario, you might want only to expose business operations and bar data operations in the Java class. In that scenario, you may find @WebMethod annotation type useful.

The @WebMethod has the following attributes:

  • Operation name — Name of the Java method that needs to be exposed as operation
  • Action — SOAP action

Listing 5 shows the implementation of the Web method:

Listing 5: Define WebMethod

package service;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import weblogic.jws.WLHttpTransport;

@WebService( name = "ZipCodeFinder",
serviceName="ZipCodeFinder",
targetNamespace = "http://sampleweb.com/services")

@SOAPBinding( style = SOAPBinding.Style.DOCUMENT,
use = SOAPBinding.Use.LITERAL,
parameterStyle = SOAPBinding.ParameterStyle.WRAPPED )

@WLHttpTransport( contextPath = "ZipCodeServices",
serviceUri = "ZipCodeFinderService" )

@WebMethod( operationName = "getZipCode" )
public class ZipCodeFinderService {
public String getZipCode( String city, String state ) {
return "08817";
}
}

Step 6 — Build file

To reiterate, the Web Service developer needs only to define the Web Service interfaces using JSR 181 annotation but does not need to worry about the remaining deployment process. The corresponding vendor platform, in our case WebLogic, will take care of implementing (or generating) necessary classes and configuration files, which are JSR 921 compliant.

As mentioned earlier, WebLogic application server provides an ant task namely jwsc. The ant task will take a few inputs like name of the annotated Web Service file name and build directory and then create the necessary files in EAR format, which can be deployed into WebLogic application server using a separate ant task (wldeploy) or manual deployment via administration console.

Listing 6 shows a sample ant configuration file with two important tasks:

  1. Build
    1. Clean directories and files generated as part of previous build (if any)
    2. Use jwsc to generate Web Service deployment files in EAR format
  2. Deploy
    1. Use wldeploy ant task to deploy the ear into WebLogic application server

Listing 6: Build file for building and deploying Web Service






jwsc"
classname="weblogic.wsee.tools.anttasks.JwscTask" />
all" depends="build, deploy" />
build" depends="clean, server" />
clean">


server">

srcdir="${basedir}/src/service"
destdir="${ear.dir}"
classpath="${java.class.path}"
fork="true"
keepGenerated="true"
deprecation="${deprecation}"
debug="${debug}"
verbose="false">



deploy">
<wldeploy action="deploy"
source="${ear.dir}" user="weblogic"
password="weblogic" verbose="true"
adminurl="t3://localhost:7001"
targets="AdminServer" />


Step 7 — Running build file

In order to run ant build and deploy targets, you will need to do the following steps:

  1. Open command prompt
  2. Call %WL_HOME%\server\bin\setWLSEnv.cmd
    1. This will set up all necessary path and classpath
  3. Now, run "ant build deploy"
    1. The build target will create necessary classes in a proper layout
    2. The deploy target will deploy the ear into application server

Step 8 — Testing

Now all dirty jobs of creating Java class, build files, running ant tasks are over. It is time to test the Web Service that was deployed in the previous steps.

If you strictly followed the steps mentioned above, the Web Service would be deployed with a URL http://localhost:7001/ZipCodeServices/ZipCodeFinderService and its WSDL can be accessed from http://localhost:7001/ZipCodeServices/ZipCodeFinderService?WSDL

This article does not create or attempt to create the Web Service client that can consume the deployed Web Services as nothing has fundamentally changed in the way the Web Service client works. You are encouraged to use whatever implementation you are comfortable to create Web Service clients.

I used Apache Axis 1.4 to create Web Service stubs to consume the deployed Web Service. The following listings (Listing 7 and Listing 8) capture the incoming and outgoing SOAP messages respectively.

Listing 7: Request SOAP message for Zip Code Finder Service





Edison
NJ



Listing 8: Response SOAP message for Zip Code Finder Service





08817



Comparison with conventional Web Services

The conventional Web Services development required developers to spend extra time in configuration and deployment whenever the underlying SOAP container was changed. The annotated Java Web services will save developers not to worry too much about deployment but concentrate on the core business areas.

The source level configuration of JSR 181 Web Services will also help the developers achieving uniform configuration and development process where the deployment of Web Service will be taken care by JSR 921 specification.

Conclusion

Web Service technology is one of those areas which evolves rapidly towards maturity. JSR 181 is an attempt to standardize and simplify the Web Service development, which will free you as a developer from the underlying implementation details and you concentrate on core business areas. Apart from standardization, they also help Web Service to achieve robustness, easy maintenance and interoperability.

Reference

About the author

Ayyappan Gandhirajan holds a Master's degree in Software Systems from BITS, Pilani, India and a Bachelor's degree in Electronics & Communication Engineering from MK University, India. He has 10 years of profound software experience in Travel, Telecom/Mobility, and e-commerce domains using technologies such as SOA, ESB, Web Service, Web Service Security, Spring, AOP and J2EE. He is currently working for Perot Systems, Bangalore, India. Before joining Perot Systems, he worked for good five years with Hewlett-Packard ISO, Bangalore, India. He can be reached at G_Ayyapparaj@yahoo.com / ayyappan.gandhirajan@ps.net

0 comments: