软件工程实践者

统计

留言簿

友情链结

阅读排行榜

评论排行榜

用Document/literal方式调用web service

Document方式是Web service缺省调用模式,和literal相组合,给我们调用Web service提供了极大的便利,省去了RPC调用方式的复杂类型序列化的问题,所以,Doucment调用方式在BPEL领域应用非常广泛,下面介绍基于Axis利用Document方式来调用一个Web service.

1. Web service准备:
Web service你可以任意实现一个,我是利用Oracle BPEL,通过建立一个BPEL流程,然后把它发布为Web service(具体创建过程省略),这里重要的是Web service的WSDL文件,这是我们调用的门户。
下面是我的Web service的WSDL文件内容:
<definitions
     name="HelloWorld"
     targetNamespace="http://xmlns.oracle.com/HelloWorld"
     xmlns="http://schemas.xmlsoap.org/wsdl/"
     xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/"
     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
     xmlns:client="http://xmlns.oracle.com/HelloWorld"
    >
    <types>
        <schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://xmlns.oracle.com/HelloWorld"
             xmlns="http://www.w3.org/2001/XMLSchema">
            <element name="HelloWorldProcessRequest">
                <complexType>
                    <sequence>
                        <element name="input" type="string"/>
                    </sequence>
                </complexType>
            </element>
            <element name="HelloWorldProcessResponse">
                <complexType>
                    <sequence>
                        <element name="result" type="string"/>
                    </sequence>
                </complexType>
            </element>
        </schema>
    </types>
    <message name="HelloWorldRequestMessage">
        <part name="payload" element="client:HelloWorldProcessRequest"/>
    </message>
    <message name="HelloWorldResponseMessage">
        <part name="payload" element="client:HelloWorldProcessResponse"/>
    </message>
    <portType name="HelloWorld">
        <operation name="process">
            <input message="client:HelloWorldRequestMessage"/>
            <output message="client:HelloWorldResponseMessage"/>
        </operation>
    </portType>
    <binding name="HelloWorldBinding" type="client:HelloWorld">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="process">
            <soap:operation style="document" soapAction="process"/>
            <input>
                <soap:body use="literal"/>
            </input>
            <output>
                <soap:body use="literal"/>
            </output>
        </operation>
    </binding>
    <service name="HelloWorld">
        <port name="HelloWorldPort" binding="client:HelloWorldBinding">
            <soap:address location="http://robin:9700/orabpel/default/HelloWorld/1.0"/>
        </port>
    </service>
  <plnk:partnerLinkType name="HelloWorld">
    <plnk:role name="HelloWorldProvider">
      <plnk:portType name="client:HelloWorld"/>
    </plnk:role>
  </plnk:partnerLinkType>

</definitions>


2. 编写调用类,代码如下:
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.util.Vector;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.rpc.ServiceException;

import org.apache.axis.client.Call;
import org.apache.axis.constants.Style;
import org.apache.axis.message.SOAPBodyElement;
import org.apache.xml.serialize.DOMSerializerImpl;
import org.apache.xml.serialize.OutputFormat;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class BPELServiceTest {
      //service的命名空间
	static final String ns = "http://xmlns.oracle.com/HelloWorld";

	public static void main(String args[]){
		Call call = null;
		try {
			call = createCall();
			Vector rtn = (Vector) call.invoke(createRequest());
			parse(rtn);
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FactoryConfigurationError e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

      /*
* 创建Call对象,对设置相关属性,注意:其中的属性应该是通过分析WSDL文件由程序动态获得来赋值,
* 这里全部简化为静态赋值
*/ static Call createCall() throws MalformedURLException, ServiceException{ org.apache.axis.client.Service s = new org.apache.axis.client.Service(); Call call = (Call) s.createCall(); call.setTargetEndpointAddress(new URL("http://robin:9700/orabpel/default/HelloWorld/1.0")); call.setSOAPActionURI("process"); call.setOperationName("process"); call.setProperty(Call.OPERATION_STYLE_PROPERTY, Style.DOCUMENT.getName()); call.setPortName(new QName(ns, "HelloWorldPort")); call.setPortTypeName(new QName(ns, "HelloWorld")); return call; } /*
       *创建请求参数,实际上就是构建DOM片断,根据Web service对输入参数的要求来构建,要多复杂,都可以实现,
*这就是Docuemnt的好处,省去了复杂对象的序列化。
*/ static Object[] createRequest() throws ParserConfigurationException, FactoryConfigurationError{ DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document doc = db.newDocument(); Element root = doc.createElementNS(ns, "HelloWorldProcessRequest"); Element input = doc.createElementNS(ns, "input"); input.appendChild(doc.createTextNode("robin")); root.appendChild(input); doc.appendChild(root); return new Object[]{new SOAPBodyElement(root)}; } // 对返回结果进行解析,并打印。 static void parse(Vector v) throws Exception{ Document doc = ((SOAPBodyElement) v.get(0)).getAsDocument(); Element root = doc.getDocumentElement(); OutputFormat of = new OutputFormat(); of.setIndent(4); System.out.println(new DOMSerializerImpl().writeToString(root)); } }


上述代码运行输出结果为:
<?xml version="1.0"?>
<HelloWorldProcessResponse xmlns="http://xmlns.oracle.com/HelloWorld">
   <result xmlns="http://xmlns.oracle.com/HelloWorld">robin</result>
  </HelloWorldProcessResponse>


上面的代码很简单,需要说明的是:采用Document调用,实际上invoke方法的参数是一个元素类型为SOAPBodyElement的对象数组,而返回结果是一个元素类型的SOAPBodyElement的Vector对象。

posted on 2006-01-02 22:09 软件工程实践者 阅读(5767) 评论(2)  编辑  收藏 所属分类: Web service

评论

# re: 用Document/literal方式调用web service 2006-07-05 11:59 QQ:55683633

但如果当同一个portType里有两个或多个operation时,这就会出问题了,
只会调用类里的位置最顶的第一个方法,注意那方法参数也是Document的.
请问如何解决.??  回复  更多评论   

# re: 用Document/literal方式调用web service 2006-11-17 13:46 人生是由回忆组成的

不是可以指定operation name吗?
你可以试一试。  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航: