For example to add WS-Addressing, XML Digital Signature and/or XML Encryption (see this post: Preparing for SCDJWS Part 18: XML Digital Signature and XML Encryption), or any other additional processing of messages (business or not).
JAX-WS defines two types of handlers: logical (only payload is available to handler) and protocol (complete SOAP message is available to handler).
Rule of a thumb:
When the message is outbound first logical handlers are applied then protocol ones.
When the message is inbound first the protocol handlers are applied and then logical ones.
Let's get to examples.
JAX-WS Logical Handler example
public class LogicalHandler implements javax.xml.ws.handler.LogicalHandler<LogicalMessageContext> {
public void close(MessageContext context) {
}
public boolean handleFault(LogicalMessageContext context) {
return false;
}
public boolean handleMessage(LogicalMessageContext context) {
String message = null;
try {
Source source = context.getMessage().getPayload();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Result result = new StreamResult(baos);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(source, result);
message = baos.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
System.out.println("logical handler ==> " + message);
return true;
}
}JAX-WS Protocol Handler examplepublic class LoggingHandler implements SOAPHandler<SOAPMessageContext> {
public void close(MessageContext context) {
}
public boolean handleFault(SOAPMessageContext context) {
return false;
}
public boolean handleMessage(SOAPMessageContext context) {
Boolean outbound = (Boolean) context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY);
System.out.println("SOAP handler outbound is set to ==> " + outbound);
String message = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
context.getMessage().writeTo(baos);
message = baos.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
System.out.println(message);
return true;
}
public Set<QName> getHeaders() {
return Collections.emptySet();
}
}JAX-WS Java EE XML descriptorThe most convenient way, and the only one available for server-side handlers, is to create Java EE XML descriptor. The file, let's say
handlers.xml, could look like this:<?xml version="1.0" encoding="UTF-8"?> <handler-chains xmlns="http://java.sun.com/xml/ns/javaee"> <handler-chain> <handler> <handler-name>L1</handler-name> <handler-class>org.xh.studies.ws.secure_web_service.LogicalHandler </handler-class> </handler> <handler> <handler-name>P1</handler-name> <handler-class>org.xh.studies.ws.secure_web_service.LoggingHandler </handler-class> </handler> <handler> <handler-name>L2</handler-name> <handler-class>org.xh.studies.ws.secure_web_service.LogicalHandler </handler-class> </handler> </handler-chain> </handler-chains>Using JAX-WS handlers on the client-side
If you generate client stubs using
wsimport tool the simplest way is to add @HandlerChain annotation to the Service class:@HandlerChain(file="handlers.xml")
@WebServiceClient(name = "HiHeyHelloWebServiceService", targetNamespace = "http://secure_web_service.ws.studies.xh.org/", wsdlLocation = "http://localhost/secure-web-service/HiHeyHelloWebServiceService?wsdl")
public class HiHeyHelloWebServiceService extends Service {
/* ... */
}Or, without any XML descriptors, using HandlerResolver interface:service.setHandlerResolver(new HandlerResolver() {
public List<Handler> getHandlerChain(PortInfo portInfo) {
List<Handler> handlers = new ArrayList<Handler>();
handlers.add(new LoggingHandler());
handlers.add(new LogicalHandler());
return handlers;
}
});Using JAX-WS handlers on the server-sideOn the server side, you can add
@HandlerChain to @WebService or @WebServiceProvider annotated classes. Or you can add <handler-chain /> element directly into webservices.xml deployment descriptor.Example output
Here is example output I get when running one of my Web Services:
logical handler ==> <?xml version="1.0" encoding="UTF-8" standalone="no"?><ns2:sayHiHeyHello xmlns:ns2="http://secure_web_service.ws.studies.xh.org/"><arg0>Lukasz</arg0></ns2:sayHiHeyHello> logical handler ==> <?xml version="1.0" encoding="UTF-8" standalone="no"?><ns2:sayHiHeyHello xmlns:ns2="http://secure_web_service.ws.studies.xh.org/"><arg0>Lukasz</arg0></ns2:sayHiHeyHello> SOAP handler outbound is set to ==> true <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Header><To xmlns="http://www.w3.org/2005/08/addressing">https://localhost/secure-web-service/HiHeyHelloWebServiceService</To><Action xmlns="http://www.w3.org/2005/08/addressing">http://secure_web_service.ws.studies.xh.org/HiHeyHelloWebService/sayHiHeyHelloRequest</Action><ReplyTo xmlns="http://www.w3.org/2005/08/addressing"> <Address>http://www.w3.org/2005/08/addressing/anonymous</Address> </ReplyTo><MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:45e01c7c-3c2a-4f23-abfe-13a3a61ed449</MessageID></S:Header><S:Body><ns2:sayHiHeyHello xmlns:ns2="http://secure_web_service.ws.studies.xh.org/"><arg0>Lukasz</arg0></ns2:sayHiHeyHello></S:Body></S:Envelope> SOAP handler outbound is set to ==> false <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header/><soapenv:Body><ns2:sayHiHeyHelloResponse xmlns:ns2="http://secure_web_service.ws.studies.xh.org/"><return>Hi, hey, hello Lukasz! You have invoked me as 'system' and I think you are in admin role: true</return></ns2:sayHiHeyHelloResponse></soapenv:Body></soapenv:Envelope> logical handler ==> <?xml version="1.0" encoding="UTF-8"?><ns2:sayHiHeyHelloResponse xmlns:ns2="http://secure_web_service.ws.studies.xh.org/"><return>Hi, hey, hello Lukasz! You have invoked me as 'system' and I think you are in admin role: true</return></ns2:sayHiHeyHelloResponse> logical handler ==> <?xml version="1.0" encoding="UTF-8"?><ns2:sayHiHeyHelloResponse xmlns:ns2="http://secure_web_service.ws.studies.xh.org/"><return>Hi, hey, hello Lukasz! You have invoked me as 'system' and I think you are in admin role: true</return></ns2:sayHiHeyHelloResponse>Summary
My next post about SCDJWS will be about exceptions and faults handling.
Stay tuned,
Łukasz

2 comments:
My name is Marie and I am new in developing web services. I am trying to secure webservices wit SSL (Keystore + Truststore). I am using Eclipse+Glassfish+Metro . I have foung some prety tutorials for Netbeans but not for Eclipse.
Is thre any?? I wasn't successful so far.
I have read and used Your great site about "Using OpenSSL to create certificates for Metro " Thanks a lot !!!!
Using SSL in web servise I need to retrieve some infomation about the client(certificate) when "building" the trusted connection. Maybe using some Callbackhandler , Request , Principal class.... I don't know yet exactly how I can retrieve information (Cert X.509) about the user.
So I think I should use Metro WSIT to do that.
Do You know maybe is there any page(procedure) with any example how to do that ??
How to use WSIT with Glassfish in Eclipse (webservice and client in Java)??? Please !!!
I would be VERY thankful for any help.
Thank You in advance.
Best regards , Marie
I am very much new in developing web services..I got very less from the code you explained in post. Can you please describe me briefly about each line. It would be really helpful for me. Thanks in advance.
Post a Comment