2008年1月25日星期五

WebService_102:SAAJ介绍

WebService_015:WSIF介绍

【WSIF】:Web Services Invocation Framework Web服务调用框架。
“WSIF is a simple Java API for invoking Web services, no matter how or where the services are provided.”(摘自
http://ws.apache.org/wsif/
WSIF提供了一组简单的API来调用Web服务而不需要了解该Web服务的实现方式。说的再明白些,“WSIF is a WSDL-based API for invoking WSDL-described services”。WSIF支持如下方式实现的服务:SOAP、Java、EJB、JMS、JCA。使用WSDL扩展规范,你可以像访问Web服务一样来访问方式实现的服务。

除了以统一的编程模型来调用Web服务外,WSIF还有以下好处:
◆ 通过WSIF 调用服务可以维护原生协议的性能。因此,在调用 Java 、EJB 或其他资源时,没有性能损失。
◆ WSIF 支持JTA事务。因此,Java 资源可以参与分布式事务。


问题1:What are differences between WSIF and Axis?
Axis is an implementation of SOAP. It includes on the server-side infrastructure for deploying web service implementations and then routing SOAP messages between clients and those implementations. It also implements the JAX-RPC specification for invoking SOAP services.
WSIF is similar to the client piece of Axis, in that it is used for invoking services. However, WSIF's API is WSDL-driven and protocol independent; it allows protocol-specific code ("providers") to be plugged in. For invoking SOAP services, WSIF is in fact packaged with an Axis provider, that uses Axis APIs (i.e. JAX-RPC) to do the invocation. So WSIF operates at a more abstract level than Axis.
问题2:What are differences between WSIF and JAX-RPC?JAX-RPC is an API for invoking XML-based RPC services - essentially its current scope is limited to invocation of SOAP services. WSIF is an API for invoking WSDL-described services, whether they happen to be SOAP services or not (for example, WSIF defines WSDL bindings so that EJBs, enterprise software acessible using JMS or the Java Connector architecture as wel as local java classes can all be described as first class WSDL services and then invoked using the same, protocol-independent WSIF API).
问题3:How to use and set HTTP proxy with WSIF and SOAP over HTTP?HTTP proxy settings can be set using the following system properties http.proxyHost- The hostname of the proxy server http.proxyPort - The port for the proxy serverhttp.nonProxyHosts - A comma separated list of hosts to access directly rather thanthrough the proxy

如何使用WSIF?
1. 实验准备
(1)下载WSIF2.0
http://ws.apache.org/wsif/
(2)下载WSIF2.0
http://ws.apache.org/wsif/

2008年1月24日星期四

WebService_107:JSR-109与JSR-181介绍

WebService_105:Axis2介绍

我们可以通过Axis2学习JAX-WS,因为Axis2实现了JAX-WS API。

WebService_103:Axis介绍

【Axis】:Apache EXtensible Interaction System,a fancy way of implying it's a very configurable SOAP engine。
我们可以通过Axis学习JAX-RPC,因为Axis完全实现了JAX-RPC 和SAAJ(jaxrpc.jar 和saaj.jar) 。
如何使用Axis?
1. 实验准备
(1)下载Axis1.4
http://ws.apache.org/axis/
(2)下载Tomcat5.5
http://tomcat.apache.org/download-55.cgi

2. 安装Axis1.4
(1)解压缩axis-bin-1_4.zip后,复制axis-1_4\webapps\axis到apache-tomcat-5.5.26\webapps下。
(2)启动tomcat:catalina run。
(3)访问
http://127.0.0.1:8080/axis/,点击Validation,会有信息提示。
(4)按照信息提示,分别加入activation.jar、mail.jar、xmlsec.jar(我用的是xmlsec-1.4.2.jar)到webapps\axis\lib下。
确认没有任何错误或警告信息后,就说明Axis1.4安装成功。

3. 开发Web服务 from a Java Interface
(1)写一个Java Interface,并编译成类。
package com.javaneverdie;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface HelloDBWebService extends Remote {
public String hello(String str) throws RemoteException;
}

(2)使用Java2WSDL创建WSDL
java org.apache.axis.wsdl.Java2WSDL [options] class-of-portType。比如:
java org.apache.axis.wsdl.Java2WSDL -o HelloDBWebService.wsdl
-l"http://localhost:8080/axis/services/HelloDB" -n http://javanerverdie.com/
-p"com.javaneverdie" "http://javaneverdie.com" com.javaneverdie.HelloDBWebService -y DOCUMENT -u LITERAL

其中:
-o 输出的WSDL文件名称。
-l 指向服务的地址。
-n WSDL的目标名称空间。
-p package到namespace的mapping,可能有多个。
-y style of the binding (DOCUMENT,RPC,WRAPPED)。
-u use of the binding(LITERAL,ENCODED)

(3)使用WSDL2Java创建Bindings
java org.apache.axis.wsdl.WSDL2Java [options] WSDL-URI。比如:
java org.apache.axis.wsdl.WSDL2Java -o C:\Output -s -d Session -S true HelloDBWebService.wsdl

其中:
-o 输出目录。
-s emit server-side bindings for web service。
-d add scope to deploy.wsdd: "Application","Request", "Session"。
-N namespace到package的mapping。
-S deploy skeleton (true) or implementation (false) in deploy.wsdd. Default is false. Assumes server-side.

以下文件将被产生:
· HelloDBSoapBindingImpl.java:默认的服务实现,你应该修改成自己想要的实现。
· HelloDBService.java:新的Interface,包括java.rmi.Remote。
· HelloDBWebServiceService.java:客户端服务Interface。
· HelloDBWebServiceServiceLocator.java:客户端服务实现。
· HelloDBSoapBindingSkeleton.java:服务端skeleton。
· HelloDBSoapBindingStub.java:客户端stub。
· deploy.wsdd:Deployment descriptor。
· undeploy.wsdd:Undeployment descriptor。

(4)编译产生的java文件,把class复制到webapps\axis\WEB-INF\classes\下。

(5)发布/卸载 Web服务
java org.apache.axis.client.AdminClient -lhttp://localhost:8080/axis/services/AdminService deploy.wsdd
java org.apache.axis.client.AdminClient -lhttp://localhost:8080/axis/services/AdminService undeploy.wsdd
访问
http://127.0.0.1:8080/axis/servlet/AxisServlet,确认已经成功发布。

(6)测试 Web服务:使用JAX-RPC 3种客户端调用

package com.javaneverdie.test;

import java.net.*;
import javax.xml.rpc.*;
import javax.xml.namespace.*;

import com.javaneverdie.*;

public class HelloDBTest {
public static void main(String[] args) {
try {
// 1. Statically Generated Stubs
System.out.println(new HelloDBWebServiceServiceLocator().getHelloDB().hello("Ping Ma"));

// 2. Dynamic Invocation Using the Service Interface
// Create a service class with WSDL information.
String wsdlUrl = "http://127.0.0.1:8080/axis/services/HelloDB?wsdl";
String nameSpaceUri = "http://javaneverdie.com";
String serviceName = "HelloDBWebServiceService";
String portName = "HelloDB";
ServiceFactory serviceFactory1 = ServiceFactory.newInstance();
Service service1 = serviceFactory1.createService(new URL(wsdlUrl), new QName(nameSpaceUri, serviceName));
HelloDBWebService proxy = (HelloDBWebService)service1.getPort(new QName(nameSpaceUri, portName), HelloDBWebService.class);
System.out.println(proxy.hello("Ping Ma"));

// 3. Dynamic Invocation Interface (DII)
// Create a service class with no WSDL information. You still must know something about the WSDL, however: the service's name.
String endpoint = "http://127.0.0.1:8080/axis/services/HelloDB";
ServiceFactory serviceFactory2 = ServiceFactory.newInstance();
Service service2 = serviceFactory2.createService(new QName(nameSpaceUri, serviceName));
Call call = (Call)service2.createCall();
call.setOperationName(new QName("http://javaneverdie.com", "hello")); call.setTargetEndpointAddress(endpoint);
String ret = (String)call.invoke(new Object[] { "Ping Ma" });
System.out.println(ret);
} catch (Exception e) {
e.printStackTrace();
}
}
}

注:使用DII方式调用时,抛出异常:org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.网上有很多人遇到这个问题,尚未找到答案。
Axis架构
理解WSDD(Web Service Deployment Descriptor)

WebService_103:JAX-WS介绍

【JAX-WS】:Java API for XML-based Web services 基于XML 的Web服务的Java API。
由于行业中不仅只使用RPC Web 服务,还使用面向消息的Web 服务。因此如果可能,请使用JAX-RPC1.1 的后续版本JAX-WS 2.0。

参考文献:
1. 《JAX-RPC 与 JAX-WS 的比较》 作者:http://www.ibm.com/developerworks/cn/webservices/ws-tip-jaxwsrpc.html

2008年1月22日星期二

WebService_011:JAXR介绍

【JAXR】:Java API for XML Registries。
JAXR提供一个统一的、标准的Java API,用于访问不同类型的XML 注册项。XML 注册项是构建、部署和发现 Web 服务的基础设施。

2008年1月15日星期二

WebService_100:服务的粒度究竟多大合适?(摘录+整理)

这是一个值得深入思考的问题。我将一直关注这个问题,期待能有一个比较好的解决办法。
1. 服务的粒度(service granularity):指一个服务包含的功能大小。
2. 细粒度服务(fine-grained)的特点:


  • 业务逻辑简单。

  • 数据量小。

  • 服务交互次数多。

  • 服务之间的耦合性大。

  • 灵活性好。

3. 粗粒度服务(coarse-grained)的特点:


  • 业务逻辑复杂。

  • 数据量大。

  • 服务交互次数少。

  • 服务之间的耦合性小。

  • 灵活性差。

结论:服务粒度既不能太大也不能太小(跟没说一样?)。

服务的粒度究竟多大合适?很遗憾,目前没有成熟的标准供我们参考。但我们知道:一个设计良好的服务应该具备三大要素:重用性,灵活性,性能。我们可以用这个标准来考量服务的粒度。

1. 重用性:服务应用于不同上下文的能力。
重用性可以降低开发和维护的成本。粒度的大小直接影响到服务的可重用性。显然,细粒度的服务更容易被重用。但是如果机械地考虑重用性,将导致大量粒度很小的功能单元,这将对系统整体性能和容量带来严重的影响。想想拼图游戏就能明白这个道理:同样大小的同一张图,用1000张拼容易还是3000张容易?

2. 灵活性:因变而变的能力。
灵活性可以更快的适应业务的变化。粒度的大小直接影响到服务的灵活性。显然,细粒度的服务可以更容易地组装,灵活性更好。同样,仅仅考虑灵活性将导致大量的细粒度的服务,这也是不可取的。这里介绍一个分析方法:自上而下的逐级流程分解法。
逐级流程分解法自上而下的逐级流程分解法是将业务流程一级级分解,直到不能分解为止。其中,把业务人员能够识别出来的服务作为候选的业务服务,粒度最小的服务就从这些服务里产生。
接下来再逐一分析每个服务,看看哪些服务有额外的灵活性要求。划分方法可以参考SAP业务流程的划分方法。SAP将流程划分为核心流程(core process)和支撑流程(context process)。其中,支撑流程是指那些不可或缺的,但又不影响企业差异化的流程,如财会流程等,它们关注的是如何提高生产效率,降低生产成本。这些流程相对稳定,因此适用于粗粒度的服务。而核心流程是指代表企业竞争力的业务流程,如营销流程等。这些流程可能随时发生变化,因此它们需要细粒度地分解,以获得最大的灵活性。

3. 性能
一个服务本身的复杂度以及调用其它服务的次数,是影响性能的两个主要方面。服务颗粒度越大,意味着包含的功能越多,业务逻辑越复杂,响应越慢。而服务颗粒度越小,意味着包含的功能越简单,虽然单个服务执行效率很高,但完成一项业务所需的服务调用次数越多,远程请求/响应次数越多。因此,为了提高服务的性能,一方面需要限制服务包含的功能范围和复杂度,也就是说粒度不能太粗;另一方面需要限制服务调用的次数和复杂度,也就是说服务粒度不能太细。二者之间需要找到一个平衡点。

用迷你裙定律(mini-skirt theory)作结:
short enough to keep people interested, but long enough to cover the important part”。
a well-designed service should be fine-grained enough to be reusable, but coarse-grained enough to make business sense”。

参考文献
1. 《服务颗粒度的困扰》 作者:http://blog.sina.com.cn/s/blog_4e2131ab01000e50.html
2. 《SOA中怎样确定服务的粒度》作者:http://www.testage.net/html/34/n-141534.html

2008年1月14日星期一

WebService_102:JAX-RPC介绍

【JAX-RPC】:Java APIs for XML-Based Remote Procedure Call 基于XML 的远程过程调用的 Java API。
JAX-RPC 定义并使用了一种基于XML 的远程过程调用机制。它旨在帮助服务消费者和服务提供者获得最大程度的灵活性,方法是通过把服务互操作性的重担转移到运行时基础架构。
它使服务提供者能够用标准的API 定义其服务并且能够用WSDL 描述其服务;它使服务消费者能够用标准的API 与服务器进行通信。
JAX-RPC遵循SOAP1.1规范,但是开发者不需要与SOAP消息打交道,开发者只会看见远程接口(方法、参数和返回值)。
JAX-RPC最终被JCP命名为JSR 101。
JAX-RPC的局限性:
“JAX-RPC enables building of Web services and Web applications based on the SOAP 1.1 specification, Java SE 1.4 or lower, or when rpc/encoded style must be used.
If possible, JAX-WS should be used instead as it is based on the most recent industry standards. ”
更多信息请访问:https://jax-rpc.dev.java.net/。

JAX-RPC的功能如下:
  • 类型映射系统

  • 服务端点

  • 异常处理

  • 服务端点上下文

  • 消息处理程序

  • 服务客户机和服务上下文

  • 带附件的 SOAP

  • 运行时服务

  • JAX-RPC 客户机调用模型


1. 类型映射系统
将XML 类型映射为Java 类型
将抽象的WSDL 定义(端口类型、操作和消息)映射为Java 接口和 Java 类。
将具体的WSDL 定义(端口、绑定和服务)映射为Java 类。
2. 服务端点
3. 异常处理
4. 服务端点上下文
5. 消息处理程序
6. 服务客户机和服务上下文
7. 带附件的 SOAP
8. 运行时服务
9. JAX-RPC 客户机调用模型


这里是三个不同的从客户机调用服务端点的的模型。它们独立于任何特定于服务实现的模型。
(1)基于存根的模型(静态存根):
一个生成了的存根类是实现 javax.xml.rpc.stub 和服务端点接口所必需的。这个存根接口通过设置诸如端点地址、会话、用户名、密码这样的属性来提供 API 以配置存根。
优点:实现比较简单。
缺点:不能实现动态调用,需要先通过工具构建客户端,生成代理,才能利用客户端来调用远程服务。
(2)动态代理。和上面所讨论的静态存根相反的是,运行时客户机使用 javax.xml.rpc.Service 接口来创建动态服务代理存根客户。客户机能够推算出关于WSDL 和它要调用的服务的信息。它使用 ServiceFactory 类来创建服务获取代理。
优点:不必构建代理程序,实现了一定的动态性。
缺点:与远程服务的关联太紧密,耦合度太高。
(3)DII(动态调用接口)。这个软件模式省却了客户提前了解服务的确切名字和参数的需要。DII 客户机可以使用能查找服务信息的服务代理程序在运行时发现这个信息。服务发现中的灵活性使运行时系统能使用服务代理程序,服务代理程序能够采用各种服务发现机制(如 ebXML、注册表、UDDI等)。

参考文献:
1. 《开发者关于JAX-RPC 的介绍》作者:http://www.ibm.com/developerworks/cn/webservices/ws-jaxrpc/part1/

2008年1月13日星期日

WebService_016:WS-Addressing 介绍 (摘录+整理)

【WS-Addressing】:WebService寻址规范。
SOAP定义了在Web Services之间传递消息的格式,SOAP消息可以在不同的传输协议进行传递。
SOAP中并没有定义如何寻址一个Web Service,为了找到一个Web Service的确切位置,我们需要求助于WSDL。但随着Web Service的发展,产生了一些新的问题。
问题1:在请求某个Web Service时使用HTTP传输协议,在响应中使用SMTP传输协议。

问题2:异步Web Service的响应信息如何寻址。


问题3:处理时间很长的事务中,如何关联请求消息与响应消息,从而维持住WebService的状态?


参考文献:
1. 《
WS-Addressing 从理论到实践

2008年1月10日星期四

WebService_101:JAXM介绍

【JAXM】:Java API for XML Messaging。
“ With the JAXM API, developers not only create XML messages that conform to SOAP specifications, but can also exchange messages synchronously or asynchronously with other JAXM providers. ”
JAXM 旨在使用纯 Java API 使应用程序能够发送与接收面向文档的 XML 消息。JAXM 的目的是为更高级别的、基于标准的并且基于 SOAP 消息传递协议的消息传递协议(如 ebXML)提供一个基础。SAAJ 规范最近从 JAXM 被分离了出来,它包含一个同步的 SOAP 连接,因此 JAXM 现在主要用于异步消息。当以异步方式使用 JAXM 时,它使用消息传递提供程序来促进消息的路由选择。JAXM 包括一个消息传递提供程序,这个提供程序是 ebXML 传输、路由和打包(ebXML Transport, Routing, and Packaging)规范版本 1.0 的参考实现。

【SAAJ】:SOAP with Attachments API forJava 带有附件的Java SOAP API。
SAAJ 使开发人员能够生产并消费那些遵循 SOAP 1.1 规范的消息及其所包含的 SOAP 附件。SAAJ 原先是作为 JAXM 1.0 规范的一部分进行定义的;但随着最近 JAXM 1.1 的发布,SAAJ 已被分离出来,自成一个规范,这样其他规范就能够依靠 SAAJ 包而无需依靠 JAXM。


使用JAX-RPC和JAXM都可以开发Web服务,二者的区别是:
◆ 使用JAX-RPC,开发者不需要与SOAP消息打交道,开发者只会看见远程接口(方法、参数和返回值)。
◆使用JAXM,开发者直接处理SOAP消息(通过SAAJ)。
因此,JAXM是面向文档的,而JAX-RPC是面向过程的。

2008年1月3日星期四

WebService_006:我的Web服务符合WS-I基本概要规范吗?

【WS-I】:Web Services Interoperability Organization 网络服务协同组织。
该组织的宗旨是致力于促进跨平台、跨操作系统和跨程序语言的网络服务互用性。
WS-I Basic Profile Specification(WS-I 基本概要规范)定义了Web 服务要遵循的内容,在WS-I的网站上提供测试工具来检查Web 服务是否符合规范。目前最新版本是1.2,更多信息请访问:
http://www.ws-i.org/

开发人员需要关心的规范内容:
1. 不要使用RPC-encoded方式。
RPC-encoded常常会导致互操作性问题,特别是不同平台应用之间的交互。

2. 正确使用wsdl:import 和 xsd:import。
wsdl:import 只能用来从一个WSDL 文档导入另一个WSDL文档。如果要导入XML Schema,应该使用xsd:import。

参考文献
1. 《初识 WS-I 基本概要 1.0》 作者:
http://www.ibm.com/developerworks/cn/webservices/ws-basicprof/index.html
2. 《了解 WS-I 测试工具》 作者:
http://www.ibm.com/developerworks/cn/webservices/ws-wsitest/
3. 《Web 服务编程技巧与窍门》 作者:http://www.ibm.com/developerworks/cn/webservices/ws-tip-j2eenet1/index.html

WebService_005:实验说明4种SOAP binding的区别

开发工具:Oracle JDeveloper Studio 10.1.3.3.0。
运行环境:Oracle SOA Suite 10.1.3.1.0 + Oracle Database 10g Express Edition。
实验目的:彻底搞清楚4种SOAP binding的不同之处。

首先从style上划分,SOAP binding 分为两种:document-style和RPC-style,二者最直观的区别是:
◆ document-style
(1)WSDL中message的定义,其中的part是用XML schema的element定义的,比如:
<message name="LoanFlowRequestMessage">
<part name="payload" element="s1:loanApplication"/>
</message>
(2)SOAP消息中Body部分直接包含消息内容(一个XML文档)。服务器负责将XML文档映射成内存对象(参数、方法调用等等)。
◆ RPC-style,
(1)WSDL中message的定义,其中的part是用XML schema的type定义的,比如:
<message name="LoanFlowRequestMessage">
<part name="payload" type="s1:LoanApplicationType"/"/>
</message>
(2)SOAP消息中Body部分包含的XML节点是该服务的调用方法名,然后依次包含方法调用的各个参数。

其次从use上划分,分为encoded和literal。
◆ encoded
表示XML的消息使用类型属性引用抽象数据类型,使用Section 5编码(SOAP1.1规范第五章定义的编码)进行XML的序列化和反序列化。
◆ literal
表示XML的消息使用type属性或者element元素引用具体的XML Schema定义,也就是说,根据XML Schema进行XML的序列化和反序列化。

style和use一组合,就形成了4种不同的SOAP binding。
对于document-style,又分为两种:document-literal bared 和 document-literal wrapped。
• document-literal bared (简称document-literal),其服务调用方法只能有一个参数。
从类HelloDBImpl 生成 HelloDBWebService.wsdl
package com.javaneverdie;
public class HelloDBImpl {
public String hello(String str) {
return "Hello, document-literal bared, " + str;
}
}
<types>
<schema ...>
<element name="helloElement" type="string" nillable="true"/>
<element name="helloResponseElement" type="string" nillable="true"/>
</schema>
</types>

SOAP 请求消息如下:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body xmlns:ns1="http://javaneverdie.com/types/"> <ns1:helloElement>Ping Ma</ns1:helloElement>
</soap:Body>
</soap:Envelope>


SOAP 响应消息如下:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body> <ans1:helloResponseElement xmlns:ans1="http://javaneverdie.com/types/">Hello, document-literal bared, Ping Ma</ans1:helloResponseElement>
</env:Body>
</env:Envelope>

document-literal wrapped(简称document-wrapped ),其服务调用方法的参数可以多个,所谓wrapped是指它的参数全部被“wrapped”一个复杂的数据类型(complexType)中。
从类HelloDW1Impl 生成 HelloDW1WebService.wsdl
package com.javaneverdie;
public class HelloDW1Impl {
public String hello(String str) {
return "Hello, document-literal wrapped, " + str;
}
}
<types>
<schema ...>
<element name="helloElement">
<complexType>
<sequence>
<element name="str" type="string" nillable="true"/>
</sequence>
</complexType>
</element>
<element name="helloResponseElement">
<complexType>
<sequence>
<element name="result" type="string" nillable="true"/>
</sequence>
</complexType>
</element>
</schema>
</types>

SOAP 请求消息如下:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body xmlns:ns1="http://javaneverdie.com/types/">
<ns1:helloElement>
<ns1:str>Ping Ma</ns1:str>
</ns1:helloElement>
</soap:Body>
</soap:Envelope>
注意:SOAP消息中helloElement来自于输入信息的element。


SOAP 响应消息如下:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://javaneverdie.com/types/">
<env:Body>
<ns0:helloResponseElement>
<ns0:result>Hello, document-literal wrapped, Ping Ma</ns0:result>
</ns0:helloResponseElement>
</env:Body>
</env:Envelope>

对于RPC-style,也分为两种:RPC-literal 和 RPC-encoded。
• RPC-literal
package com.javaneverdie;
public class HelloRLImpl {
public String hello(String str1, String str2) {
return "Hello, RPC-literal, " + str1 + ", " + str2;
}
}
SOAP 请求消息如下:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://javaneverdie.com/">
<soap:Body>
<ns:hello>
<str1>Ping</str1>
<str2>Ma</str2>
</ns:hello>
</soap:Body>
</soap:Envelope>
注意:SOAP消息中hello来自于服务调用的方法名。

SOAP 响应消息如下:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://javaneverdie.com/">
<env:Body>
<ns0:helloResponse>
<result>Hello, RPC-literal, Ping, Ma</result>
</ns0:helloResponse>
</env:Body>
</env:Envelope>

• RPC-encoded
package com.javaneverdie;
public class HelloREImpl {
public String hello(String str1, String str2) {
return "Hello, RPC-encoded, " + str1 + ", " + str2;
}
}
SOAP 请求消息如下:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://javaneverdie.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<ns:hello>
<str1 xsi:type="xsd:string"></str1>
<str2 xsi:type="xsd:string"></str2>
</ns:hello>
</soap:Body>
</soap:Envelope>

SOAP 响应消息如下:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://javaneverdie.com/">
<env:Body>
<ns0:helloResponse env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<result xsi:type="xsd:string">Hello, RPC-encoded, Ping, Ma</result>
</ns0:helloResponse>
</env:Body>
</env:Envelope>

参考文献
1. 《我应该采用哪一种 WSDL 样式?》 作者:
http://www.ibm.com/developerworks/cn/webservices/ws-whichwsdl/
2. 《SOAP中 RPC/ENC 为什么被抛弃?》作者: http://www.javaeye.com/topic/145061

WebService_004:UDDI介绍

【UDDI】:Universal Description, Discovery, and Integration。

2008年1月2日星期三

WebService_003:WSDL介绍

进入IT界10年以来,我一直有这样一个憧憬:
1. 希望用一种语言中立的接口定义语言来描述服务的接口。
2. 希望可以用任何一种技术来是实现这个接口。
3. 希望访问这些服务的时候不必在意它是用哪一种技术实现的。
今天,答案早已经不是什么秘密,它就是WSDL。
【WSDL】: Web Services Description(Definition)Language Web服务描述(定义)语言。
WSDL描述Web服务的公共接口。WSDL基于XML,采用抽象语言描述服务支持的操作和信息,实际使用时再将的具体的网络协议和信息格式绑定给该服务。WSDL由W3C制定,读音为:“Whuz-Duhl”。WSDL的流行版本是1.1,
http://www.w3.org/TR/wsdl;最新版本是2.0 http://www.w3.org/TR/wsdl20/
1. types:a container for data type definitions using some type system (such as XSD)。types定义交换消息的数据类型。为了实现互操作性(interoperability)和平台独立性(neutrality),WSDL选用XML Schema 作为标准数据类型。
<types>
<xsd:schema .... />*
</types>


2. message:an abstract, typed definition of the data being communicated.
message由若干个part构成。每个part都与某种数据类型相关联。
<message name="nmtoken"> *
<part name="nmtoken" element="qname"? type="qname"?/> *
</message>


3. portType:an abstract set of operations supported by one or more endpoints.
端口类型由一个抽象操作和抽象消息构成。
<portType name="nmtoken"> *
<operation name="nmtoken">
<input name="nmtoken"? message="qname"/>
<output name="nmtoken"? message="qname"/>
<fault name="nmtoken" message="qname"/>*
</operation>
</portType >


4. binding:a concrete protocol and data format specification for a particular port type.
(1)SOAP binding
<binding…>
<soap:binding style="rpc or document" transport="uri">
<operation…>
<soap:operation soapAction="uri"? style="rpc or document"?>?
<input>
<soap:body parts="nmtokens"? use="literal or encoded" encodingStyle="uri-list"? namespace="uri"?>
<soap:header element="qname" fault="qname"?>*
</input>
<output>
<soap:body parts="nmtokens"? use="literal or encoded" encodingStyle="uri-list"? namespace="uri"?>
<soap:header element="qname" fault="qname"?>*
</output>
<fault>*
<soap:fault name="nmtoken" use="literal or encoded" encodingStyle="uri-list"? namespace="uri"?>
</fault>
</operation>
</binding>
其中 transport="http://schemas.xmlsoap.org/soap/http" 表示传输方式和SOAP规范的HTTP绑定相一致 。


(2)Java binding(3)EJB binding
(4)JMS binding
(5)HTTP binding




5. service:a collection of related endpoints.<service name="nmtoken">*
<port name="nmtoken" binding="qname"/>*
</service>


6. port:a single endpoint defined as a combination of a binding and a network address.

小结:
(1)
一个portType可以对应多个binding,因为抽象的操作和消息定义可以由不同的技术来实现。
(2)
一个binding可以对应多个port,因为同样的技术实现可以有多个访问地址。


WSDL支持4种消息交换方式:
1.单向(One-way):服务访问端点接收消息。
<operation name="nmtoken">
<input name="nmtoken"? message="qname"/>
</operation>

2.请求响应(Request-response):服务访问端点接收请求消息,然后发送响应消息。
<operation name="nmtoken" parameterOrder="nmtokens">
<input name="nmtoken"? message="qname"/>

<output name="nmtoken"? message="qname"/>
<fault name="nmtoken" message="qname"/>*
</operation>

3.要求应答(Solicit-response):服务访问端点发送要求消息,然后接收应答消息。
<operation name="nmtoken" parameterOrder="nmtokens">
<output name="nmtoken"? message="qname"/>
<input name="nmtoken"? message="qname"/><fault name="nmtoken" message="qname"/>*
</operation>


4.通知(Notification):服务访问端点发送通知消息。
<operation name="nmtoken">
<output name="nmtoken"? message="qname"/>
</operation>

MovieEnglish_006:经典粗口台词


  1. 1. His outfit bugs me. 他的穿着让我看了不爽。bug 在这里作动词,表示“烦到某人”,很像中文里“不爽”,千万不要在正式场合使用。可以用形容词disturbing,让人不快的。相似的还有一个词组叫piss sb off 意思接近,语气比bug更加粗鲁。
  2. mess with sb. 耍某人,“唬弄”某人。如果别人告诉你"don't mess with me",就是说,“老子不是好惹的”或者说“别忽悠我”。
  3. I don't give a damn./ I don't give a shit./ I don't give a tiny rat's ass. 我一点都不在乎。其实更确切地说是,“老子他妈的一点都不在乎”。 这句话是电影《乱世佳人》中男主角的经典台词,曾经被美国某杂志评选为“史上100句最经典台词”的冠军,曾经被无数电影抄袭过,但是,尽管有这么多的荣誉,但它还是一句脏话。
  4. sb/sth sucks 某人/某物很烂,很菜,很逊...,比如 the game sucks, the movie sucks, I suck at maths……仅限于“自己人”之间互相损人。
  5. kick-ass 极好的,接近中文的“牛B”,是一个表示高度赞扬、却总让人不是个滋味的词。
  6. holy asses / holy shit/crap / holy smoke / holy cricket / holy balls


MovieEnglish_005:《不眠西雅图》经典台词

  1. Work hard! Work will save you. Work is the only thing that will see you through this. 努力工作吧!工作能拯救你。埋头苦干可令你忘记痛楚。
  2. You make millions of decisions that mean nothing and then one day your order takes out and it changes your life. 你每天都在做很多看起来毫无意义的决定,但某天你的某个决定就能改变你的一生。
  3. Destiny takes a hand. 命中注定。
  4. You know, you can tell a lot from a person's voice. 从一个人的声音可以知道他是怎样的人。
  5. People who truly loved once are far more likely to love again. 真爱过的人很难再恋爱。
  6. You know it's easier to get killed by a terrorist than get married over the age of 40. 你知道,女人过了40想出嫁就难了,被恐怖分子杀死都比这容易。
  7. You are the most attractive man I ever laid ears. 你是我听过的最帅的男士。
  8. Why would you want to be with someone who doesn't love you? 为什么留恋一个不爱你的人?
  9. When you are attracted to someone it just means that your subconscious is attracted to their subconscious,subconsciously. So what we think of as fate, is just two neuroses knowing they are a perfect match. 当你被某个人吸引时,那只是意味着你俩在潜意识里相互吸引。因此,所谓命运,就只不过是两个疯子认为他们自己是天造一对,地设一双。
  10. Everybody panics before they get married. 每个人婚前都会紧张的。
  11. Your destiny can be your doom. 命运也许会成为厄运。
  12. The reason I know this and you don't is because I'm younger and pure. So I'm more in touch with cosmic forces. 之所以我知道而你不知道是因为我年幼纯洁,所以我比较能接触宇宙的力量。
  13. I don't want to be someone that you're settling for. I don't want to be someone that anyone settles for. 我不想要你将就,我也不想成为将就的对象。
  14. What if something had happened to you? What if I couldn't get to you? What would I have done without you? You're my family. You're all I've got. 要是你出了事怎么办?要是我找不到你怎么办?如果没有你我该怎么办?你是我的家人,你是我的一切。



MovieEnglish_004:《乱世佳人》经典台词


  1. Land is the only thing in the world worth working for, worth fighting for, worth dying for. Because it is the only thing that lasts. 土地是世界上唯一值得你去为之工作, 为之战斗, 为之牺牲的东西,因为它是唯一永恒的东西。
  2. I wish I could be more like you. 我要像你一样就好了。
  3. Whatever comes, I'll love you, just as I do now. Until I die. 无论发生什么事,我都会像现在一样爱你,直到永远。
  4. I think it's hard winning a war with words. 我认为纸上谈兵没什么作用。
  5. Sir, you're no gentleman. And you miss are no lady. 先生,你可真不是个君子;小姐,你也不是什么淑女。
  6. I never give anything without expecting something in return. I always get paid. 我做任何事不过是为了有所回报,我总要得到报酬。
  7. In spite of you and me and the whole silly world going to pieces around us, I love you. 哪怕是世界末日我都会爱着你。
  8. If I have to lie, steal, cheat or kill, as God as my witness, I'll never be hungry again! 即使让我撒谎、去偷、去骗、去杀人,上帝作证,我再也不要挨饿了!
  9. Now I find myself in a world which for me is worse than death. A world in which there is no place for me. 现在我发现自己活在一个比死还要痛苦的世界,一个无我容身之处的世界。
  10. You're throwing away happiness with both hands. And reaching out for something that will never make you happy. 你把自己的幸福拱手相让,去追求一些根本不会让你幸福的东西。
  11. Home. I'll go home. And I'll think of some way to get him back. After all, tomorrow is another day. 家,我要回家。我要想办法让他回来。不管怎样,明天又是全新的一天。


MovieEnglish_003:《肖恩克的救赎》经典台词

  1. I guess it comes down to a simple choice:get busy living or get busy dying. 生命可以归结为一种简单的选择:要么忙于生存,要么赶着去死。
  2. These walls are kind of funny like that. First you hate them, then you get used to them. Enough time passed, get so you depend on them. That's institutionalized. 监狱里的高墙实在是很有趣。刚入狱的时候,你痛恨周围的高墙;慢慢地,你习惯了生活在其中;最终你会发现自己不得不依靠它而生存。这就是体制化。
  3. Fear can hold you prisoner. Hope can set you free. A strong man can save himself. A great man can save another. 懦怯囚禁人的灵魂,希望可以感受自由。强者自救,圣者渡人。
  4. Hope is good thing, maybe the best of things. And no good thing ever dies. 希望是个好东西,也许是最好的东西。美好的东西是永远不会死的。
  5. I find I’m so excited. I can barely sit still or hold a thought in my head. I think it the excitement only a free man can feel, a free man at the start of a long journey whose conclusion is uncertain. I hope I can make it across the border. I hope to see my friend, and shake his hand. I hope the Pacific is as blue as it has been in my dreams. I hope. 我发现自己是如此的激动,以至于不能静静地坐下来思考。我想只有那些重获自由即将踏上新征程的人们才能感受到这种即将揭开未来神秘面纱的激动心情。我希望跨越千山万水握住朋友的手,我希望太平洋的海水如同梦中的一样蓝:我希望。
  6. I have no idea to this day what those two Italian ladies were singing about. Truth is, I don’t want to know. Some things are better left unsaid.I’d like to think they were singing about somethings so beautiful,it can" t expressed in words,and it makes your heart ache because of it.I tell you, those voices soared higher and farther than anybody in a great place dares to dream. It was as if some beautiful bird had flapped into our drab little cage an d made these walls dissolve away, and for the briefest of moments, every last man is Shawshank felt free. 到今天我还不知道那两个意大利娘们在唱些什么,其实,我也不想知道。有些东西还是留着不说为妙。我像她们该是在唱一些非常美妙动人的故事,美妙得难以用言语来表达,美妙的让你心痛。告诉你吧,这些声音直插云霄,飞得比任何一个人敢想的梦 还要遥远。就像一些美丽的鸟儿扑扇着翅膀来到我们褐色牢笼,让那些墙壁消失得无影无踪。就在那一刹那,鲨堡监狱的每一个人都感到了自由。
  7. There's not a day goes by I don't feel regret. Not because I'm in here, or because you think I should. I look back on the way I was then. Then a young, stupid kid who committed that terrible crime. I want to talk to him. I want to try and talk some sense to him, tell him the way things are. But I can't. That kid's long gone and this old man is all that's left. I got to live with that. Rehabilitated? It's just a bull.......... word. So you go on and stamp your form, sorry, and stop wasting my time. Because to tell you the truth, I don't give a shit. 我无时不刻地对自己的所作所为深感内疚,这不是因为我在这里(指监狱),也不是讨好你们(指假释官)。回首曾经走过的弯路,我多么想对那个犯下重罪的愚蠢的年轻人说些什么,告诉他我现在的感受,告诉他还可以有其他的方式解决问题。可是,我做不到了。那个年轻人早已淹没在岁月的长河里,只留下一个老人孤独地面对过去。重新做人?骗人罢了!小子,别再浪费我的时间了,盖你的章吧,我不会再废话了。
  8. Here’s where it makes the most sense. You need it so you don't forget. Forget that there are place in the world that aren’t made out of stone That there’s a---there's a---there’s something inside that’s yours, that they can't touch. 这就是意义所在。你需要它,就好像自己不要忘记。忘记世上还有不是用石 头围起来的地方。忘记自己的内心还有你自己的东西,他们碰不到的东西。
  9. That’s the beauty of music. They can’t take that away from you. 这就是音乐的美丽。他们无法把这种美丽从你那里夺去。
  10. You know some birds are not meant to be caged, their feathers are just too bright. 你知道,有些鸟儿是注定不会被关在牢笼里的,它们的每一片羽毛都闪耀着自由的光辉。
  11. Let me tell you something my friend: Hope is a dangerous thing. Hope can drive a man insane.听我说,朋友,希望是件危险的事。希望能叫人发疯。 
  12. There is something inside ,that they can't get to , that they can't touch. That's yours.
    那是一种内在的东西,他们到达不了,也无法触及的,那是你的。

MovieEnglish_002:《阿甘正传》经典台词

  1. His back is as crooked as a politician. 他的后背就像一个政客那样弯曲。
  2. Life was like a box of chocolates, you never know what you're gonna get. 生命就像一盒巧克力,结果往往出人意料。
  3. There is an awful lot you can tell about a person by their shoes.Where they're going. Where they've been. 通过人家的鞋可以了解别人很多的东西。
  4. You are no different than anybody else is. 你和别人没有任何的不同。
  5. Stupid is as stupid does. 蠢人就是做蠢事(傻人有傻福)。
  6. Miracles happen every day. 奇迹每天都在发生。
  7. Jenny and I was like peas and carrots. 我和珍妮形影不离(豌豆和胡萝卜丁,一个圆的,一个方的;一个红的,一个绿的。美国主妇烹饪时做为主食的点缀,而且它俩都是同时出现。故引申为形影不离)。
  8. There must be someing can be done. 不同的语境可以传递不同的信息,在电影里阿甘妈妈一侧身,眼神里充满的诱惑,对校长暧昧的说了这句话。校长没有领会错她的意思。
  9. Sure as hell was. 绝对可信,铁板定钉了,敢以人格担保的可信,就是这种感觉。
  10. Have you given any thought to your future? 你有没有为将来打算过呢?
  11. Nobody gives a horse's shit who you are,puss ball. 没人在乎你是谁,你个娘炮儿(女里女气的男人)。
  12. Get your maggoty ass on the bus. 滚到车上来!
  13. That is the outstanding answer I've ever heard. 这是我听到的最棒的回答。(夸奖别人一定要把这句话挂在嘴上。)
  14. You just stay away from me please. 求你离开我。
  15. If you are ever in trouble, don't try to be brave, just run, just run away. 你若遇上麻烦,别逞强,你就跑,远远跑开。
  16. Just like that ,she was gone. 就这样,她走了。
  17. It made me look like a duck in water. 它让我如鱼得水。
  18. I am a man of my word. 我是信守我承诺的人。
  19. There is only so much of fortune a man really needs and the rest is just for showing off. 一个人真正需要财富的就那么一点点,其余的都是用来炫耀的。
  20. I was messed up for a long time. 这些年我过得一塌糊涂。
  21. I don't know if we each have a destiny,or if we're all just floating around accidentally——like on a breeze. 我不懂我们是否有着各自的命运,还是只是到处随风飘荡。
  22. You have got to put the past behind you before you can move on. 放下包袱,才能继续前进。
  23. It's my time. It's just my time. Oh, now, don't you be afraid sweetheart. Death is just a part of life, something we're all destined to do. I didn't know it. But I was destined to be your momma. I did the best I could. 我的时间到了。哦,别害怕,宝贝儿。死亡是生命的一部分,是我们注定要去做的一件事。我不知道它是怎么一回事,但我注定是你的妈妈,并且我尽我的全力去做好。
  24. It was like just before the sun goes to bed down on the bayou.There was a million sparkles on the river. 就像太阳在落山前映射在河口上,有无数的亮点在闪闪发光。
  25. If there is anything you need I will not be far away. 让人心碎的一句,无法翻译。
参考文献:
1. http://www.generationterrorists.com/quotes/gump.html
2. http://www.imdb.com/title/tt0109830/quotes

2008年1月1日星期二

WebService_002:SOAP介绍

WebService_001:WebService是个啥东东?

让我们以一个问题开始我们的话题:给你XMLHTTP,你能创造出什么?
答案可能是五花八门,千差万别。我比较倾向的回答是:分布式XML应用。
这当然不是我想到的,你可能觉得这个回答没啥了不起,觉得自己也能想到——但我必须承认,我想不到,虽然在那个时候,我会做些Web开发,也懂得XML的各种好处,但是把这两个东西放在一起,我却不知道能做什么。让我们感谢那些“遇事总是要问为什么”的人,是他们推动了科技的进步。
XML + HTTP = 分布式XML应用
这是一个天才的主意,虽然这个主意一开始还很不成熟,但是没有这个最初的想法,就没有我们要谈论的WebService。今天,几乎所有人都知道了WebService——但是真的是很清楚了吗?那么,我问你:什么是WebService?
嘿嘿,我Google了一圈,没有找到一个让我满意的答案。最后,我决定采用下面这个说法:
“A web service is a piece of business logic, located somewhere on the Internet, that is accessible through standard-based Internet protocols such as HTTP or SMTP.”(摘自《Java Web Service》)
这个定义起码说清楚了WebService是干吗用的,以什么样的方式用。
Web服务的核心特征:


  • XML-based:基于XML的数据传输方式。

  • Loosely coupled:松耦合。Web服务接口改变,而客户端无需改变。

  • Coarse-grained:粗粒度。业务接口应该是粗粒度的。(后面有专文讨论粒度问题)

  • Support synchronous and asynchronous:支持同步和异步。

  • Supports Remote Procedure Calls (RPCs):支持远程调用。

  • Supports document exchange:支持文档交换。

Web服务的核心技术:


  • SOAP

  • WSDL

  • UDDI
参考文献
1. 《Java Web Service》 作者 David Chappell 和 Tyler Jewell。
2. 《Java SOAP 编程指南》 作者 Henry Bequet 译者 魏海萍 于晓菲 毛选。

MovieEnglish_001:《借刀杀人》经典台词

借刀杀人 Collateral (2004)
导演: 迈克尔·曼
编剧: Stuart Beattie
主演: 汤姆·克鲁斯 / 杰米·福克斯 / 贾达·萍克·史密斯 / 马克·鲁弗洛 / 彼得·博格 /
类型: 剧情 / 惊悚 / 犯罪
制片国家/地区: 美国
语言: 英语 / 西班牙语
上映日期: 2004-08-06 (美国)
片长: 120 分钟
又名: 同行杀机 / 落日杀神 / 间接伤害


  1. 17 million people. This was a country, it would be the fifth bigest economy in the world. But nobody knows each other. Too impersonal.But there is just me, you know,I read about this guy. Gets on the MTA, here, and dies. Six hours he's riding the subway before antbody notices.This corpse doing laps around LA, people on and off, sitting next to him, nobody notice.
    一千七百万人口,国内第五大经济体,但是人们彼此就陌生的很。我刚看报说一个人在巴士上死了,尸体在车上逛了六个小时,一堆人上上下下,坐在他身旁都没注意到。
  2. Get with it .Get over it.....millions of galaxies of hundreds of milloins of stars and a speck on one in a blink...that's us. Lost in space.The universe don't care. The cop, you, me? who notices.
    实际一点吧。这宇宙有千千万万颗星星,其中最微小的那个...就是我们。眨一眼就迷失于太空。那警察、你、我...谁会留意到?
  3. Someday? someday my dream'll come...?
    And one night you will wake up, and you will discover it never happened.It's all turned around on you.It never will.Suddenly you are old. Didn't happen. And it never will.Cause you were never gonna do it anyway.You will push it into memory,then zone out in your Barcalounger, being hypnotized by daytime TV for the rest of your life. Don't you talk to me about murder.All it ever took was a down payment on a Lincoln Town car.Or that girl.You can't even call that girl.What the hell are you still doing in a cab?What the fuck are you still doing driving a cab?
    有一天?有一天梦想会成真?有一天晚上你会醒来,发现梦想没成真。根本不会成真!猛然间,你年华已逝。梦想从未发生过,而且永远不会发生,因为你根本没有尝试去做!你会把梦想压抑在记忆里,你的余生是这样度过的:睡在躺椅里一边做白日梦一边被电视催眠。别跟我谈论谋杀。有本事你先付首付买一辆豪华出租车,或者追一下你喜欢的那个女孩,你甚至不敢打电话给她。我说你他妈干嘛还在开出租车?
  4. Cause I never straightened up and looked at it, you know, myself.I should have. I've tried to gamble my way out from under, but that was just a born-to-lose deal. 
    因为我从没有勇气直面我自己。我本该这样尝试一次的。我试图从低谷中摆脱出来,可那不过是一次注定失败的尝试。
  5. 人们的心里总有一个梦想,但那个梦想却很遥远,永远无法实现,这是一个很残酷的现实。为什么无法实现?因为不敢,因为怕做了以后所剩下的这一点点也会化为乌有,就像是赌博一样,然后每天仍然上着班,做着该做的事。
  6. 心里头继续放着那些永不会实现的梦想,梦想很大,想得很远,紧紧抓着不放,然后越来越发现时间不停的逝去,自己开始渐渐老去,然而梦想越来越远,重复的日子,重复的想法,每天不断的循环。很多人过着这样的生活。
  7. 有人靠杀人过日子,有人每天炒股票,有人开出租车,有人搞设计,有人抓坏人,有人卖毒品,有人用身体赚钱,有人写程序,有人当小混混,有人做业务靠嘴,有人在家当贤妻良母,有人靠打棒球过活,有人没有工作呆在家里想着下一顿,有人靠抢钱过日子,有人想尽办法靠提高知名度赚钱。
  8. 追求什么样的生活?追求心灵上的平静?还是一夜致富的快感?享受生命无心的可能性放手一搏?为什么不呢?需要的是机会,一个对的时间!
  9. 如果我们不在乎卢旺达数百万人在日落之前惨遭屠杀这样的事实,你凭什么对我杀死一个和你毫不相干的人耿耿于怀? (这是我的工作,无关乎任何的道德和情感因素在里面)