📄 soapclient.java
字号:
/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the JBPM BPEL PUBLIC LICENSE AGREEMENT as
* published by JBoss Inc.; either version 1.0 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
package org.jbpm.bpel.integration.client;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.wsdl.Binding;
import javax.wsdl.BindingFault;
import javax.wsdl.BindingInput;
import javax.wsdl.BindingOperation;
import javax.wsdl.BindingOutput;
import javax.wsdl.Fault;
import javax.wsdl.Message;
import javax.wsdl.Operation;
import javax.wsdl.Part;
import javax.wsdl.Port;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.wsdl.extensions.soap.SOAPBinding;
import javax.wsdl.extensions.soap.SOAPFault;
import javax.wsdl.extensions.soap.SOAPOperation;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Element;
import com.ibm.wsdl.extensions.soap.SOAPConstants;
import org.jbpm.bpel.BpelException;
import org.jbpm.bpel.graph.exe.BpelFaultException;
import org.jbpm.bpel.graph.exe.FaultInstance;
import org.jbpm.bpel.variable.def.MessageType;
import org.jbpm.bpel.variable.exe.MessageValue;
import org.jbpm.bpel.wsdl.util.WsdlUtil;
import org.jbpm.bpel.xml.util.XmlUtil;
/**
* @author Alejandro Gu韟ar
* @version $Revision: 1.6 $ $Date: 2007/01/18 14:22:16 $
*/
public class SoapClient {
private final Binding binding;
private final URL address;
private static final Log log = LogFactory.getLog(SoapClient.class);
public SoapClient(Port port) {
binding = port.getBinding();
SOAPBinding soapBinding = (SOAPBinding) WsdlUtil.getExtension(
binding.getExtensibilityElements(), SOAPConstants.Q_ELEM_SOAP_BINDING);
// exclude non-soap bindings
if (soapBinding == null) {
throw new IllegalArgumentException("non-soap bindings not supported: "
+ binding);
}
// exclude non-http transport protocols
String transport = soapBinding.getTransportURI();
if (!SoapBindConstants.HTTP_TRANSPORT_URI.equals(transport)) {
throw new IllegalArgumentException("non-http transports not supported: "
+ transport);
}
// exclude non-soap ports
SOAPAddress soapAddress = (SOAPAddress) WsdlUtil.getExtension(
port.getExtensibilityElements(), SOAPConstants.Q_ELEM_SOAP_ADDRESS);
if (soapAddress == null) {
throw new BpelException("non-soap ports not supported: " + port);
}
// exclude non-url address locations
String location = soapAddress.getLocationURI();
try {
address = new URL(location);
}
catch (MalformedURLException e) {
throw new BpelException("invalid address location: " + location, e);
}
}
public Map call(String operation, Map inputParts) throws BpelFaultException {
try {
SOAPMessage soapOutput = callImpl(operation, inputParts);
// prepare output message
SOAPEnvelope envelope = soapOutput.getSOAPPart().getEnvelope();
if (envelope.getBody().hasFault()) {
FaultInstance faultInstance = readFault(operation, envelope);
throw new BpelFaultException(faultInstance);
}
return readMessage(operation, envelope);
}
catch (SOAPException e) {
throw new BpelException("failed to call soap endpoint: " + getAddress(),
e);
}
}
public void callOneWay(String operation, Map inputParts) {
try {
callImpl(operation, inputParts);
}
catch (SOAPException e) {
throw new BpelException("failed to call soap endpoint: " + getAddress(),
e);
}
}
private URL getAddress() {
return address;
}
protected SOAPMessage callImpl(String operation, Map inputParts)
throws SOAPException {
// prepare input message
SOAPMessage soapInput = writeMessage(operation, inputParts);
// call endpoint
SOAPConnection soapConnection = SOAPConnectionFactory.newInstance()
.createConnection();
try {
return soapConnection.call(soapInput, getAddress());
}
finally {
try {
soapConnection.close();
}
catch (SOAPException e) {
log.warn("coult not close soap connection", e);
}
}
}
public Binding getBinding() {
return binding;
}
public SOAPMessage writeMessage(String operation, Map inputParts)
throws SOAPException {
BindingOperation bindOperation = binding.getBindingOperation(operation,
null, null);
// create soap message
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
// obtain info on the operation as a whole
SOAPOperation soapOperation = (SOAPOperation) WsdlUtil.getExtension(
bindOperation.getExtensibilityElements(),
SOAPConstants.Q_ELEM_SOAP_OPERATION);
// set the value of the SOAPAction HTTP header
String action = soapOperation.getSoapActionURI();
soapPart.setMimeHeader(SoapBindConstants.SOAP_ACTION_HEADER, action);
// determine whether the operation is rpc-oriented or document-oriented
String style = soapOperation.getStyle();
if (style == null) {
// default to the value specified in the soap:binding element
SOAPBinding soapBinding = (SOAPBinding) WsdlUtil.getExtension(
getBinding().getExtensibilityElements(),
SOAPConstants.Q_ELEM_SOAP_BINDING);
style = soapBinding.getStyle();
if (style == null) {
// if the soap:binding element does not specify a style, 'document' is
// assumed
style = SoapBindConstants.DOCUMENT_STYLE;
}
}
SOAPEnvelope envelope = soapPart.getEnvelope();
// write body element
if (SoapBindConstants.DOCUMENT_STYLE.equals(style)) {
writeDocumentBody(bindOperation, inputParts, envelope);
}
else {
writeRpcBody(bindOperation, inputParts, envelope);
}
return soapMessage;
}
protected void writeRpcBody(BindingOperation bindOperation, Map inputParts,
SOAPEnvelope envelope) throws SOAPException {
// obtain info on how message parts appear inside the body element
BindingInput bindInput = bindOperation.getBindingInput();
javax.wsdl.extensions.soap.SOAPBody soapBody = (javax.wsdl.extensions.soap.SOAPBody) WsdlUtil.getExtension(
bindInput.getExtensibilityElements(), SOAPConstants.Q_ELEM_SOAP_BODY);
// exclude the use of encodings
if (SoapBindConstants.ENCODED_USE.equals(soapBody.getUse())) {
throw new BpelException("encoded use not supported");
}
// obtain the definitions of parts which appear inside the body, in
// parameter order
List partNames = soapBody.getParts();
Operation operation = bindOperation.getOperation();
List parameterOrder = operation.getParameterOrdering();
if (parameterOrder != null) {
if (partNames != null) {
// retain only parts specified by soap:body keeping the parameter order
parameterOrder = new ArrayList(parameterOrder);
parameterOrder.retainAll(partNames);
}
partNames = parameterOrder;
}
Message message = operation.getInput().getMessage();
// the message filters out parts that it does not define
Collection parts = getParts(message, partNames);
// create operation wrapper
Name operationName = envelope.createName(bindOperation.getName(),
"soapBodyNS", soapBody.getNamespaceURI());
SOAPBodyElement operationElem = envelope.getBody().addBodyElement(
operationName);
// fill in part values
Iterator partIt = parts.iterator();
while (partIt.hasNext()) {
Part part = (Part) partIt.next();
String partName = part.getName();
// create part accessor under operation wrapper
SOAPElement operPartAccessor = XmlUtil.addChildElement(operationElem,
partName);
// get part accessor from input message data
Element inputPartAccessor = (Element) inputParts.get(partName);
// copy input part to operation part
XmlUtil.copy(operPartAccessor, inputPartAccessor);
}
}
protected void writeDocumentBody(BindingOperation bindOperation,
Map inputParts, SOAPEnvelope envelope) throws SOAPException {
// obtain info on how message parts appear inside the body element
BindingInput bindInput = bindOperation.getBindingInput();
javax.wsdl.extensions.soap.SOAPBody soapBody = (javax.wsdl.extensions.soap.SOAPBody) WsdlUtil.getExtension(
bindInput.getExtensibilityElements(), SOAPConstants.Q_ELEM_SOAP_BODY);
// exclude the use of encodings
if (SoapBindConstants.ENCODED_USE.equals(soapBody.getUse())) {
throw new BpelException("encoded use not supported");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -