本章主要详细记录如何读懂一个WSDL描述文件。
在上一章里面我们已经成功部署了一个WebService服务,并且通过浏览器能够顺利的看到WSDL文件。那么该文件
表示什么含义呢?通过这个文件我们该如何调用他呢?
首先让我们想一想,如果你想告诉别人你的网络服务,最起码你要让别人知道那些信息,别人才能调用。
1、服务的请求地址,最好多个服务绑定到一个地址上。传递参数时指明调用方法名就可以了。
2、服务使用了什么协议传输数据,例如soap协议,或者http协议的get方法,或者http协议的post方式等。
3、在这个地址中,有哪些可以操作的方法。方法入参是什么,出参是什么。例如出参是UserInfo复杂对象。
4、针对上面的方法,详细描述入参或者出参的结构。例如UserInfo里面有哪些String类型的,那些int类型的等。
上面的wsdl文件由4个节点组成。首先根节点是wsdl:definitions表示这个是一个wsdl的定义文件。(文件从下往上看)
3.1、wsdl:definitions:根节点,表示里面的内容是用来描述webservice的,首先引入schema。这样就不能乱写了。
3.2、wsdl:service:提供了一个地址,如果你想访问这个服务就调用这个地址就行了。
3.3、wsdl:binding:服务的协议,例如使用了soap协议。
3.4、wsdl:portType:具体的服务集合,有哪些方法可以操作。方法入参是什么,出参是什么。
3.5、wsdl:message:消息的详细信息,详细描述了出参是什么,入参是什么。
第一次看这个文档挺难理解的。如果你了解下面几个原因我想看着也许挺容易的。
1、比较复杂的东西应该抽取出来复用。例如上面的wsdl:portType里面有方法入参和出参。之所以用wsdl:message抽
取出来作为一个节点描述入参和出参。不就是为了复用吗,如果写在一起有别的方法也用到这种类型入参或者出参。那岂
不是还要写一次。
2、其实这个和配置servlet有些相似。servlet配置时配置如下
AxisServlet
org.apache.axis.transport.http.AxisServlet
AxisServlet
/services/*
例如上面想把一个url和一个类对应起来,中间加了一个servlet-name节点做为中间连接点,为什么不直接把url和类映
射到一起呢?我想如果这样做,可能不合理,要是直接映射。那么多一个对应该类的请求就需要多写一次类的全名,例如
org.apache.axis.transport.http.AxisServlet
/services/*
org.apache.axis.transport.http.AxisServlet
/ws/*
如果中间多出来一个步骤,使用别名来对应应该方便很多。以后更改类了,只要改一次就可以了,如果不是的话,那么岂
不是每一个都需要改。
而这里呢?wsdl:service可以看成是url-pattern。wsdl:binding则相当于是servlet-name。wsdl:portType相当于servlet-class
这样看是不是容易了,而且还可以添加很多额外的信息。例如wsdl:binding还可以添加一些描述信息,例如使用什么协议。
服务集合wsdl:service里面有个服务SayHello的访问地址是http://127.0.0.1:8080/axis/services/SayHello,这个服务的
使用协议(通过什么方式传输数据)是wsdl:binding描述的。并且通过他我们还可以找到具体实现类wsdl:portType,在这
个类中有哪些方法wsdl:operation,以及方法的详细入参(wsdl:input)出参(wsdl:output)。在wsdl:message中可以看
到参数的详细组成。
package com.ztesoft.axis.client;
import javax.xml.namespace.QName;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
public class Client {
public static void main(String[] args) throws Exception {
// wsdlsoap:address 节点中的地址值。
String url = "http://127.0.0.1:8080/axis/services/SayHello";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(url);
// wsdl:portType 里面的操作方法。
call.setOperationName(new QName(url, "qryUserName"));
// 根据描述传入一个String对象,因为可能有多个入参,所以使用Objct[]
// 描述的返回参数是String, 强转String。
String result = (String) call.invoke(new Object[]{"Readiay"});
System.out.println(result);;
}
}
上面就是使用axis提供的客户端简单调用一下,最后在控制台就简单的打印了处理后的东西。在后面的章节将详细说明
如何调用客户端的内容。此处先做一个简单说明。