Arjen Poutsma谈Spring Web Services

Spring Framework作为一种更轻量化的“企业”框架选择,它在Java开发人员中非常流行。最新增加的其中一项是Spring Web Services子项目,根据网站上的说法,是“专注于创建文档驱动(document-driven)的Web Services,[并]帮助推动契约优先(contract-first)的SOAP服务开发,允许利用操作XML payloads的多种方法之一来创建灵活的Web Services。

InfoQ的Stefan Tilkov和Spring Web Services的创建者Arjen Poutsma进行了一次对话,谈到了整体的Web Services,并特别讨论了Spring的支持。

InfoQ:您能向我们介绍一下您自己吗?

Arjen Poutsma(以下简称AP):我是Interface21的高级顾问。我现在从事企业应用程序开发已经13年了,刚开始用C++,后来用Java,有两年我还从事过一些.NET的开发。我大约四年前开始对Web Services感兴趣,并且建议了一些大公司如何去实现它们。

在刚过去的一年半中,我一直在从事Spring Web Services项目,这是Spring Portfolio中的一个产品,专注于创建契约优先、文档驱动的Web Services。近来,我们已经发布了Spring Web Services的Milestone 3,我们还计划在2007年的第二季度发布1.0。

InfoQ:构建Spring Web Services的主要动机是什么?Java还没有足够的Web Services框架吗?

AP:在我作为顾问的工作中,我遇到过Web Services有严重问题的客户。例如,他们想要维护一个Service契约的多个版本,或者直接处理得到的XML,而不用先转化成对象。当时,现成的 SOAP堆栈专注于使“SOAP化”现有的Java类变得更容易,而不是正确地完成它:从编写一个Service契约开始,并编写可以处理得到的XML的类。虽然有可能进行契约优先的Web Service设计,但也不容易。就像整个Spring Portfolio所做得那样,Spring Web Services使得以正确方式进行变得更加容易,并向人们展示了如何使Web Services符合他们现有的架构。

InfoQ:许多人认为,将XML转化成对象再转化回来,这正是他们在Web Services堆栈中寻求的功能。您对此似乎并不认同——能解释一下吗?

AP:我认为开发人员应该要能选择以他们想要的方式来处理得到的XML,XML封送(marshalling)就是一种(方便的)方式。

然而,XML封送有几个问题。其中一个就是有些封送引擎十分脆弱,例如,当它们遇到它们不能识别的XML时就会爆炸,这真的不太符合Postel法则(发送时严谨,接收时宽松)。

另一个问题是,在面向对象的语言如Java或者C#,和基于树的语言如XML之间有许多结构上的差别。例如以对象图为例。我们假设有一个Person类,它有一个spouse(配偶)属性,以便spouse的spouse指向同一个对象。用XML表示这种关系并没有标准的方法;你只能求助于定制机制。另一个问题是数据类型的:在Java中我们有一个java.util.Map,它一般有两个实现(HashMap和TreeMap)。XML Schema(XSD)没有字典结构的数据类型,因此当我将一个HashMap封送给XML时会发生什么呢?

我希望从中得到某种XML,但是当我再次解封它时,我就可能得不到与当初相同的HashMap了。

因此没有透明封送这回事,就像没有透明的对象持久化一样。你必须指示封送引擎如何将你的对象转化成XML,就像你指示一个对象/关系映射工具在SQL和对象之间进行转化一样。这就是我更喜欢称它为对象/XML映射而不是封送的原因,因为这显然也要注意对象/XML阻抗不匹配的问题。

InfoQ:您对JAX-RPC/JAX-WS怎么看?

AP:JAX-RPC发布时,人们只是把Web Services当成远程过程调用(Remote Procedure Calls)的另一种方法。规范的名称明显说明了这一点。在那些年里,我们发现像RPC这样进行Web Services的行为驱动方式,并不是最佳的前进方式。它导致客户端和服务之间更加紧耦合,并且完全忽略了像延时、失败、缺乏共享的内存访问等东西。像消息这样的数据驱动法反而更适合。

JAX-WS是JAX-RPC的一种改进。我特别喜欢的东西是Provider API,它提供了一种处理得到的SOAP请求的消息关注方式。我不喜欢的是,规范的其余内容仍然十分关注RPC,并且强烈依赖Java 5特性,即使有很好的Java 1.4时也一样。好像目前出现的每一个JSR都必须定义一对注解。外面仍然有许多Java 1.4甚至1.3的用户,他们无法使用泛型(generic)、枚举(enum)和注解(annotation),当你使用上述的Provider API时这三种都需要。

InfoQ:是什么东西使Spring Web Services变得如此独树一帜,为什么我要用它而不用Axis、XFire或者ActiveSOAP?

AP:Spring Web Services有几个独特的特性。首先,它完全专注于契约优先的Web Service设计。这基本上意味着你必须编写自己定义XML消息的XSD Schema。你可以引用WSDL中的Schema(虽然Spring Web Services也可以从XSD中生成WSDL),并将它用于验证。值得关注的事情是,当人们使用契约优先的开发风格时,他们在Web Services方面的许多互通性问题就消失了。这就是契约优先之所以被普遍当作是一种最佳实践的原因。你基本上是在设计一个XML API:你用Java实现这个API的事实,只是没有客户会在意的一个实现细节而已。

其次,Spring Web Services提供了契约和实现之间的一种松耦合:没有wsdl2java工具将契约直接连接到一个类;而是用你喜欢的任何方式(DOM、SAX、 StAX,甚至XML封送技术如JAXB、Castor、JIBX或者XMLBeans),实现处理得到的XML的端点(endpoint)。你将得到的请求映射到端点的方式,完全由你自己决定;默认情况下,我们提供基于消息内容的映射,或者SOAPAction Header。主要的思想是,你不用处理方法调用,而是处理XML消息。

最后,你可以从Spring项目中期待这些特性:

  • WS-Sercurity实现与Acegi Security整合;
  • JMS支持使用Spring 2的Message Driven POJO;
  • 主客户端类(WebServiceTemplate)提供一种类似于JdbcTemplate的API;
  • XML封送支持完全独立于Web Services(以便它可以用在其他的设置中);
  • 它适用于JDK 1.4及以上版本(虽然也有特定于Java 5的特性)。

InfoQ:因此在默认情况下,我的应用程序是从消息传送XML的?以哪种形式——以DOM树、流、Reader还是其他形式?

AP:应用程序传送一个XML输入抽象进行读取,并且一个输出抽象写入(相应为javax.xml.transform.Source和 javax.xml.transform.Result)。这样你的代码就不依赖任何特殊的XML处理API了。这个机制的实际实现取决于你选择使用的消息工厂。我们给SOAP提供了两种工厂:默认的是基于SAAJ的(javax.xml.soap,J2EE 1.4的一部分),它在底层使用DOM。对于更大的消息,我们支持Axis2的AXIOM,它使用一种StAX流。

InfoQ:Spring Web Services如何处理WS-*标准——你能开箱即用地支持它们中的任何一种标准吗?

AP:Spring Web Services支持SOAP 1.1和1.2、WS-Security,并支持在XSD Schema里面生成1.1 WSDL,WS-Addressing计划在1.0中发布。我基本上趋向于等到有足够的用户请求它时才会实现一种标准。目前为止,人们似乎对现状十分满意。

InfoQ:你对WS-*的前景整体上怎么看?

AP:嗯,有一部分我喜欢,有一部分不喜欢。我喜欢SOAP,我认为它是跨传输器发送XML消息的一种很好的方式。我不太喜欢WSDL,因为它提供了一个几乎是面向对象的Web Service模型,包含操作、接口等等,它不太适合SOAP。因为SOAP没有操作,它只是一种XML消息。从这一点上来说,我更喜欢SSDL(SOAP Service Description Language)。

我喜欢WS-Addressing的理念:把地址信息放在SOAP Header里面,但我不喜欢它有五个不同的不可兼容的版本在使用。基本上,如果有人告诉你他们的服务支持WS-Addressing,你就需要问:“你是支持2004年3月的版本,还是2004年8月的版本,或者其他的版本呢?”

最后,我认为WS-Security十分有用。它没有试图去重新发明轮子,而是在必要的地方使用XML-DSig和XML-Enc。

InfoQ:你对REST有什么评价,以及你认为Spring Web Services将来总有一天会支持它吗?

AP:我喜欢REST,我喜欢它通过把自身基于HTTP上,来解决我们在WS-*中面临的许多问题的方式,这是一种公认的技术。也就是说,我认为REST就像SOAP一样受限制,或者更甚。在编写一个REST服务时,你对于你有什么资源、你的哪些数据格式支持它们(REST不仅仅是关于 XML的!),以及它们意味着什么等等,都必须了然于胸。所有这一切也都必须清楚地写成文档,HTTP规范不足以达到这个目的。

许多人说他们在做REST,但是他们实际上在做的只是被Don Box称之为POX(Plain Old XML)的事情。POX是一种XML消息协议,在这里,你只要发送XML消息,而不需要用SOAP包将它封装起来。Spring Web Services已经支持这一点了。

至于“真正”的REST支持,我认为我们未来将会支持它,但不是在Spring Web Services的1.0版本中。它与SOAP和POX非常不同,例如,并不总是有XML消息进来。我们不想通过从HTTP请求中创建一个XML消息,将它射入3毫秒后要在那里被再次解析的管道中,以此来支持REST:这成本简直太高了。我们而是将把REST支持放在Spring-MVC中,它是 Spring的Web框架。

