-
1. Re: Websphere and Webservice: No Seam context, SOAPHandler not called
tigerblue Jul 12, 2011 7:55 AM (in response to tigerblue)Got it working for my simple example.
It looks like Websphere (v7) requires handlers to be implementing the old (Java 1.4?) interface: javax.xml.rpc.handler.Handler.
Seam uses the newer javax.xml.ws.handler.Handler for SOAPRequestHandler. They are unfortunately not compatible.So basically I have rewritten the SOAPRequestHandler for Websphere and the older handler interface.
Also I only found one location where Websphere accepted my handler definition: That is in the webservices.xml inside the port-component.
It looks like this:<handler> <handler-name>Websphere Seam Bridge Handler</handler-name> <handler-class>de.some.path.WebsphereSeamSoapHandler</handler-class> </handler>
My handler class looks like this:
package de.some.path.; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.xml.namespace.QName; import javax.xml.rpc.handler.HandlerInfo; import javax.xml.soap.SOAPElement; import javax.xml.soap.SOAPEnvelope; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPHeader; import org.jboss.seam.contexts.Lifecycle; import org.jboss.seam.contexts.ServletLifecycle; import org.jboss.seam.core.ConversationPropagation; import org.jboss.seam.core.Manager; import org.jboss.seam.log.LogProvider; import org.jboss.seam.log.Logging; import org.jboss.seam.servlet.ServletRequestSessionMap; import org.jboss.seam.web.ServletContexts; // javax.xml.rpc.handler.Handler is taken from j2ee.jar from Websphere public class WebsphereSeamSoapHandler implements javax.xml.rpc.handler.Handler { public static final QName CIDQN = new QName("http://www.jboss.org/seam/webservice", "conversationId", "seam"); private static final LogProvider log = Logging.getLogProvider(WebsphereSeamSoapHandler.class); private Set<QName> headers = new HashSet<QName>(); private String handlerName; @Override public boolean handleRequest(javax.xml.rpc.handler.MessageContext rpcContext) { // It is a javax.xml.rpc.handler.soap.SOAPMessageContext try { HttpServletRequest request = (HttpServletRequest)rpcContext.getProperty("transport.http.servletRequest"); // Only for newer version of Seam? //ServletLifecycle.beginRequest(request, ServletLifecycle.getServletContext()); ServletLifecycle.beginRequest(request); ServletContexts.instance().setRequest(request); String conversationId = extractConversationId(rpcContext); ConversationPropagation.instance().setConversationId( conversationId ); Manager.instance().restoreConversation(); ServletLifecycle.resumeConversation(request); return true; } catch (SOAPException ex) { log.error("Error handling inbound SOAP request", ex); return false; } } @Override public boolean handleResponse(javax.xml.rpc.handler.MessageContext rpcContext) { try { HttpServletRequest request = (HttpServletRequest)rpcContext.getProperty("transport.http.servletRequest"); String conversationId = Manager.instance().getCurrentConversationId(); if (conversationId != null) { javax.xml.rpc.handler.soap.SOAPMessageContext smc = (javax.xml.rpc.handler.soap.SOAPMessageContext)rpcContext; SOAPHeader header = smc.getMessage().getSOAPHeader(); if (header != null) { SOAPElement element = header.addChildElement(CIDQN); element.addTextNode(conversationId); smc.getMessage().saveChanges(); } else { SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope(); header = envelope.addHeader(); SOAPElement element = header.addChildElement(CIDQN); element.addTextNode(conversationId); smc.getMessage().saveChanges(); } } Manager.instance().endRequest(new ServletRequestSessionMap(request)); return true; } catch (SOAPException ex) { log.error("Exception processing outbound message", ex); return false; } } @Override public boolean handleFault(javax.xml.rpc.handler.MessageContext rpcContext) { return true; } @Override public void init(HandlerInfo arg0) { } @Override public void destroy() { Lifecycle.endRequest(); } @Override public QName[] getHeaders() { QName[] aHeaders = new QName[headers.size()]; headers.toArray(aHeaders); return aHeaders; } public void setHeaders(Set<QName> headers) { this.headers = headers; } public String getHandlerName() { return handlerName; } public void setHandlerName(String handlerName) { this.handlerName = handlerName; } @Override public String toString() { return (handlerName != null ? handlerName : super.toString()); } private String extractConversationId( javax.xml.rpc.handler.MessageContext messageContext) throws SOAPException { javax.xml.rpc.handler.soap.SOAPMessageContext smc = (javax.xml.rpc.handler.soap.SOAPMessageContext) messageContext; SOAPHeader header = smc.getMessage().getSOAPHeader(); if (header != null) { Iterator iter = header.getChildElements(CIDQN); if (iter.hasNext()) { SOAPElement element = (SOAPElement) iter.next(); return element.getFirstChild().getNodeValue(); } } return null; } }
This is the log file entry that finally gave me some hint about what to do. It does not appear very often:
WSDDJAXRPCHan E com.ibm.ws.webservices.engine.deployment.wsdd.WSDDJAXRPCHandlerInfo getJavaClass WSWS3123E: Fehler: Die Java-Klasse de.some.path.DebugHandler, die für Handler null angegeben ist, muss javax.xml.rpc.handler.Handler oder com.ibm.wsspi.webservices.rpc.handler.HandlerClassFactory implementieren. Der Handler wird übersprungen.
After that I did find a respective documentation entry for Websphere 7...
-
2. Re: Websphere and Webservice: No Seam context, SOAPHandler not called
tigerblue Aug 8, 2011 10:48 AM (in response to tigerblue)On a side note: the whole business was finally solved/implemented with using JAXWS for Websphere (and the command endptEnabler).