Over a million developers have joined DZone.

Advanced Web Service Interoperability In Easy Steps

· Java Zone

Check out this 8-step guide to see how you can increase your productivity by skipping slow application redeploys and by implementing application profiling, as you code! Brought to you in partnership with ZeroTurnaround.

This article is intended for programmers who are interested in adding additional qualities to their services, clients, or SOA solutions, as well as for beginners in Java web service development. You will learn how to use NetBeans IDE 6.1 to develop Java web service clients and services that can interoperate with Microsoft .NET 3.0 clients and services, how to use encryption and signatures to protect confidentiality and integrity of message transmission without need for SSL, and how to use Reliability features to ensure that none of your application messages are lost or delivered twice.

NetBeans IDE 6.1 comes with enhanced support for web services development, reflecting the state of industry-wide adopted technologies in web services and Service Oriented Architecture (SOA). NetBeans includes unique and easy to use tools, from visual web service design to enabling powerful technologies for security, reliability or transactions. Bundled together with ready-to-run examples, help and documentation, it provides an easy entrance point for beginners in web service development as well as a broad set of features required by enterprise class solutions and SOA.

METRO Overview

Most of the web service related features in NetBeans are built with the use of Project Metro. Project Metro is the Web services stack (framework) from Sun Microsystems. The stack is integrated in GlassFish V2, a high-performance, production-quality, Java EE 5 compatible application server.

The individual components of Metro can be divided in two categories:

● JAX-WS Implementation – The core Web services platform
Project Tango, also referred to as Web Services Interoperability Technology (WSIT)

JAX-WS is the core Web Service platform, including all the SOAP message functionality, and Project Tango adds interoperability with Microsoft .NET, Reliability, Security, and Transactions.

Tango Terminology

  • Credentials – A set of claims used to prove the identity of a client. They contain an identifier for the client and a proof of the client's identity, such as a password. They may also include information, such as a signature, to indicate that the issuer certifies the claims in the credential.
  • Direct Authentication – A type of authentication where the service validates credentials directly with an identity store, such as a database or directory service.
  • Impersonation – The act of assuming a different identity on a temporary basis so that a different security context or set of credentials can be used to access the resource.
  • Message Layer Security – Represents an approach where all the information that is related to security is encapsulated in the message. In other words, with message layer security, the credentials are passed in the message.
  • Mutual Authentication – This is a form of authentication where the client authenticates the server in addition to the server that authenticates the client.
  • Security Token – A set of claims used to prove the identity of a client. They contain an identifier for the client and a proof of the client's identity such as a password. They may also include information, such as a signature, to indicate that the issuer certifies the claims in the credential. Most security tokens will also contain additional information that is specific to the authentication broker that issued the token.
  • Transport Layer Security – Represents an approach where security protection is enforced by lower level network communication protocols (such as SSL).
  • Trusted subsystem (domain) – This is a process where a trusted business identity is used to access a resource on behalf of the client. The identity could belong to a service account or it could be the identity of an application account created specifically for access to remote resources.


Get Ready For Web Services

Implement and Deploy web service

In this example, we show how to develop a web service. We enhance this service with additional capabilities in later chapters. Our service will be able to receive banking orders and store them in a map (for simplicity, we'll skip databases in this example). First, create an Enterprise Application in which we will host our web service, by choosing File -> New Project and selecting Enterprise Application. Click Next and name the application BankApplication. Leave the other values at default. Your wizard screen for Enterprise Application should look similar to Figure 1.

Note: The target server is GlassFish v2. You can have it installed with your NetBeans IDE 6.1 installation if you choose the Full or Web & J2EE download or specifically select GlassFish). If you don't have it, download GlassFish from http://glassfish.dev.java.net, and register it into NetBeans through Tools -> Servers.

Figure 1. Creating Enterprise Application


Now create the web service itself in the EJB module. Right-click BankApplication-ejb node and select New -> Web Service. In the wizard window, name the web service BankOrderService and place it in package bankorder.service as shown on Figure 2.

Figure 2. Creating a Web Service in an EJB module

