软件工程实践者

统计

留言簿

友情链结

阅读排行榜

评论排行榜

#

JavaScript调用Web service

要调用的Web服务是求两个整数和,并返回结果。

服务的WSDL文件内容如下:
<?xml version="1.0" encoding="utf-8" ?> 
<wsdl:definitions
    xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:s="http://www.w3.org/2001/XMLSchema" 
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:tns="http://tempuri.org/"  
    xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" 
    xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" 
    targetNamespace="http://tempuri.org/" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <wsdl:types>
     <s:schema elementFormDefault="qualified"  
        targetNamespace="http://tempuri.org/">
        <s:element name="AddTwoIntegers">
            <s:complexType>
               <s:sequence>  
                  <s:elementminOccurs="1" maxOccurs="1" name="IntegerOne" type="s:int" />    
                  <s:elementminOccurs="1" maxOccurs="1" name="IntegerTwo" type="s:int" />   
               </s:sequence>
            </s:complexType>
        </s:element>
        <s:element name="AddTwoIntegersResponse">
            <s:complexType>
                <s:sequence> 
                   <s:elementminOccurs="1" maxOccurs="1" name="AddTwoIntegersResult" type="s:int" />    
                </s:sequence>
            </s:complexType>
        </s:element>
     </s:schema>
  </wsdl:types>
  <wsdl:message name="AddTwoIntegersSoapIn"> 
      <wsdl:part name="parameters" element="tns:AddTwoIntegers" />
  </wsdl:message>
  <wsdl:message name="AddTwoIntegersSoapOut">  
      <wsdl:part name="parameters" element="tns:AddTwoIntegersResponse" />   
   </wsdl:message>
   <wsdl:portType name="SimpleServiceSoap">
       <wsdl:operation name="AddTwoIntegers">
          <wsdl:input message="tns:AddTwoIntegersSoapIn" />
          <wsdl:output message="tns:AddTwoIntegersSoapOut" />    
       </wsdl:operation> 
   </wsdl:portType>

   <wsdl:binding name="SimpleServiceSoap" type="tns:SimpleServiceSoap"> 
       <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> 
       <wsdl:operation name="AddTwoIntegers">   
           <soap:operation soapAction="http://tempuri.org/AddTwoIntegers" style="document" /> 
           <wsdl:input>  
               <soap:body use="literal" />    
           </wsdl:input>
           <wsdl:output>  
               <soap:body use="literal" />    
           </wsdl:output>
       </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="SimpleService"> 
      <documentation xmlns="http://schemas.xmlsoap.org/wsdl/" /> 
      <wsdl:port name="SimpleServiceSoap" binding="tns:SimpleServiceSoap">  
          <soap:address location="http://localhost/Develop.NET/Home.Develop.WebServices/SimpleService.asmx"/>  
      </wsdl:port>  
  </wsdl:service> 
</wsdl:definitions>


javaScript代码中利用了MS的HTTP代理对象XMLHTTP,在Mozilla's Web brower中相应的组件是XMLHttpRequest,他们都提供了类似的方法来完成soap请求。下面的代码用的是IE中的XMLHTTP对象。代码假定调用过程中没有Fault。
function fncAddTwoIntegers(a, b)
{    
    var oXmlHttp = new ActiveXObject("MSXML2.XMLHTTP");      
    oXmlHttp.open("POST", "http://localhost/Develop.NET/Home.Develop.WebServices/SimpleService.asmx'", false);
    oXmlHttp.setRequestHeader("Content-Type", "text/xml");    
    oXmlHttp.setRequestHeader("SOAPAction", "http://tempuri.org/AddTwoIntegers");

    oXmlHttp.send("      
<soap:Envelopexmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>
<soap:Body> <AddTwoIntegersxmlns='http://tempuri.org/'> <IntegerOne>" + a + "</IntegerOne> <IntegerTwo>" + b + "</IntegerTwo> </AddTwoIntegers>
</soap:Body> </soap:Envelope>"); return oXmlHttp.responseXML.selectSingleNode("//AddTwoIntegersResult").text; }


原文英文出自:http://builder.com.com/5100-6371_14-5887775.html?tag=nl.e601

posted @ 2006-01-05 20:01 软件工程实践者 阅读(1210) | 评论 (3)编辑 收藏

用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 @ 2006-01-02 22:09 软件工程实践者 阅读(5767) | 评论 (2)编辑 收藏

如何编写子定义annotation及使用JDK5.0 annotation包中的annotations

这一小节介绍如何编写一个自定义的注解类型,以及如何应用JDK5.0 java.lang.annotation包中提供的4种注解:
@Documented,@Retention,@Target,@Inherited

1. 编写自定义@Todo注解
经常我们在写程序时,有时候有些功能在当前的版本中并不提供,或由于某些其它原因,有些方法没有完成,而留待以后完成,我们在javadoc中用@TODO来描述这一行为,下面用java注解来实现。

public @interface Todo { } // Todo.java

如果你想让这个注解类型能够自省的话,给它加上@Todo注解,写法如下:

@Todo
public @interface Todo{ }


下面我们给这个注解接受参数的能力,代码如下:
@Todo("Just articleware")
public @interface Todo{
  public enum Priority { LOW, MEDIUM, HIGH }
  String value();
  String[] owners() default "";
  Priority priority() default Priority.MEDIUM;
}

注意注解类性所能接受的参数类型有着严格的规则:
a. 参数类型只能是:primitive, String, Class, enum, annotation, 或者是数组;
b. 参数值不能为空,因此每一个参数值都要定义一个缺省值;
c. 名字为value的参数可以用简便的方法来设置;
d. 参数的写法如同写简单方法(看如上代码),不允许加入参数,不允许有throws子句等。

在上面的代码中,我们为@Todo定义了3个参数, 分别是value, owners, priority. 注意:由于value的特殊性,它的的却省值可以由上面代码中的"Just articleware"来定义,当然你也可以单独写一个缺省值。

下面看一个应用@Todo注解的例子:
@Todo(
  value="Class scope",
  priority=Unfinished.Priority.LOW
)
public class TodoDemo {

  @Todo("Constructor scope")//通过快捷方式,设置value的值
  public TodoDemo() { }

  @Todo(owner="Jason", value="Method scope")
  public void foo() { }
}

上面的代码很简单,不多介绍。

下面我们想让@Todo不能应用在fields, parameters, 或者local variables(因为这对我们来说没有意义);它应当可以出现在javadoc中;在运行是具有持久性。要实现这些特性,就需要annotation包的支持啦。

2. 应用annotation包的支持

1)@Documented
类和方法的annotation缺省情况下是不出现在javadoc中的,为了加入这个性质我们用@Documented
应用代码如下(简单,不多介绍):
package com.robin;
import java.lang.annotation.*;

@Todo("Just articleware")
@Documented
public @interface Todo{ ...


2)@Retention
用来表明你的annotation的有效期,可以有三种选择(如图所示):

以下示例代码应用RUNTIME策略
package com.robin;
import java.lang.annotation.*;

@Todo("Just articleware")
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Todo{ ...

3) @Target
@Target注解表明某个注解应用在哪些目标上,可选择如下范围:
  • ElementType.TYPE (class, interface, enum)
  • ElementType.FIELD (instance variable)
  • ElementType.METHOD ElementType.PARAMETER
  • ElementType.CONSTRUCTOR
  • ElementType.LOCAL_VARIABLE
  • ElementType.ANNOTATION_TYPE (应用于另一个注解上)
  • ElementType.PACKAGE

按我们的功能要求,代码如下:
package com.robin;
import java.lang.annotation.*;

@Todo("Just articleware")
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD,
 ElementType.CONSTRUCTOR,ElementType.ANNOTATION_TYPE,
 ElementType.PACKAGE})
