In the following code sample a document-oriented web service passing an XML document (message-style) web service is processed by a custom provider to allow for default credentials to be set based on the operation name.
package webservice; import curam.util.connectors.webservice.CuramMsgStyleEJBMethodProvider; import java.util.Vector; import javax.xml.namespace.QName; import org.apache.axis.AxisFault; import org.apache.axis.Handler; import org.apache.axis.MessageContext; import org.apache.axis.description.OperationDesc; import org.apache.axis.description.ServiceDesc; import org.apache.axis.handlers.soap.SOAPService; import org.apache.axis.i18n.Messages; import org.apache.axis.message.MessageElement; import org.apache.axis.message.SOAPEnvelope; /** * A web services hook which extends the Curam message style * provider to enable the developer to do custom processing for * properties and then pass control to the Curam handler. */ public class CustomMsgStyleMethodProvider extends CuramMsgStyleEJBMethodProvider { /** * Process the message: Ensure the interface method matches * the supported Curam message style signature: * [public Document doSomething (Document xmlMessage)]. * * Parse the SOAP body XML message into a Document object, * strip the root wrapper element, do the actual invocation * and restore the root wrapper element before responding. * * @param msgContext the active MessageContext * @param reqEnv the request SOAPEnvelope * @param resEnv the response SOAPEnvelope * @param obj the service target object * @throws Exception exception */ @Override public void processMessage(final MessageContext msgContext, final SOAPEnvelope reqEnv, final SOAPEnvelope resEnv, final Object obj) throws Exception { try { OperationDesc operation = msgContext.getOperation(); final SOAPService serviceHandler = msgContext.getService(); final ServiceDesc serviceDesc = serviceHandler.getServiceDescription(); QName opQName = null; // If operation not in the context extract from the // SOAP envelope. if (operation == null) { final Vector bodyElements = reqEnv.getBodyElements(); if (bodyElements.size() > 0) { final MessageElement element = (MessageElement) bodyElements.get(0); if (element != null) { opQName = new QName( element.getNamespaceURI(), element.getLocalName()); operation = serviceDesc.getOperationByElementQName(opQName); } } } // Cannot proceed without an operation name. if (operation == null) { throw new AxisFault(Messages.getMessage("noOperationForQName", opQName == null ? "null" : opQName.toString())); } // If this is a "public" operation we ensure // default credentials are supplied. if ("public_operation".equals(opQName.toString())) { final String jndiUserName = "jndiUser"; String jndiUser = (serviceHandler != null) ? (String) serviceHandler.getOption(jndiUserName) : (String) getOption(jndiUserName); if (jndiUser == null || jndiUser.length() == 0) { serviceHandler.setOption(jndiUserName, "default"); final String jndiPasswordName = "jndiPassword"; serviceHandler.setOption(jndiPasswordName, "password"); } } msgContext.setService(serviceHandler); // Process the message super.processMessage(msgContext, reqEnv, resEnv, obj); } catch (Exception e) { e.printStackTrace(); throw e; } } }
A custom message-style handler could also be used to intercept the (W3C) Document in the SOAP message to inspect and modify as the following illustrates:
package webservice; import curam.util.exception.AppException; import curam.util.message.INFRASTRUCTURE; import curam.util.webservices.MessageProcessor; import java.lang.reflect.Method; import java.util.Vector; import javax.xml.namespace.QName; import org.apache.axis.AxisFault; import org.apache.axis.MessageContext; import org.apache.axis.description.OperationDesc; import org.apache.axis.description.ServiceDesc; import org.apache.axis.handlers.soap.SOAPService; import org.apache.axis.i18n.Messages; import org.apache.axis.message.MessageElement; import org.apache.axis.message.SOAPBodyElement; import org.apache.axis.message.SOAPEnvelope; import org.w3c.dom.Document; import org.w3c.dom.Node; /** * */ public class CustomMsgStyleMethodProvider extends CuramMsgStyleEJBMethodProvider { /** * Process the message: Ensure the interface method matches * the supported Curam message style: * [public Document doSomething (Document xmlMessage)]. * * Parse the SOAP body XML message in to a Document object, * strip the root wrapper element, do the actual invocation * and restore the root wrapper element before responding. * * @param msgContext the active MessageContext * @param reqEnv the request SOAPEnvelope * @param resEnv the response SOAPEnvelope * @param obj the service target object * @throws Exception exception */ @Override public void processMessage(final MessageContext msgContext, final SOAPEnvelope reqEnv, final SOAPEnvelope resEnv, final Object obj) throws Exception { OperationDesc operation = msgContext.getOperation(); final SOAPService service = msgContext.getService(); final ServiceDesc serviceDesc = service.getServiceDescription(); QName opQName = null; // If operation not in the context extract from the // SOAP envelope. if (operation == null) { final Vector bodyElements = reqEnv.getBodyElements(); if (bodyElements.size() > 0) { final MessageElement element = (MessageElement) bodyElements.get(0); if (element != null) { opQName = new QName( element.getNamespaceURI(), element.getLocalName()); operation = serviceDesc.getOperationByElementQName(opQName); } } } // Cannot proceed without an operation name. if (operation == null) { throw new AxisFault(Messages.getMessage("noOperationForQName", opQName == null ? "null" : opQName.toString())); } final Method method = operation.getMethod(); final int methodType = operation.getMessageOperationStyle(); if (methodType == OperationDesc.MSG_METHOD_DOCUMENT) { // Dig out the body XML and invoke method. final Vector bodies = reqEnv.getBodyElements(); Document doc = ((SOAPBodyElement) bodies.get(0)).getAsDocument(); // Preserve wrapper root element, and then remove it. final Node root = doc.getDocumentElement(); doc = MessageProcessor.removeWrapperElement(doc); // ******************************** // Custom Document processing here. // ******************************** // ... // Add XML to arg for invocation. final Object[] argObjects = new Object[1]; argObjects[0] = doc; // Do the actual invocation of EJB method. // TODO: instantiate your own provider instead // of CuramEJBMethodProvider. final CuramEJBMethodProvider ejbMP = new CuramEJBMethodProvider(); Document resultDoc = (Document) ejbMP. invokeMethod(msgContext, method, obj, argObjects); // Add return XML to SOAP response if (resultDoc != null) { // Restore the wrapper root element that // was removed above. resultDoc = MessageProcessor. restoreWrapperElement(root, resultDoc); resEnv.addBodyElement( new SOAPBodyElement(resultDoc.getDocumentElement())); } return; } } }