After clicking Finish, you should see the Visual Designer window for your web service. It is empty, because we did not define any operations for the service yet. Our application should be able to receive orders, and we would like to model them as a Java class with 3 fields for recipient account number, sender account number, and the actual amount being transferred. We will represent this data in a class called bankorder.data.BankOrder. Create the class as shown on Listing 1, and then use the Refactoring -> Encapsulate Fields feature in the editor to generate setters and getters for all fields.

Listing 1. BankOrder.java Class for transferring information about the Banking orders between service and client

package bankorder.data;

public class BankOrder {
private int id;
private String receiverAccount;
private String sender Account;

With the data transfer class ready, we are able to implement the web service itself. Return to the web service BankOrderService we created in previous step, click Add Operation in the visual designer, and fill in the details as shown in Figure 3. The operation should return String as a status code to reflect if the order has been successfully submitted or not, and will take our BankOrder data transfer object as a parameter. After you added the operation, select Source tab at the top of the visual designer, which will navigate you to the service source code. There, make sure the implementation of the receiveBankOrder() operation corresponds to Listing 2.

Figure 3. Creating Data Transfer Object

Listing 2. BankOrderService.java Banking Web Service implementation

package bankorder.service;

import bankorder.data.BankOrder;
import java.util.HashMap;
import javax.jws.*;
import javax.ejb.Stateless;

public class BankOrderService {

public static final HashMap bankOrderStorage = new HashMap();

@WebMethod(operationName = "receiveBankOrder")
public String receiveBankOrder(@WebParam(name = "order")
BankOrder order) {
String status = "";
try {
bankOrderStorage.put(order.getId(), order);
return "OK";
} catch (Exception e) {
status += e.getLocalizedMessage();
return "FAIL" + status;


Implementing the web service is the final step, and we're ready to deploy the web service to the application server (GlassFish). Right-click the BankApplication node, and select the Undeploy & Deploy menu item. Once the application is deployed, verify your service by invoking BankOrderService -> Test Web Service action. After invocation, your browser window should show a page similar to Figure 4.

Figure 4. Web Service Tester Page


Implement Client to call the web service

We will continue in our sample with the Client implementation. The client will be a web application that will show a simple form to input the data for a bank order together with a Submit button. Clicking Submit will submit the form data to a processing servlet, which will call the web service. Based on success or failure feedback from the service, the client will redirect to success,jsp or failure.jsp pages. To implement what we described, create a simple Web Application by selecting New Project -> Web Application. The name of the application is going to be WebBankClientApplication. The wizard screen is shown in Figure 5.

Figure 5. Creating Client Web Application

Continue with creating a Web Service Client. Right-click the WebBankClientApplication node, and select New -> Web Service Client. In the wizard window, select the service we implemented by clicking the Browse button next to the project field. Place the client in the package bankorder.webclient. The details are shown in Figure 6.

Figure 6. Creating a Web Service Client

Once the client is created, you should see a Web Service References node in the project view, and expanding all nodes underneath should reveal the web service operation. Now let's use the client and call the web service operation in a processing servlet. The servlet will accept requests coming from the JSP page, and will transform the data from a request into our data transfer object called BankOrder. Then it will invoke the service with the BankOrder object as a parameter. Create the servlet by choosing New -> Servlet in your client project context menu, name it OrderSubmission and place it in the bankorder.web package. Then implement the servlet according to Listing 3. To help with web service invocation, drag the receiveBankOrder() web service operation from Web Service References into your servlet source code – directly into processRequest() method. NetBeans will generate the necessary annotations and web service invocation code for you.

Listing 3. OrderSubmission.java Processing servlet, processRequest() operation implementation

try {
bankorder.webclient.BankOrderService port = service.getBankOrderServicePort();
bankorder.webclient.BankOrder order = new bankorder.webclient.BankOrder();
java.lang.String result = port.receiveBankOrder(order);
if (result.equals("OK")) {
} else {
} catch (Exception e) {

Next, create the pages that the servlet redirects to. Their names shall be failure.jsp and success.jsp. Contents for both is in Listing 4 and 5.

Listing 4. failure.jsp Failure notification page
<h2>Service invocation failed!
Check server log for more info.</h2>

Listing 5. success.jsp Success notification page
<h2>Bank Order successfully submitted!</h2>

As a last step, we're missing the web form to fill the bank order data into. The form can reside in the default index.jsp which is already created in your project. Listing 6 shows the form, which will submit the data to the implemented OrderSubmission servlet.

Listing 6. index.jsp Form for entering bank order data (account numbers, amount)
<form name="OrderSubmission" action="OrderSubmission" method="POST">
Amount: <input type="text" name="amount" value="100" /><br/>
Sender Account: <input type="text" name="senderAcc" value="5678" /><br/>
Recipient Account: <input type="text" name="recAcc" value="1234" /><br/>
<input type="submit" value="Submit" name="Submit" />

And we're ready! Run the web application, enter some data, click Submit and observe the message flow in the GlassFish output window.

To see the messages and HTTP requests and responses flowing between services and clients, add following Java options to your GlassFish domain.xml ($GLASSFISH_DIR/domains/domain1/config/domain.xml):



Enhancing your service/client with Security and Reliability

The work we have done so far has covered web service implementation. However, to make our example more realistic, we need to make sure of several things. It would be very bad if your bank order requests have been lost during transmission and you wouldn't know about it. Also, it would be wrong if banking orders are executed in a different order than you submit them. Reliability features of Metro will help us here, but the list of complaints against the basic implementation is longer.

From security perspective, we need to make sure that only certain users are able to submit the orders. Also, when they are sending the orders, we should make sure the communication is encrypted so that nobody can read what kind of banking orders we are submitting, and we need to use signing of messages to ensure that the message has not been tampered with on the route from service to client and back.

Performance is also important, so we'd prefer not to establish a secure session for each message, but establish only one secure session, send multiple messages during the session and then terminate it, or set a timeout when the session should terminate.

To help with these additional requirements for our service implementation, we'll use the WSIT NetBeans plugins, which are directly included in NetBeans Full or Web & Java EE bundles. To invoke the WSIT functionality for your web service, click the Advanced... button in the bottom of the Visual WS designer, or right-click your web service in project explorer window and select Edit WS Attributes action. You should see a dialog corresponding to Figure 7.

Figure 7. Quality Of Service Settings in NetBeans IDE 6.1



Let's start with solving the first two complaints first. To make sure that messages are not lost on the wire, click the Reliable Message Delivery checkbox, as shown on Figure 8. Right below that, click Deliver Messages In Exact Order to solve the second complaint. That sets up the reliability features of project Metro. Close the dialog, redeploy the service BankApplication and the client, and submit several orders again.

Figure 8. Setting up Reliability and Ordered Message Delivery

If you look closely to your application, you might notice the dialog created one configuration file, called wsit-bankorder.service.BankOrderService under project's src/conf folder. The file includes the settings in the form of Policy expressions, understood by WSIT implementation.

With this setup, you can see that message communication has changed a bit. In the message log, you may find the messages contain new headers, such as those from Listing 7. Some namespace declarations are removed from there for more clarity.

Listing 7. Message Headers with Reliable Messaging turned on

<RelatesTo >uuid:fcd8cf00-3f97-49b6-a290-58fb7c8afdd5</RelatesTo>

Presence of those headers means that Reliable Messaging is active. You might notice the Sequence identifiers and MessageIDs. Those are used to ensure proper delivery so that the Metro runtime knows which message to resend if it has been lost, and also how to order the messages correctly on receiving side.


Security - Service

Now focus on the security requirements. NetBeans allows you to secure your service in one step. Return back to the Quality Of Service dialog, choose Secure Service option as shown on Figure 9 and redeploy the application. That's all you need to do on service side to secure your service. If you try to invoke your client again, you'll see it fails because it does not specify required credentials for the service.

Figure 9. Setting up Security on service

For development purposes, NetBeans with Metro provides certificates to be used. These development credentials are used if you click Use Development Defaults checkbox, which is chosen by default. For your production purposes, you will need a real certificates issued by appropriate certificate authorities.

In the real world, security considerations are much more broad, so the default settings might not apply for your real life scenario. NetBeans IDE 6.1 defines several Security Profiles, which are designed for different security scenarios. The default profile is called Username Authentication With Symmetric Keys. The profile uses message level security, and protects your application for integrity and confidentiality, which means that the communication between service and client is encrypted and signed. With this profile, symmetric key cryptography is used – it relies on a single, shared secret key that is used to both sign and encrypt a message. Symmetric keys are usually faster than public key cryptography. For this profile, the client does not possess any certificate/key of his own, but instead sends its username/password for authentication. The client shares a secret key with the server. The shared, symmetric key is generated at runtime and encrypted using the service's certificate. The client must specify the alias in the truststore by identifying the server's certificate alias.

From other profiles, you may choose different security mechanisms with message level security or SSL transport, using SAML tokens, or using Secure Token Service (STS). STS profiles are used to introduce 3rd party into the client-service communication. Client authenticates with the 3rd party (STS provider), and further requests to the service are made using security tokens issued by the 3rd party.

Each security profile can be configured in detail through the configuration dialog. The settings correspond to the profile chosen, but for most non-SSL based security profiles you can specify the key lengths used (128-256bit), configure Secure Conversation and other settings. Secure Conversation is switched on automatically when Reliable Messaging is used, and improves performance of secure communication between service and client significantly where multiple messages are transferred. With Secure Conversation, the security context is established only once, and further communication happens using derived keys. One of the configuration dialogs is shown on Figure 10.

Figure 10. Security Profile configuration dialog

A complete description of the configuration, security requirements and possibilities would be enough for a book or two, so for further information you can consult the Metro documentation, where you'll find the list of security profiles with descriptions to easily find which profile match your needs.


Security – Client

After we secure the service, our client is not allowed to communicate with it anymore, because it requires credentials. To fix this, we need to let the client know about the new service capabilities. These capabilities are advertised in the service WSDL in the form of Policy assertions, such as those in Listing 8.

Listing 8. Policy assertions describing Reliability settings on service – Reliability enabled, Ordered Delivery enabled

<wsp:Policy wsu:Id="BankOrderServicePortBindingPolicy">

Right-click your WS client under the Web Service References node, and select Refresh Client. Choose also an option to replace service WSDL with new version in the next dialog. With this update, the client is aware of service security capabilities, but it still doesn't have the required credentials. To set them, right-click the client node again, and select the Edit WS Attributes action. The client Quality Of Service dialog is shown in Figure 11.

Figure 11. Setting up Security on client

For development purposes, select Use development defaults button, click OK, redeploy your client application and try to submit several banking orders again. Check the GlassFish log for the messages. You'll notice they are encrypted, and you can no longer read the real values being transfered.

The development defaults option automatically sets the required certificate aliases, and also creates and specifies the login credentials for wsitUser. Static specification of username credentials is not preferred in most security scenarios. For that purpose, you can verify or pass the credentials dynamically using callback handlers. To specify callback handlers, you need to switch the Authentication Credentials combo box from Static to Dynamic, and specify the location of your handler classes. More information about this type of authentication/verification can again be found in the Metro documentation.

Note: You don't need to change your service implementation at all to enable Reliability, Security, or other features!


In this article we tried to show how you can develop web services, from basic web service & client development, to adding more advanced enterprise-class features, in a few clicks. For further reading, I'd recommend NetBeans documentation, tutorials, FAQs, or documents on the Metro website. If you have specific questions or would like to give us feedback, please use the Metro or NetBeans public forums.



Author Bio

Martin Grebac (martin.grebac@sun.com) is a staff engineer at Sun Microsystems, Inc. He worked on JSP debugging and J2EE refactoring features in NetBeans, led Java EE 5 Wed Services efforts in NetBeans 5, and raised WSIT support in later releases. He is a member of GlassFish Web Technologies and Standards team, focusing on Tools integration of web technologies around Project Metro, and involved in other GlassFish integration efforts, such as with Groovy and Grails.

The Java Zone is brought to you in partnership with ZeroTurnaround. Check out this 8-step guide to see how you can increase your productivity by skipping slow application redeploys and by implementing application profiling, as you code!


Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}