public @interface Todo{ ...

4) @Inherited
@Inherited表明是否一个使用某个annotation的父类可以让此annotation应用于子类。
示例代码如下:
package com.robin;
import java.lang.annotation.*;

@Todo("Just articleware")
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD,
 ElementType.CONSTRUCTOR,ElementType.ANNOTATION_TYPE,
 ElementType.PACKAGE})
@Inherited
public @interface Todo{
  public enum Priority { LOW, MEDIUM, HIGH }

  String value();
  String[] owners() default "";
  Priority priority() default Priority.MEDIUM;
}

posted @ 2006-01-02 10:31 软件工程实践者 阅读(1208) | 评论 (0)编辑 收藏

J2SE 5.0的三种内置注释类型

注解(annotation)是J2SE 5.0的新内容,它给我们提供了很好的编程支持,下面介绍一下其内置的三种注解类型:

1. @Override

@Override用在多态情况下,比如:

public abstract class Animal{
   public void say(){
      System.out.println("annimal is saying");
   }
}

public class Cat extends Animal{
    @Override
    public void say(){
        System.out.println("miao, miao");
    }
}

通过@Override来告诉java编译器,say方法是重载的父类的方法,这样,当父类的say方法签名改名的话,比如增加了一些参数,那么子类的Cat中的say方法编译时就会报错,说没有正确的重载父类方法,所以,@Override可以帮我们验证程序的正确性,这一点,很有用。

2. @Deprecated

@Deprecated的意思和JavaDoc中的@deprecated注释在本质上是一样的,使用如下:

public class DeprecatedExample { 
   @Deprecated 
   public static void badMethod() { }
}

public class DeprecatedUser { 
   public static void main(String[] args){
      DeprecatedExample.badMethod(); 
   }
}

上面的代码如果用javac进行编译的话,会打印出如下信息:
Note: DeprecatedUser.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
1 error
如果你按提示重新加-Xlint进行编译,你就可以得到错误的详细信息:
% javac -Xlint:deprecation
DeprecatedUser.java:3: warning: [deprecation] badMethod() in DeprecatedExample
has been deprecated
DeprecatedExample.badMethod();

需要注意的是:和javadoc中的@deprecated相比,@Deprecated并没有强大多少,因为它不支持参数,而@deprecated后面还可以跟字符串来给一些相关的信息,但@Deprecated做不到,但它提供了运行时自省的功能,来提示错误,所以建议@Deprecated和@deprecated同时使用。


 3. @SuppressWarnings

顾名思义,就是抑制警告信息的出现,使用如下:
public class DeprecatedExample2{ 
   @Deprecated 
   public static void foo() { }
}

public class DeprecatedUser2 { 
   @SuppressWarnings(value={"deprecation"}) 
   public static void main(String[] args) { 
      DeprecatedExample2.foo(); 
   }
}

上述@SuppressWarnings(value={"deprecation"})的作用就是抑制编译器报deprecation的错。
@SuppressWarnings(value={"deprecation"})只支持一个参数,是数组类型,所以你可以不用加value, 写成:@SuppressWarnings({"deprecation"});当想抑制多个类型的警告信息时,可写:@SuppressWarnings({"unchecked","fallthrough",deprecation"}).

注意:在JDK1.5.0 release中,@SuppressWarnings还没有得到完全支持,会在以后支持,但Sun并没有给出具体的时间。

posted @ 2006-01-01 21:41 软件工程实践者 阅读(1140) | 评论 (2)编辑 收藏

仅列出标题
共3页: 上一页 1 2 3