InfoQ:非常感谢!

****************************************************************************************************************************************************************************************************************************************************************

 

The Spring framework is very popular among Java developers as a more lightweight alternative to "enterprise" frameworks. One of the newest additions is the Spring Web Services subproject, which according to the Web site "is focused on creating document-driven Web services [and] aims to facilitate contract-first SOAP service development, allowing for the creation of flexible web services using one of the many ways to manipulate XML payloads."

InfoQ's Stefan Tilkov had a chance to talk to Spring web services creator Arjen Poutsma about Web services in general and the Spring support in particular.  

InfoQ: Can you tell us a little about yourself?

Arjen Poutsma (AP): I'm a Senior Consultant at Interface21. I've been doing Enterprise Application development for about 13 years now, first in in C++, then in Java, with a two-year period where I did some .NET development. I started to become interested in Web services about four years ago, and have advised some large corporations as to how to implement them.

For the last year-and-a-half I've been working on the Spring Web Services project, a product from the Spring portfolio focused on creating contract-first, document-driven Web services. Recently, we have released Milestone 3 of Spring Web Services, and we plan to release 1.0 in the second quarter of 2007.

InfoQ: What has been the main motivation for building Spring Web Services? Aren't there enough Web services frameworks for Java already?

AP:In my work as a consultant, I came across customers having major issues with their Web services. For instance, they wanted to maintain multiple versions of a service contract, or handle the incoming XML directly, without it being converted to an object first. At the time, existing SOAP stacks focused on making it easier to "SOAPify" existing Java classes, rather than do it the right way: start by writing a service contract, and write classes that can handle the incoming XML. While it was possible to do contract-first Web service design, it wasn't easy. Just as the entire Spring portfolio does, Spring Web Services makes the right way easier, and shows people how to fit Web services in their existing architecture.

Related Vendor Content

Top 10 Java Performance Problems

High Performance In-Memory Data Grids for Speed and Scale

