消费
Web services
允许把现有的
Web services
加入到业务流程,可以在一个
orchestration
整合进多个
Web services
。
可以在
orchestration
用
Web ports
消费(调用)
Web service
,为了在
orchestration
调用一个
Web service
,需要建立一个
Web port
和构造一个
Web messages
本文以一个比较典型的实例来说明
biztalk
如何消费一个
web services
,深入分析
biztalk
消费
web services
的一些内部机制。
一、
Web services
端
有一个
Web services
,很简单,代码如下:
[
WebService
(Namespace =
“http://chnking.com/”
)]
[
WebServiceBinding
(ConformsTo =
WsiProfiles
.BasicProfile1_1)]
public
class
SAMPLEService
: System.Web.Services.
WebService
{
[
WebMethod
]
public
string
[] TwoWayMethod(
float
a,
Person
person)
{
return
new
string
[] {
“1”
,
“2”
,
“3”
,
“4”
};
}
}
public
class
Person
{
public
string
firstname;
public
string
lastname;
public
Contact
contact;
}
public
class
Contact
{
public
string
telpohone;
public
string
fax;
public
string
address;
public
int
postalcode;
}
1、
TwoWayMethod
方法
方法签名:
public
string
[] TwoWayMethod(
float
a,
Person
person)
有两个输入参数:简单类型
float
和自定义的类
Person
。
Person
类有三个公开字段,其中有一个字段的类型是自定义类型
Contact
,
Contact
类又包括四个公开字段
。
返回参数为一个字符串的数组。
2、
查看
web services
的
WSDL
一个
web services
要被其它应用调用,就必须告诉其它应用如何去调用
web services
中的
webmethod
,比如这个
web services
中包含哪些可以调用的方法,每个方法的方法签名是怎样的,方法是用的输入输出参数的类型又是什么等等,这些都是通过
web services
的
WSDL
来进行描述的。
要查看一个
web services
的
WSDL
可以向
web services
所在的
asmx
文件的
URL
发送
http
请求,并附带
?wsdl
参数即可,比如:
http://biztalkr2:81/WSTest/Service1.asmx?WSDL
来查看一下上面这个
web services
的
WSDL
中跟
TwoWayMethod
相关的
部分:
Figue 1.
WSDL
中跟
TwoWayMethod
相关的
部分
这个
WSDL
的结构需要按照从下面往上面的顺序看。
2.1.
portType
标签
portType
标签用来描述整个的
web services
,
portType
的
name
属性即为这个
web services
类的类名。这个标签下包含了所有的可用方法,每个
operation
标签表示一个方法。
2.2.
operation
标签
每一个
operation
标签表示
web services
里的一个
webmethod
方法,
operation
标签的
name
属性是这个
webmethod
的方法名。
2.3.
Input
和
output
标签
Input
和
output
标签分别表示一个
operation
(
webmethod
方法)的输入和输出的参数集合,这里叫做消息,不管输入参数有几个,每个参数有多么复杂,只有一个表示这些输入参数的消息,就是
input
标签的
message
属性表示的那个消息。对于输出消息也一样。
2.4.
Message
标签
方法的输入输出参数都用一个消息来表示,
message
标签表示一个这样的消息,
message
标签按下面有个
part
标签,用来具体指示这个消息在
schema
中的类型,类型以
element
形式表现出来,即
part
标签的
element
属性指定的那个
element
。
对于输入参数消息,
part
标签的
element
属性命名同
webmethod
方法名。
对于输出参数消息,
part
标签的
element
属性命名同
webmethod
方法名
+ response
。
表示类型的
element
都被集中放置在
types
标签内。
2.5.
types
标签
此标签用来描述所有
webmethod
所要用到的类型,都以
element
来描述类型。比如:
public
string
[] TwoWayMethod(
float
a,
Person
person)
这个
webmethod
的输入参数有两个:
float
a,
Person
person
,在
WSDL
的中的类型表现是这样的:
<
s:element name
=”
TwoWayMethod
“>
<
s:complexType
>
<
s:sequence
>
<
s:element
minOccurs
=”
1
”
maxOccurs
=”
1
”
name
=”
a
”
type
=”
s:float
” />
<
s:element
minOccurs
=”
0
”
maxOccurs
=”
1
”
name
=”
person
”
type
=”
tns:Person
” />
</
s:sequence
>
</
s:complexType
>
</
s:element
>
其中
a
元素是简单的
float
类型,不需要另加说明。
person
元素是
Person
类型,
Person
类型又是个
complex
类型,在
types
标签里还包括了这个
Person
类型的定义。只要是消息中引用到的非简单类型,都需要在
types
中进行定义描述。
二、
Biztalk
消费
Web services
的一般方法
这个
Web services
中的
TwoWayMethod
方法是个比较复杂的方法,具有两个输入参数,其中一个参数是自定义的类,并且嵌套了另一个自定义的类,返回的参数也是字符型的数组,相对比较复杂。
1、
新建
biztalk
项目
新建一个
biztalk
项目,用来测试
Web services
的
TwoWayMethod
方法。
2、
引用
Web services
跟一般的应用项目要调用一个
Web services
一样,首先在项目中引用这个
Web services
。但是在
biztalk
项目中引用一个
Web services
跟一般的应用引用
Web services
表现不一样。
Figure 2. biztalk
项目和
windows
项目引用同一个
web services
的不同表现
windows
项目引用
web services
后,在引用目录下
Reference.map
生成一个
Reference.cs
文件,这个文件是被引用的
web services
在本地生成的代理类,派生自
System.Web.Services.Protocols.
SoapHttpClientProtocol
类。
Biztalk
项目引用
web services
后,在引用目录
Reference.map
下生成两类文件,一个
odx
类型的
orchestration
文件,和数量不定的
xsd
架构文件。分别看一下这两类文件都生成了什么。
2.1.
xsd
架构文件
2.1.1.
每个复杂参数类型被生成一个
schema
文件
web services
中的每个
webmethod
的参数,不管是输入参数还是输出参数,只要不是简单数据类型,每个参数类型就会被生成一个
schema
文件,所有类型都将都被转成
schema
类型,这就意味着,参数类型必须是可以被
xml
序列化的。
public
string
[] TwoWayMethod(
float
a,
Person
person)
这个
webmethod
方法,参数
person
和返回的
string[]
类型的参数都不是简单数据类型,所以这两个参数类型分别被形成
schema
文件,表现为在
Reference.map
下的
Reference.xsd
和
Reference1.xsd
文件。
2.1.2.
简单参数类型不需要生成
schema
简单数据类型(
int
、
string
、
float
等等)这些
schema
本身支持的简单类型,不需要另外用
schema
进行定义。比如上面那个
webmethod
方法中的
a
参数。
2.2.
odx
流程文件
Figure 3. biztalk
项目引用
web services
后形成的
odx
流程文件
引用
web services
后形成的
odx
流程文件是把
web services
的方法转变成
orchestration
的端口类型和消息类型,实际上反映的也就是每个
webmethod
的方法签名。
2.2.1.
Web
Port
Types
一个
web
端口类型代表了一个
web services
的类。
每个端口类型下可以有多个操作(
operation
),每个操作就是
web services
的类里的一个
webmethod
方法。
每个操作都有两个消息,分表表示输入消息
Request
,输出消息
Response
。不管输入参数或输出参数有多少,所有的输入参数都被放入到一个消息中,同样所有的输出参数也都被放入到一个消息中。
每个消息都是一个多部分消息类型。这些多部分消息类型由
Web Message Types
部分定义。
注意:
<?xml:namespace prefix = o />
如果
webmethod
方法没有返回值(
void
),
webmethod
仍要生成返回消息,在
biztalk
的
web
端口类型中仍要生成返回的
response
部分。
2.2.2.
Web Message Types
Web
消息类型定义
web
端口的每个操作使用的消息,都为多部分消息。
如果一个操作的输入参数有多个参数,则每个参数在多部分消息中作为一个消息部分出现。
每个参数的参数名就是消息中一个消息部分的部分名。
Webmethod
方法的
retuen
返回参数没有名称,默认就是
“Webmethod
方法名+
Result”
做为消息部分名。
注意:
如果
webmethod
方法没有返回值(
void
),
webmethod
的
response
部分对应的
web
多部分消息类型,就是一个只有消息上下文而没有消息部分的
web
消息类型。
2.3.
引用
web services
后的作用
Biztalk
项目引用
web services
形成的
odx
流程文件是只读的,不能单独使用这个
odx
文件。
Odx
的作用是在新建的自定义
orchestration
流程中,这个
odx
的
web
端口类型和
web
消息类型都会被自动的加入到进去,只是这些端口类型和消息类型不能被修改。
在自定义
orchestration
流程中要消费引用的
web services
的
webmethod
就需要使用这些端口类型,通过这些类型的端口跟物理
soap
的发送端口绑定。
2.4.
biztalk
项目引用
web services
不生成代理类吗?
这是个问题,一般的应用项目在引用
web services
后会生成一个从
System.Web.Services.Protocols.
SoapHttpClientProtocol
类继承的本地代理类,应用程序通过调用代理类来调用
web services
。
但是从上面
biztalk
引用
web services
的过程,在生成的引用文件中似乎没有发现生成本地代理类。是不是
biztalk
引用
web services
并不生成本地代理类呢?
我们来分别看一下
windows
应用项目和
biztalk
项目引用这个
web services
后生成的恶
exe
和
dll
里的内容。
Figure 4.
用
ildasm
看
windows
应用项目引用
web services
后的
exe
文件
windows
应用引用
web services
后,在引用
web services
的名称空间下生成本地代理类,代理类的名称跟
web services
类名一样。
除了代理类,
webmethod
方法中用到的参数如果不是简单的数据类型,也会在本地生成参数类型(参数类型在
WSDL
中以
schema
形式描述),
windows
项目引用
web services
会把参数类型从
schema
形成转成
class
类形式。
Figure 5.
用
ildasm
看
biztalk
项目引用
web services
后的
dll
文件
可以看到,
biztalk
项目引用
web services
后,在生成的
dll
中同样有继承自
System.Web.Services.Protocols.
SoapHttpClientProtocol
的本地代理类,说明
biztalk
项目引用
web services
后也要生成本地代理类,并且
biztalk
如果调用
web services
同样也是需要通过这个代理类来调用(后面还会继续谈到这个问题)。
3、
建立
orchestration
消费
web services
设计一个流程消费上述的那个
web services
。
Figure 6.
消费
web services
的
orchestration
流程很简单,
Port_1
从一个文件夹中读取
Person
格式的
xml
文件:
<
ns0:Person
xmlns:ns0
=
”
http://chnking.com/
”
>
<
ns0:firstname
>
firstname_0
</
ns0:firstname
>
<
ns0:lastname
>
lastname_0
</
ns0:lastname
>
<
ns0:contact
>
<
ns0:telpohone
>
telpohone_0
</
ns0:telpohone
>
<
ns0:fax
>
fax_0
</
ns0:fax
>
<
ns0:address
>
address_0
</
ns0:address
>
<
ns0:postalcode
>
10
</
ns0:postalcode
>
</
ns0:contact
>
</
ns0:Person
>
赋值形状
MessageAssignment_1
把读取进来的
person
消息赋给要发送到
web services
的多部分消息的
person
消息部分,同时给多部分消息的
a
消息赋一个浮点数的值:
Message_WSRequest.a = (System.Single)3.1416;
Message_WSRequest.person = Message_person;
建立消费
web services
的端口。
新建一个端口,端口类型选引用
web services
后生成的那个
web
端口类型。如图所示:
Figure 7.
新建消费
web services
的端口
绑定方式默认为现在指定,
biztalk
会把引用
web services
的
URI
和需要采用的
SOAP
适配器记录下来,部署后根据这些信息生成物理
SOAP
发送端口并跟这个双向发送端口绑定。
Figure 8.
双向发送端口的绑定
从
web services
返回的消息通过
Port_2
端口写入到另一个文件夹。
4、
部署设置消费
web services
的
biztalk
项目
编译部署
biztalk
项目。
部署好后,查看项目配置,可以看到消费
web services
的双向发送端口来已经跟一个
SOAP
发送端口绑定。
剩下的添加两个
file
适配器的端口,分别设置为读取
person xml
文件的输入端口和保存最后结果的发送端口。
5、
SOAP
端口的设置
一般按照部署后的默认配置,这个
SOAP
已经能够很好的工作了,但是为了更深一步的了解
SOAP
端口,来看看
SOAP
端口的各个设置。
5.1.
General
标签
Figure 9. SOAP
端口的
General
标签设置
Web services URL
:
引用
web services
的
URL
Authentication type
:
web services
方的验证方式。
Anonymous –
匿名验证,
web services
服务端允许匿名访问可以设置为
Anonymous
。
Basic –
基本身份验证,
web services
服务端采用基本身份验证时采用,需要客户端提供用户名和密码,在
Credentials
中输入用户名和密码。此用户名和密码被转换成
base64
编码连同
SOAP
的
http
请求一起发送到服务端。
NTLM –
在
web services
服务端设置了
windows
集成验证时采用,
windows
集成验证的客户端可以选用
NTLM
验证和
Kerberos
两种验证方式,但
SOAP
只使用
NTLM
验证,并且使用客户端登录帐户的用户名和密码进行验证凭据的传送。关于
IIS
的身份验证的详细讨论请参看《
IIS
的各种身
份验证详细测试
》《
应用程序向
IIS
传送身份验证
》。
5.2.
Proxy
标签
Figure 10. SOAP
端口的
Proxy
标签设置
用于设置访问
web services
是否要使用代理服务器。
Use Handler’s default proxy configuration
:
使用
SOAP handler
级别的代理设置。
在
Biztalk Group
下打开
Platform Setting
目录,在其下选择
Adapters
,展开,所有的适配器都列在其中,选择
SOAP
,看右边窗口的显示。
双击发送
handler
的那一条,在弹出的
SOAP – Adapter Handler Properties
窗口中,点
Properties
按钮,在这里设置
handler
级别的代理设置,如下图:
Figure 11. SOAP
端口
handler
级别的
Proxy
设置
Dot not use proxy
:
调用
web services
不使用代理服务器。
Use proxy
:
设置这个
SOAP
端口使用的代理服务器。
5.3.
Web services
标签
Figure 12. SOAP
端口的
Web services
标签设置
这个标签设置使用哪个代理类访问实际的
web services
。
SOAP
端口也是需要使用从
SoapHttpClientProtocol
继承的本地代理类访问
web services
。这里就是指定使用哪个代理类的。
Orchestration Web port
:
Biztalk
项目引用
web services
后形成了
web
端口类型和
web
消息类型,这些在
biztalk
项目编译后就会生成一个本地代理类,跟一般
windows
项目引用
web services
后形成的代理类基本一致。本设置就是选择这个
SOAP
使用引用
biztalk
项目编译后自己形成的代理类。
The following setting
:
选择其他的代理类,但是这个代理类必须是从
SoapHttpClientProtocol
继承的。
Assembly name
:
包含了代理类的
assembly
Type name
:在
assembly
中选择这个
SOAP
适配器要使用的那个代理类
Method name
:
选择这个
SOAP
要调用的
web services
中的方法。
Use SOAP 1.2
:
设置发送到
web services
服务端的
SOAP
消息使用
SOAP1.2
规范的。
但是实际测试这个选项好像不起作用。