Accessing Web Services from JSF

1) Introduction

In this technical article, let us see how it is possible to access Web Services from JSF Applications. JSF Application resides in the Web Tier of a typical Enterprise Application, whereas Web Services are External Services that reside in the Application Tier. We make use of Java EE 5 for developing the Sample Application in the final section of this article. It is assumed that readers have sufficient knowledge of JSF and Web Services before continuing this article. They also can have a glance over the introductory JavaBeat article on Java Server Faces before proceeding with this.

2) Web Services
2.1) Introduction


Web Services have been there in the software market over a decade of years and they are gaining more popularity in the recent years. Web Services provide an integration layer between two heterogeneous Applications. With Web Services, it is now possible to access a Java Application that is running in some remote machine with the client being any of the compliant languages like C, C++ or C#. This ensures that Web Services promote language interoperability. It is not necessary that both the Server and Client Application must be running in the same platform, thereby making it platform independent. Web Services alone is not a standard, instead it is a combination of several standards like SOAP, WSDL etc.
2.2) SOAP

SOAP stands for Simple Object Access Protocol and this is used in Web Services for transmitting messages between the Client and the Server. Technically, a SOAP message is in Xml format that conforms to a well defined schema. It means that a Client Application will construct its request in a SOAP message and send the message to the Server. The Server after unpacking the SOAP message will analyze the type of request and will return a suitable response in the form of a SOAP message.

Given below is a sample illustrating the structure of a Sample SOAP message,
<span style="font-weight: bold;">soap.xml</span>


<soap:envelope soap="http://schemas.xmlsoap.org/soap/envelope/">

<soap:header>
...
</soap:header>

<soap:header>
...
</soap:header>

<soap:body mydata="http://mydata.com">
</soap:body>

</soap:envelope>

The SOAP message has an outer core called the SOAP Envelope followed by optional SOAP Headers. Following the SOAP Headers is the SOAP Body which will contain the Application that needs to be processed.

2.3) WSDL

WSDL stands for Web Service Description Language and this is the Client facing interface for accessing the Web Service. A typical WSDL file, which is also in Xml format, will list down all the possible Web Service that can be accessed over the Internet. Not only it will list down all the Web Services, but also the various supported operations that a particular Web Service will support.


3) Using Web Services in JSF Application
3.1) Introduction


In this section, let us develop a Simple Hello Web Service that can be accessed by a JSF Application. As we are aware that in a JSF Application, the business processing is usually done by the Managed Beans. It is also possible that a Managed Bean can delegate its functionality to an External Service like an Enterprise Bean or a Web Service.

3.2) Coding the Hello Web Service

HelloWebService.java


package hello;

import javax.jws.HandlerChain;
import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService()
@HandlerChain(file = "HelloWebService_handler.xml")
public class HelloWebService
{
@WebMethod
public String sayHello()
{
return "Hello";
}
}

The above code defines a Hello Web Service by name 'HelloWebService'. Since the Application is developed using J2EE 5.0 standard, we have taken the full utilization of Annotation for annotating our declarations. Let us get into the details now. To qualify an implementation class as a Web Service we have simply used the Annotation 'WebService'. That is all which is needed for the Application Server to treat this class as a Web Service. Let us look into the Handler Chain in the next section. To qualify an operation as a Web Service operation, we have to use the Annotation 'WebMethod'.

3.2) Handler Chains

It is possible to attach any number of Handler Chains for a Web Service. To say in simple words, a Handler Chain defines the sequence of steps that used to happen when the request from the Client (in the form of SOAP message), after passing through the various nodes, goes to the ultimate Server for getting processed. Since a Handler Chain is not dependent of the type of the protocol used, we can define a handler Chain for any protocol. Just to make use of the Handler Chain in this Application, we have defined Custom Handler Chain and have referenced the same in the Hello Web Service with the help of HandlerChain Annotation.

Given below is the declaration of a Simple Standard Chain,

HelloMH.java


package hello;

import java.util.Collections;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

public class HelloMH implements SOAPHandler
{
public boolean handleMessage(SOAPMessageContext messageContext)
{
SOAPMessage msg = messageContext.getMessage();
return true;
}

public Set getHeaders()
{
return Collections.EMPTY_SET;
}

public boolean handleFault(SOAPMessageContext messageContext)
{
return true;
}

public void close(MessageContext context)
{
}
}