Microservices vs. Service-Oriented Architecture (By O'Reilly) - Download Now

Getting Started with Clustering in R

Start your FREE TRIAL of AppDynamics Pro

Related Sponsor

Assets-Logo-RSB-02052017V3.png

 

Guided Tour: AppDynamics Application Performance Management

InfoQ: Many people would argue that converting XML to objects and back is exactly the functionality they're looking for in a Web services stack. You seem to disagree - can you elaborate?

AP:I think developers should have a choice to handle the incoming XML any way they want, XML marshalling being one (convenient) way.

However, there are several issues with XML marshalling. One of them is that some marshalling engines are quite fragile, i.e. they blow up when they come across XML they don't know about, which doesn't really fit well with Postel's Law (be conservative in what you send, be liberal in what you receive).

Another thing is that there is quite a structural difference between an object-oriented language such as Java or C#, and a tree-based language such as XML. Take object graphs, for example. Let's say that I have a Person class which has a spouse property, so that the spouse of a spouse point to the same object. There is no standard way to represent such a relationship in XML; you can only resort to a custom mechanism. Another issue is that of data types: in Java we have a java.util.Map, and basically two implementations of it (HashMap and TreeMap). XML Schema (XSD) does not have a datatype for a dictionary structure, so what happens when I marshal a HashMap to XML?

Hopefully, I will get some sort of XML out of it, but when I unmarshal it again, I will probably not end up with the same HashMap I started out with.

So there is no such thing as transparent marshalling, in the same way as there is no transparent object persistence. You will have to instruct the marshalling engine how to convert your objects to XML, much in the same way as you instruct an Object/Relational Mapper to convert between SQL and objects. That's why I prefer to call it Object/XML Mapping instead of marshalling, because it makes clear that there is also Object/XML impedance mismatch to take care of.

InfoQ: What's your opinion about JAX-RPC/JAX-WS?

AP:When JAX-RPC was released, people thought about Web services as just another way to do Remote Procedure Calls. The name of the specification clearly suggests this. During the years, we have figured out that a behavior-driven, RPC-like way of doing Web services is not the best way to go forward. It results in a tighter coupling between client and server, and also completely ignores things like latency, failure, lack of a shared memory access, etc. Instead, a data-driven, message-like methodology is a better fit.

JAX-WS is an improvement over JAX-RPC. The thing I particularly like is the Provider API, which offers an message-focussed way of handling incoming SOAP requests. What I don't like is fact that the rest of the specification is still pretty much focused on RPC, and that there is a strong dependance on Java 5 features, even when there are perfectly fine Java 1.4 alternatives. It seems like every JSR that comes out these days has to define a couple of annotations. There are still a lot of Java 1.4 or even 1.3 users out there, and they can't use generics, enums, and annotations, all three of which are required when you use the Provider API mentioned above.

InfoQ: What makes Spring Web Services unique, why would I use it instead of Axis, XFire or ActiveSOAP?

AP:Spring Web Services has a couple of unique features. Firstly, it's completely focussed on contract-first Web service design. This basically means that you have to write your own XSD schema that defines the XML messages. You can refer to that schema in a WSDL (though Spring Web Services can also generate the WSDL from the XSD), and possibly use it for validation purposes. The interesting thing is that a lot of the interoperability issues that people have with Web services disappear when they use a contract-first development style. That is why contract-first is generally considered to be a best practice. You are basically designing a XML API: the fact that you implement that API using Java is just an implementation detail which no client should care about.

Secondly, Spring Web Services provides a loose coupling between contract and implementation: there is no wsdl2java tool which directly ties the contract to a class; instead, you implement endpoints which handle the incoming XML in any way you want to (DOM, SAX, StAX, or even XML marshalling techniques such as JAXB, Castor, JIBX, or XMLBeans). The way you map incoming request to the endpoints is completely up to you: by default, we supply mappings that are based on message content, or the SOAPAction header. The main idea is that you're not handling method calls, but rather XML messages.

Finally, there are some features which you can expect from a Spring project:

  • the WS-Security implementation integrates with Acegi Security,
  • the JMS support uses Spring 2's Message Driven POJOs,
  • the main client-side class (WebServiceTemplate) offers an API similar to JdbcTemplate,
  • the XML marshalling support is completely independent of Web services (so that it can be used in other settings),
  • it works on JDK 1.4 and above (though there are also Java 5- specific features).

InfoQ: So by default, my application gets passed the XML from the message? In what form - as a DOM tree, a stream, a reader or something else?

AP:The application gets passed an XML input abstraction to read from, and a output abstraction to write to (javax.xml.transform.Source and javax.xml.transform.Result respectively). This way your code isn't tied to any particular XML handling API. The actual implementation of this mechanism depends on the message factory you choose to use. We offer two for SOAP: the default is based on SAAJ (javax.xml.soap, part of J2EE 1.4), which uses DOM underneath. For larger messages we support AXIOM from Axis2, which uses a StAX stream.

InfoQ: How does Spring Web Services handle WS-* standards - do you support any of them out of the box?

AP:Spring Web Services supports SOAP 1.1 and 1.2, WS-Security, and support for generating a 1.1 WSDL out of a XSD schema. WS-Addressing is planned in the post 1.0 timeframe. Basically, I tend to wait with implementing a standard until there is sufficient user request for it. So far, people seem pretty happy with what we have.

InfoQ: What is your general opinion on the WS-* landscape?

AP:Well, there are parts I like and parts I don't like. I like SOAP, I think it's a nice way to send XML messages across transports. I don't like WSDL that much, because it offers an almost object-oriented model of a Web service with operations, interfaces, etc., which doesn't fit well with SOAP. SOAP doesn't have operations, it is just an XML message. In that respect, I like SSDL (the SOAP Service Description Language) more.

I like the concept of WS-Addressing: to put addressing information in the SOAP Header, but I don't like the fact that there are five different, and incompatible versions of it in use. Basically, if someone tells you that their service supports WS-Addressing, you need to ask: "Do you support the March 2004 version, the August 2004 version, or any other version?"

And finally I think WS-Security is quite useful. It doesn't try to reinvent the wheel, but uses XML-DSig and XML-Enc where it made sense.

InfoQ: What's your take on REST, and do you think Spring Web Services will support it some day?

AP:I like REST, I like the way it solves a lot of problems we face in the WS-* space by basing itself on HTTP, a proven technology. That said, I think that REST is just as, or even more restrictive than SOAP is. When writing a REST service, you have to have a clear idea about what your resources are, which data formats you support for them (REST is not just about XML!), which HTTP methods you support on them, and what they mean. All of this has to be clearly documented as well; the HTTP specification isn't enough for this purpose.

A lot of people say they do REST, but what actually do is something Don Box has named POX (Plain Old XML). POX is an XML messaging protocol, where you simply send XML message, without the SOAP envelope wrapped around it. Spring Web Services already supports this.

Regarding "true" REST support, I think we will support it in the future, but not in the 1.0 version of Spring Web Services. It is very different from SOAP and POX, for instance, there is no XML message coming in at all time. We don't want to support REST by creating a XML message from an HTTP request, shooting that into the pipeline where three milliseconds later it gets parsed again: that's simply too expensive. Instead, we will base the REST support on Spring-MVC, Spring's Web framework.

InfoQ: Thank you for your time!

转载于:https://my.oschina.net/weaver/blog/866270

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值