SOAP message handlers are used to intercept the SOAP message as they make their way from the client to the end-point service and vice-versa. These handlers intercept the SOAP message for both the request and response of the Web Service. If you are familiar with EJB interceptors, handlers are similar to EJB interceptors and are defined in an XML file.
A few typical scenarios where you would be using SOAP Message handlers are: to encrypt and decrypt messages, to support logging, caching and in some cases auditing, and in rare cases to provide transaction management as well.
So much for the theory. Lets see the three basic steps to use a simple log handler to intercept and print our SOAP messages (request and response).
In this tutorial, we are going to expose an EJB 3 stateless session bean as a web service which is simple and can be done by adding the @WebService annotation. So, here comes the source code for the interface as well as the implementation class which is self explanatory:
Listing 1: Remote Interface
01.
package
com.ws;
02.
03.
import
javax.ejb.Remote;
04.
05.
/**
06.
*
07.
* @author meerasubbarao
08.
*/
09.
@Remote
10.
public
interface
HelloWebServiceRemote {
11.
12.
String sayHello(String name);
13.
14.
}
01.
package
com.ws;
02.
03.
import
javax.ejb.Stateless;
04.
import
javax.jws.WebMethod;
05.
import
javax.jws.WebParam;
06.
import
javax.jws.WebService;
07.
08.
/**
09.
*
10.
* @author meerasubbarao
11.
*/
12.
@WebService
13.
@Stateless
14.
public
class
HelloWebServiceBean
implements
HelloWebServiceRemote {
15.
16.
@WebMethod
(operationName =
"sayHello"
)
17.
public
String sayHello(
@WebParam
(name =
"name"
) String name) {
18.
return
"Hello "
+ name;
19.
}
20.
21.
22.
}
Now that we know our web services work, lets start writing the message handler, which as I said earlier is just 3 steps. So, what are these SOAP message handlers? They are simple Java classes that can used to modify SOAP messages; both request as well as response. These handlers have access to both the SOAP header as well as the body of the message.
Lets move on to create SOAP message handlers:
Step 1. Implement the SOAPHandler interface.
01.
package
com.ws;
02.
03.
import
java.io.IOException;
04.
import
java.util.Collections;
05.
import
java.util.Set;
06.
import
java.util.logging.Level;
07.
import
java.util.logging.Logger;
08.
import
javax.xml.namespace.QName;
09.
import
javax.xml.soap.SOAPException;
10.
import
javax.xml.soap.SOAPMessage;
11.
import
javax.xml.ws.handler.MessageContext;
12.
import
javax.xml.ws.handler.soap.SOAPHandler;
13.
import
javax.xml.ws.handler.soap.SOAPMessageContext;
14.
15.
/**
16.
*
17.
* @author meerasubbarao
18.
*/
19.
public
class
LogMessageHandler
implements
SOAPHandler<SOAPMessageContext> {
20.
21.
public
boolean
handleMessage(SOAPMessageContext messageContext) {
22.
return
true
;
23.
}
24.
25.
public
Set<QName> getHeaders() {
26.
return
Collections.EMPTY_SET;
27.
}
28.
29.
public
boolean
handleFault(SOAPMessageContext messageContext) {
30.
return
true
;
31.
}
32.
33.
public
void
close(MessageContext context) {
34.
}
35.
36.
}
01.
private
void
log(SOAPMessageContext messageContext) {
02.
SOAPMessage msg = messageContext.getMessage();
//Line 1
03.
try
{
04.
msg.writeTo(System.out);
//Line 3
05.
}
catch
(SOAPException ex) {
06.
Logger.getLogger(LogMessageHandler.
class
.getName()).log(Level.SEVERE,
null
, ex);
07.
}
catch
(IOException ex) {
08.
Logger.getLogger(LogMessageHandler.
class
.getName()).log(Level.SEVERE,
null
, ex);
09.
}
10.
}
Invoke this method from within the handleMessage() as shown:
1.
public
boolean
handleMessage(SOAPMessageContext messageContext) {
2.
log(messageContext);
3.
return
true
;
4.
}
Create this XML file in the same package as the web service with the name LogMessage_handler.xml.
01.
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
02.
<
handler-chains
xmlns
=
"http://java.sun.com/xml/ns/javaee"
>
03.
<
handler-chain
>
04.
<
handler
>
05.
<
handler-name
>com.ws.LogMessageHandler</
handler-name
>
06.
<
handler-class
>com.ws.LogMessageHandler</
handler-class
>
07.
</
handler
>
08.
</
handler-chain
>
09.
</
handler-chains
>
1. <handler-chains> is the root element that will contain a list of all handler chains that are defined for the Web Service.
2. The <handler-chain> child element of the <handler-chains> element lists all the handlers in the handler chain.
3. Within the <handler-chain> element is defined the <handler>, each handler element must in turn specify the name and also the fully qualified name of the Java class that implements the handler. If you have more than one handler, specify each one of them within the handler-chain element.
Step 3: Invoking the Handler
The @HandlerChain annotation is used to define a set of handlers that are invoked in response to a SOAP message. So, within our HelloWebServiceBean implementaion, you need to make a simple change to invoke the Log Handler as shown below in Line 1:
01.
package
com.ws;
02.
03.
import
javax.ejb.Stateless;
04.
import
javax.jws.HandlerChain;
05.
import
javax.jws.WebMethod;
06.
import
javax.jws.WebParam;
07.
import
javax.jws.WebService;
08.
09.
/**
10.
*
11.
* @author meerasubbarao
12.
*/
13.
@WebService
14.
@Stateless
15.
@HandlerChain
(file =
"LogMessage_handler.xml"
)
// Line 1
16.
public
class
HelloWebServiceBean
implements
HelloWebServiceRemote {
17.
18.
@WebMethod
(operationName =
"sayHello"
)
19.
public
String sayHello(
@WebParam
(name =
"name"
) String name) {
20.
return
"Hello "
+ name;
21.
}
22.
}
Now invoke the web service from SoapUI and see if it works. If it does, we should be able to see the request and response logged in our GlassFish console window.
Here is the final output:
**RemoteBusinessJndiName: com.ws.CustomerManagerRemote; remoteBusIntf: com.ws.CustomerManagerRemoteIn this article, we saw how simple and easy it was to create and use SOAP Handlers to intercept request and response of SOAP messages. We implemented the SOAPHandler interface, wrote minimal XML to define the handler chain, and finally added one simple annotation to the web service implementation class. We were also able to test these web service using SoapUI.
LDR5010: All ejb(s) of [EJBWebServices] loaded successfully!
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.com/"><soapenv:Header/><soapenv:Body><ws:sayHello>
<name>Javalobby</name>
</ws:sayHello></soapenv:Body></soapenv:Envelope>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:sayHelloResponse xmlns:ns2="http://ws.com/"><return>Hello Javalobby</return></ns2:sayHelloResponse></S:Body></S:Envelope>
Ref: http://java.dzone.com/articles/creating-soap-message-handlers
No comments:
Post a Comment