The definition of the Handler Chain is defined in the following Xml file and this Xml file is referenced in the HandlerChain Annotation while defining the Web Service.

HelloWebService_handler.xml



<?xml version="1.0" encoding="UTF-8"?>

<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
<handler-chain>
<handler>
<handler-name>hello.HelloMH</handler-name>
<handler-class>hello.HelloMH</handler-class>
</handler>
</handler-chain>

</handler-chains>

3.3) Hello WSDL File

As mentioned earlier, a WSDL contains the definitions for various Web Services along with its supported operation. Precisely, all the request and the response data from the Client and the Server will be modeled as messages in the WSDL file. A port type is a WSDL file which defines a set of operations along with the input and the output messages that they will take. Having defined about the various operations along with its messages, how they are bound with a specific protocol is defined by the 'binding' element. Finally the 'service' element along with its 'port' and the 'address' elements will define the ports that are accessible by the clients and the URL through which these Web Services can be invoked.

The following code snippet is the definition of the Hello WSDL file,

HelloWebServiceService.wsdl

<?xml version="1.0" encoding="UTF-8"?>

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://hello/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://hello/" name="HelloWebServiceService">

<types>
<xsd:schema>
<xsd:import namespace="http://hello/" schemaLocation="HelloWebServiceService_schema.xsd" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"/>
</xsd:schema>
</types>

<message name="sayHello">
<part name="parameters" element="tns:sayHello"/>
</message>
<message name="sayHelloResponse">
<part name="parameters" element="tns:sayHelloResponse"/>
</message>

<portType name="HelloWebService">
<operation name="sayHello">
<input message="tns:sayHello"/>
<output message="tns:sayHelloResponse"/>
</operation>
</portType>

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

<service name="HelloWebServiceService">
<port name="HelloWebServicePort" binding="tns:HelloWebServicePortBinding">
<soap:address location="http://indpd218:8080/HelloWS/HelloWebServiceService" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"/>
</port>
</service>

</definitions>



3.4) JSF Managed Bean

HelloManagedBean.java


package hello;
public class HelloManagedBean {

public HelloManagedBean()
{
}

public void callWebService()
{
try
{
hello.client.HelloWebServiceService service =
new hello.client.HelloWebServiceService();
hello.client.HelloWebService port =
service.getHelloWebServicePort();

java.lang.String result = port.sayHello();
System.out.println("Result = "+result);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

A JSF Managed Bean will be triggered whenever an Event happens in the Client side like the Click of a Button, or hyperlink etc. So, invoking the business logic defined for the Web Service in this place will be more ideal. In the above Managed Bean, we have defined a method called callWebService() within which we have coded the logic for accessing the Web Service. Note the usage of the classes HelloWebServiceService and HelloWebService. The classes (or Web Service skeletons) will be generated by a standard IDE (like NetBeans) when given with a WSDL file.
3.5) JSF Configuration File

The following is the definition of the HelloManagedBean that we saw just now. We have given an identifier called 'helloManagedBean' through the attribute 'managed-bean-name' element. Note that the 'managed-bean-class' element should point to the fully qualified name of the Managed Bean.

faces-config.xml







helloManagedBean
hello.HelloManagedBean
request




3.6) Accessing the Web Service

index.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Accessing Web Services from JavaServer Faces</title>
</head>

<body>
<f:view>
<h1>
<h:outputText value="Accessing Web Services from JavaServer Faces" />
</h1>

<h:commandButton value = "Invoke Web Service"
action = "#{helloManagedBean.callWebService}">
</h:commandButton>

</f:view>
</body>

</html>

Since we have wrapped the Hello Web Service within the Managed Bean declaration, invoking the Web Service becomes as easy as defining the JSF Method Expression. In the above code snippet, we have defined a Command Button and the value of the 'action' attribute is pointing to '#{helloManagedBean.callWebService}'

4) Conclusion

This article had guided in using External Services like Web Services from JSF Applications. It initially went through Web Services explaining the various standards related to Web Services like SOAP and WSDL. Then the later half of the article showed the steps involved in integration Web Services in a JSF Application.

0 comments: