﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-我是北航MSE-随笔分类-Web Service</title><link>http://www.blogjava.net/hopeshared/category/10128.html</link><description>静下心来，一切变得美好</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 11:22:54 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 11:22:54 GMT</pubDate><ttl>60</ttl><item><title>读Axis2用户帮助文档</title><link>http://www.blogjava.net/hopeshared/archive/2006/10/23/76785.html</link><dc:creator>hopeshared</dc:creator><author>hopeshared</author><pubDate>Mon, 23 Oct 2006 08:46:00 GMT</pubDate><guid>http://www.blogjava.net/hopeshared/archive/2006/10/23/76785.html</guid><wfw:comment>http://www.blogjava.net/hopeshared/comments/76785.html</wfw:comment><comments>http://www.blogjava.net/hopeshared/archive/2006/10/23/76785.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/hopeshared/comments/commentRss/76785.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hopeshared/services/trackbacks/76785.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 作者：李红霞时间：2006-10-19声明：本文可以算作Axis2用户手册的翻译，但是翻译后的文本是经过作者理解写出来的，可能有些偏差，欢迎讨论。本文属作者原创，允许转载，但请注明出处。						英文原文http://ws.apache.org/axis2/1_0/userguide.html														 															...&nbsp;&nbsp;<a href='http://www.blogjava.net/hopeshared/archive/2006/10/23/76785.html'>阅读全文</a><img src ="http://www.blogjava.net/hopeshared/aggbug/76785.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hopeshared/" target="_blank">hopeshared</a> 2006-10-23 16:46 <a href="http://www.blogjava.net/hopeshared/archive/2006/10/23/76785.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>服务设计的原则：服务模式与反模式（zz）</title><link>http://www.blogjava.net/hopeshared/archive/2006/09/27/72232.html</link><dc:creator>hopeshared</dc:creator><author>hopeshared</author><pubDate>Wed, 27 Sep 2006 03:04:00 GMT</pubDate><guid>http://www.blogjava.net/hopeshared/archive/2006/09/27/72232.html</guid><wfw:comment>http://www.blogjava.net/hopeshared/comments/72232.html</wfw:comment><comments>http://www.blogjava.net/hopeshared/archive/2006/09/27/72232.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hopeshared/comments/commentRss/72232.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hopeshared/services/trackbacks/72232.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 发布日期： 12/15/2005 | 更新日期： 12/15/2005						John Evdemon				Microsoft Corporation, Architecture Strategy 团队				适用于：																												•																						企业体系结构									...&nbsp;&nbsp;<a href='http://www.blogjava.net/hopeshared/archive/2006/09/27/72232.html'>阅读全文</a><img src ="http://www.blogjava.net/hopeshared/aggbug/72232.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hopeshared/" target="_blank">hopeshared</a> 2006-09-27 11:04 <a href="http://www.blogjava.net/hopeshared/archive/2006/09/27/72232.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Implementing REST Web Services: Best Practices and Guidelines</title><link>http://www.blogjava.net/hopeshared/archive/2006/08/31/66913.html</link><dc:creator>hopeshared</dc:creator><author>hopeshared</author><pubDate>Thu, 31 Aug 2006 09:26:00 GMT</pubDate><guid>http://www.blogjava.net/hopeshared/archive/2006/08/31/66913.html</guid><wfw:comment>http://www.blogjava.net/hopeshared/comments/66913.html</wfw:comment><comments>http://www.blogjava.net/hopeshared/archive/2006/08/31/66913.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hopeshared/comments/commentRss/66913.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hopeshared/services/trackbacks/66913.html</trackback:ping><description><![CDATA[
		<span class="secondary">by <a href="http://www.xml.com/pub/au/213">Hao He</a></span>
		<br />
		<span class="secondary">August 11, 2004<br /><br />Despite the lack of vendor support, <a href="http://www1.ics.uci.edu/%7Efielding/pubs/dissertation/rest_arch_style.htm">Representational State Transfer (REST)</a> web services have won the hearts of many working developers. For example, <a href="http://www.oreillynet.com/pub/wlg/3005">Amazon's web services</a> have both SOAP and REST interfaces, and 85% of the usage is on the REST interface. Compared with other styles of web services, REST is easy to implement and has many highly desirable architectural properties: scalability, performance, security, reliability, and extensibility. Those characteristics fit nicely with the modern business environment, which commands technical solutions just as adoptive and agile as the business itself. 
<p></p><p>A few short years ago, REST had a much lower profile than <a href="http://www.xml.com/pub/a/ws/2001/04/04/soap.html">XML-RPC</a>, which was much in fashion. Now XML-RPC seems to have less mindshare. People have made significant efforts to RESTize SOAP and WSDL. The question is no longer whether to REST, but instead it's become how to be the best REST?</p><p>The purpose of this article is to summarize some best practices and guidelines for implementing RESTful web services. I also propose a number of <a href="http://www.xml.com/pub/a/2004/06/23/standards.html">informal standards</a> in the hope that REST implementations can become more consistent and interoperable. </p><!-- sidebar begins --><!-- don't move sidebars --><!-- sidebar ends --><p>The following notations are used in this article: </p><ol><li>BP: best practice 
</li><li>G: general guideline 
</li><li>PS: proposed <a href="http://www.xml.com/pub/a/2004/06/23/standards.html">informal standard</a></li><li>TIP: implementation tip 
</li><li>AR: arguably RESTful -- may not be RESTful in the strict sense </li></ol><h3>Reprising REST</h3><p>Let's briefly reiterate the REST web services architecture. REST web services architecture conforms to the W3C's <a href="http://www.w3.org/TR/webarch/">Web Architecture</a>, and leverages the architectural principles of the Web, building its strength on the proven infrastructure of the Web. It utilizes the semantics of HTTP whenever possible and most of the <a href="http://www.w3.org/TR/webarch/">principles, constraints, and best practices published by the TAG</a> also apply.</p><p>The REST web services architecture is related to the <a href="http://webservices.xml.com/pub/a/ws/2003/09/30/soa.html">Service Oriented Architecture</a>. This limits the interface to HTTP with the four well-defined verbs: GET, POST, PUT, and DELETE. REST web services also tend to use XML as the main messaging format. </p><p>[<strong>G</strong>] Implementing REST correctly requires a resource-oriented view of the world instead of the object-oriented views many developers are familiar with.</p><h4>Resource</h4><p>One of the most important concepts of web architecture is a "resource." A resource is an abstract thing identified by a <a href="http://www.w3.org/Addressing/">URI</a>. A REST service is a resource. A service provider is an implementation of a service. </p><h4>URI Opacity [<strong>BP</strong>]</h4><p>The creator of a URI decides the encoding of the URI, and users should not derive metadata from the URI itself. URI opacity only applies to the path of a URI. The query string and fragment have special meaning that can be understood by users. There must be a shared vocabulary between a service and its consumers.</p><h4>Query String Extensibility [<strong>BP</strong>, <strong>AR</strong>]</h4><p>A service provider should ignore any query parameters it does not understand during processing. If it needs to consume other services, it should pass all ignored parameters along. This practice allows new functionality to be added without breaking existing services. </p><p>[<strong>TIP</strong>] <a href="http://www.w3.org/XML/Schema">XML Schema</a> provides a good framework for defining simple types, which can be used for validating query parameters.</p><h4>Deliver Correct Resource Representation [<strong>G</strong>]</h4><p>A resource may have more than one representation. There are four frequently used ways of delivering the correct resource representation to consumers:</p><ol><li>Server-driven negotiation. The service provider determines the right representation from prior knowledge of its clients or uses the information provided in HTTP headers like Accept, Accept-Charset, Accept-Encoding, Accept-Language, and User-Agent. The drawback of this approach is that the server may not have the best knowledge about what a client really wants. 
</li><li>Client-driven negotiation. A client initiates a request to a server. The server returns a list of available of representations. The client then selects the representation it wants and sends a second request to the server. The drawback is that a client needs to send two requests. 
</li><li>Proxy-driven negotiation. A client initiates a request to a server through a proxy. The proxy passes the request to the server and obtains a list of representations. The proxy selects one representation according to preferences set by the client and returns the representation back to the client. 
</li><li>URI-specified representation. A client specifies the representation it wants in the URI query string. </li></ol><h4>Server-Driven Negotiation [<strong>BP</strong>]</h4><ol><li>When delivering a representation to its client, a server MUST check the following HTTP headers: Accept, Accept-Charset, Accept-Encoding, Accept-Language, and User-Agent to ensure the representation it sends satisfies the user agent's capability. 
</li><li>When consuming a service, a client should set the value of the following HTTP headers: Accept, Accept-Charset, Accept-Encoding, Accept-Language, and User-Agent. It should be specific about the type of representation it wants and avoid "*/*", unless the intention is to retrieve a list of all possible representations. 
</li><li>A server may determine the type of representation to send from the profile information of the client. </li></ol><h4>URI-Specified Representation [<strong>PS</strong>, <strong>AR</strong>]</h4><p>A client can specify the representation using the following query string:</p><pre><code>mimeType={mime-type}</code></pre><p>A REST server should support this query.</p><h4>Different Views of a Resource [<strong>PS</strong>, <strong>AR</strong>]</h4><p>A resource may have different views, even if there is only one representation available. For example, a resource has an XML representation but different clients may only see different portion of the same XML. Another common example is that a client might want to obtain metadata of the current representation.</p><p>To obtain a different view, a client can set a "view" parameter in the URI query string. For example:</p><pre><code>
GET http://www.example.com/abc?view=meta</code></pre><p>where the value of the "view" parameter determines the actual view. Although the value of "view" is application specific in most cases, this guideline reserves the following words:</p><ol><li>"<code>meta</code>," for obtaining the metadata view of the resource or representation. 
</li><li>"<code>status</code>," for obtaining the status of a request/transaction resource. </li></ol><h3>Service</h3><p>A service represents a specialized business function. A service is safe if it does not incur any obligations from its invoking client, even if this service may cause a change of state on the server side. A service is obligated if the client is held responsible for the change of states on server side.</p><h4>Safe Service</h4><p>A safe service should be invoked by the GET method of HTTP. Parameters needed to invoke the service can be embedded in the query string of a URI. The main purpose of a safe service is to obtain a representation of a resource.</p><h4>Service Provider Responsibility [<strong>BP</strong>]</h4><p>If there is more than one representation available for a resource, the service should negotiate with the client as discussed above. When returning a representation, a service provider should set the HTTP headers that relate to caching policies for better performance.</p><p>A safe service is by its nature idempotent. A service provider should not break this constraint. Clients should expect to receive consistent representations. </p><h4>Obligated Services [<strong>BP</strong>]</h4><p>Obligated services should be implemented using POST. A request to an obligated service should be described by some kind of XML instance, which should be constrained by a schema. The schema should be written in W3C XML Schema or Relax NG. An obligated service should be made idempotent so that if a client is unsure about the state of its request, it can send it again. This allows low-cost error recovery. An obligated service usually has the simple semantic of "process this" and has two potential impacts: either the creation of new resources or the creation of a new representation of a resource.</p><h4>Asynchronous Services</h4><p>One often hears the criticism that HTTP is synchronous, while many services need to be asynchronous. It is actually quite easy to implement an asynchronous REST service. An asynchronous service needs to perform the following:</p><ol><li>Return a receipt immediately upon receiving a request. 
</li><li>Validate the request. 
</li><li>If the request if valid, the service must act on the request as soon as possible. It must report an error if the service cannot process the request after a period of time defined in the service contract. </li></ol><h4>Request Receipt</h4><p>An example receipt is shown below:</p><p><code>&lt;receipt xmlns="http://www.xml.org/2004/rest/receipt" requestUri = "http://www.example.com/xya343343" received = "2004-10-03T12:34:33+10:00"&gt;<br />  &lt;transaction uri="http://www.example.com/xyz2343" status = "http://www.example.com/xyz2343?view=status"/&gt;<br />&lt;/receipt&gt; </code></p><p>A receipt is a confirmation that the server has received a request from a client and promises to act on the request as soon as possible. The receipt element should include a received attribute, the value of which is the time the server received the request in WXS <code>dateTime</code> type format. The <code>requestUri</code> attribute is optional. A service may optionally create a request resource identified by the <code>requestUri</code>. The request resource has a representation, which is equivalent to the request content the server receives. A client may use this URI to inspect the actual request content as received by the server. Both client and server may use this URI for future reference. </p><p>However, this is application-specific. A request may initiate more than one transaction. Each transaction element must have a URI attribute which identifies this transaction. A server should also create a transaction resource identified by the URI value. The transaction element must have a status attribute whose value is a URI pointing to a status resource. The status resource must have an XML representation, which indicates the status of the transaction. </p><h4>Transaction</h4><p>A transaction represents an atomic unit of work done by a server. The goal of a transaction is to complete the work successfully or return to the original state if an error occurs. For example, a transaction in a purchase order service should either place the order successfully or not place the order at all, in which case the client incurs no obligation. </p><h4>Status URI [<strong>BP</strong>, <strong>AR</strong>]</h4><p>The status resource can be seen as a different view of its associated transaction resource. The status URI should only differ in the query string with an additional status parameter. For example: </p><p><code>Transaction URI: http://www.example.com/xyz2343 Transaction Status URI: http://www.example.com/xyz2343?view=status </code></p><h4>Transaction Lifecycle [<strong>G</strong>]</h4><p>A transaction request submitted to a service will experience the following lifecycle as defined in <a href="http://www.w3.org/TR/wslc/">Web Service Management: Service Life Cycle</a>:</p><ol><li>Start -- the transaction is created. This is triggered by the arrival of a request. 
</li><li>Received -- the transaction has been received. This status is reached when a request is persisted and the server is committed to fulfill the request. 
</li><li>Processing -- the transaction is being processed, that is, the server has committed resources to process the request. 
</li><li>Processed -- processing is successfully finished. This status is reached when all processing has completed without any errors. 
</li><li>Failed -- processing is terminated due to errors. The error is usually caused by invalid submission. A client may rectify its submission and resubmit. If the error is caused by system faults, logging messages should be included. An error can also be caused by internal server malfunction. 
</li><li>Final -- the request and its associated resources may be removed from the server. An implementation may choose not to remove those resources. This state is triggered when all results are persisted correctly. </li></ol><p>Note that it is implementation-dependent as to what operations must be performed on the request itself in order to transition it from one status to another. The state diagram of a request (taken from <a href="http://www.w3.org/TR/wslc/">Web Service Management: Service Life Cycle</a>) is shown below: </p><p></p><table cellspacing="0" cellpadding="0" width="500" align="center" border="0"><tbody><tr><td class="secondary"><img height="136" alt="The state diagram of a request (taken from Web Service Management: Service Life Cycle)" src="http://www.xml.com/2004/08/11/graphics/image004.png" width="500" border="0" /></td></tr></tbody></table><p>As an example of the status XML, when a request is just received: </p><p><code>&lt;status state="received" timestamp="2004-10-03T12:34:33+10:00" /&gt; </code></p><p>The XML contains a state attribute, which indicates the current state of the request. Other possible values of the state attribute are processing, processed, and failed. </p><p>When a request is processed, the status XML is (non-normative):</p><p><code>&lt;status state="processed" timestamp="2004-10-03T12:34:33+10:00" &gt;<br />  &lt;result uri="http://example.com/rest/1123/xyz" /&gt;<br />&lt;/status&gt; </code></p><p>This time, a result element is included and it points to a URL where the client can GET request results. </p><p>In case a request fails, the status XML is (non-normative):</p><pre><code>
&lt;status   state="failed" timestamp="2002-10-03T12:34:33+10:00" &gt;
  &lt;error code="3" &gt;
    &lt;message&gt;A bad request. &lt;/message&gt;
    &lt;exception&gt;line 3234&lt;/exception&gt;
  &lt;/error&gt;
&lt;/status&gt;</code></pre><p>A client application can display the message enclosed within the message tag. It should ignore all other information. If a client believes that the error was not caused by its fault, this XML may serve as a proof. All other information is for internal debugging purposes. </p><h4>Request Result [<strong>BP</strong>]</h4><p>A request result view should be regarded as a special view of a transaction. One may create a request resource and transaction resources whenever a request is received. The result should use XML markup that is as closely related to the original request markup as possible. </p><h4>Receiving and Sending XML [<strong>BP</strong>]</h4><p>When receiving and sending XML, one should follow the principle of "strict out and loose in." When sending XML, one must ensure it is validated against the relevant schema. When receiving an XML document, one should only validate the XML against the smallest set of schema that is really needed. Any software agent must not change XML it does not understand. </p><h3>An Implementation Architecture</h3><p></p><table cellspacing="0" cellpadding="0" width="500" align="center" border="0"><tbody><tr><td class="secondary"><img height="218" alt="An Implementation Architecture" src="http://www.xml.com/2004/08/11/graphics/restImpl.png" width="500" border="0" /></td></tr></tbody></table><p>The architecture represented above has a pipe-and-filter style, a classical and robust architectural style used as early as in 1944 by the famous physicist, Richard Feynman, to build the first atomic bomb in his computing team. A request is processed by a chain of filters and each filter is responsible for a well-defined unit of work. Those filters are further classified as two distinct groups: front-end and back-end. Front-end filters are responsible to handle common Web service tasks and they must be light weight. Before or at the end of front-end filters, a response is returned to the invoking client. </p><p>All front-end filters must be lightweight and must not cause serious resource drain on the host. A common filter is a bouncer filter, which checks the eligibility of the request using some simple techniques: </p><ol><li>IP filtering. Only requests from eligible IPs are allowed. 
</li><li>URL mapping. Only certain URL patterns are allowed. 
</li><li>Time-based filtering. A client can only send a certain number of requests per second. 
</li><li>Cookie-based filtering. A client must have a cookie to be able to access this service. 
</li><li>Duplication-detection filter. This filter checks the content of a request and determines whether it has received it before. A simple technique is based on the hash value of the received message. However, a more sophisticated technique involves normalizing the contents using an application-specific algorithm. </li></ol><p>A connector, whose purpose is to decouple the time dependency between front-end filters and back-end filters, connects front-end filters and back-end filters. If back-end processing is lightweight, the connector serves mainly as a delegator, which delegates requests to its corresponding back-end processors. If back-end processing is heavy, the connector is normally implemented as a queue. </p><p>Back-end filters are usually more application specific or heavy. They should not respond directly to requests but create or update resources. </p><p>This architecture is known to have many good properties, as observed by Feynman, whose team improved its productivity many times over. Most notably, the filters can be considered as a standard form of computing and new filters can be added or extended from existing ones easily. This architecture has good user-perceived performance because responses are returned as soon as possible once a request becomes fully processed by lightweight filters. This architecture also has good security and stability because security breakage and errors can only propagate a limited number of filters. However, it is important to note that one must not put a heavyweight filter in the front-end or the system may become vulnerable to denial-of-service attacks. </p><!-- sidebar begins --></span>
<img src ="http://www.blogjava.net/hopeshared/aggbug/66913.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hopeshared/" target="_blank">hopeshared</a> 2006-08-31 17:26 <a href="http://www.blogjava.net/hopeshared/archive/2006/08/31/66913.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>REST vs SOAP Web Services</title><link>http://www.blogjava.net/hopeshared/archive/2006/08/31/66911.html</link><dc:creator>hopeshared</dc:creator><author>hopeshared</author><pubDate>Thu, 31 Aug 2006 09:21:00 GMT</pubDate><guid>http://www.blogjava.net/hopeshared/archive/2006/08/31/66911.html</guid><wfw:comment>http://www.blogjava.net/hopeshared/comments/66911.html</wfw:comment><comments>http://www.blogjava.net/hopeshared/archive/2006/08/31/66911.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hopeshared/comments/commentRss/66911.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hopeshared/services/trackbacks/66911.html</trackback:ping><description><![CDATA[
		<p>I am seeing a lot of new web services are implemented using a <strong>REST</strong> style architecture these days rather than a SOAP one. Lets step back a second and explain what REST is.</p>
		<p>
				<strong>What is a REST Web Service</strong>
		</p>
		<p>The acronym REST stands for <em>Representational State Transfer</em>, this basically means that each unique URL is a representation of some object. You can get the contents of that object using an HTTP GET, to delete it, you then might use a POST, PUT, or DELETE to modify the object (in practice most of the services use a POST for this).</p>
		<p>
				<strong>Who's using REST?</strong>
		</p>
		<p>All of Yahoo's web services use REST, including Flickr, del.icio.us API uses it, pubsub, bloglines, technorati, and both eBay, and Amazon have web services for both REST and SOAP.</p>
		<p>
				<strong>Who's using SOAP?</strong>
		</p>
		<p>Google seams to be consistent in implementing their web services to use SOAP, with the exception of Blogger, which uses XML-RPC. You will find SOAP web services in lots of enterprise software as well.</p>
		<p>
				<strong>REST vs SOAP</strong>
		</p>
		<p>As you may have noticed the companies I mentioned that are using REST api's haven't been around for very long, and their apis came out this year mostly. So REST is definitely the trendy way to create a web service, if creating web services could ever be trendy (lets face it you use soap to wash, and you rest when your tired). The main advantages of REST web services are:</p>
		<ul>
				<li>Lightweight - not a lot of extra xml markup 
</li>
				<li>Human Readable Results 
</li>
				<li>Easy to build - no toolkits required </li>
		</ul>
		<p>SOAP also has some advantages:</p>
		<ul>
				<li>Easy to consume - sometimes 
</li>
				<li>Rigid - type checking, adheres to a contract 
</li>
				<li>Development tools </li>
		</ul>
		<p>For consuming web services, its sometimes a toss up between which is easier. For instance Google's AdWords web service is really hard to consume (in CF anyways), it uses SOAP headers, and a number of other things that make it kind of difficult. On the converse, Amazon's REST web service can sometimes be tricky to parse because it can be highly nested, and the result schema can vary quite a bit based on what you search for.</p>
		<p>Which ever architecture you choose make sure its easy for developers to access it, and well documented.<br /><br /><br /><br /><br />原文：<a href="http://www.petefreitag.com/item/431.cfm">http://www.petefreitag.com/item/431.cfm</a></p>
<img src ="http://www.blogjava.net/hopeshared/aggbug/66911.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hopeshared/" target="_blank">hopeshared</a> 2006-08-31 17:21 <a href="http://www.blogjava.net/hopeshared/archive/2006/08/31/66911.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Building Web Services the REST Way</title><link>http://www.blogjava.net/hopeshared/archive/2006/08/31/66907.html</link><dc:creator>hopeshared</dc:creator><author>hopeshared</author><pubDate>Thu, 31 Aug 2006 09:17:00 GMT</pubDate><guid>http://www.blogjava.net/hopeshared/archive/2006/08/31/66907.html</guid><wfw:comment>http://www.blogjava.net/hopeshared/comments/66907.html</wfw:comment><comments>http://www.blogjava.net/hopeshared/archive/2006/08/31/66907.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hopeshared/comments/commentRss/66907.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hopeshared/services/trackbacks/66907.html</trackback:ping><description><![CDATA[
		<h1>
				<font face="Verdana" size="4">Building Web Services the REST Way</font>
		</h1>
		<font face="Verdana" size="2">
				<b>Roger L. Costello</b>
		</font>
		<blockquote>
				<p>
						<font face="Verdana" size="2">I will first provide a brief introduction to REST and then describe how to build Web services in the REST style. </font>
				</p>
				<h2>
						<font face="Verdana" size="2">What is REST?</font>
				</h2>
				<font face="Verdana" size="2">REST is a term coined by Roy Fielding in his Ph.D. dissertation [1] to describe an <b>architecture style</b> of networked systems. REST is an acronym standing for Representational State Transfer. </font>
				<h2>
						<font face="Verdana" size="2">Why is it called Representational State Transfer?</font>
				</h2>
				<font face="Verdana" size="2">The Web is comprised of resources. A resource is any item of interest. For example, the Boeing Aircraft Corp may define a 747 resource. Clients may access that resource with this URL:</font>
				<p>
				</p>
				<form action="">
						<blockquote>
								<pre>http://www.boeing.com/aircraft/747
</pre>
						</blockquote>
				</form>
				<font face="Verdana" size="2">A <b>representation</b> of the resource is returned (e.g., Boeing747.html). The representation places the client application in a <b>state</b>. The result of the client traversing a hyperlink in Boeing747.html is another resource is accessed. The new representation places the client application into yet another state. Thus, the client application changes (<b>transfer</b>s) state with each resource representation --&gt; Representational State Transfer!</font>
				<p>
				</p>
				<font face="Verdana" size="2">Here is Roy Fielding's explanation of the meaning of Representational State Transfer:</font>
				<p>
				</p>
				<font face="Verdana" size="2">"Representational State Transfer is intended to evoke an image of how a well-designed Web application behaves: a network of web pages (a virtual state-machine), where the user progresses through an application by selecting links (state transitions), resulting in the next page (representing the next state of the application) being transferred to the user and rendered for their use." </font>
				<h2>
						<font face="Verdana" size="2">Motivation for REST</font>
				</h2>
				<font face="Verdana" size="2">The motivation for REST was to capture the characteristics of the Web which made the Web successful. Subsequently these characteristics are being used to guide the evolution of the Web. </font>
				<h2>
						<font face="Verdana" size="2">REST - An Architectural Style, Not a Standard</font>
				</h2>
				<font face="Verdana" size="2">REST is not a standard. You will not see the W3C putting out a REST specification. You will not see IBM or Microsoft or Sun selling a REST developer's toolkit. Why? Because REST is just an architectural style. You can't bottle up that style. You can only understand it, and design your Web services in that style. (Analogous to the client-server architectural style. There is no client-server standard.)</font>
				<p>
				</p>
				<font face="Verdana" size="2">While REST is not a standard, it does use standards: </font>
				<ul>
						<li>
								<font face="Verdana" size="2">HTTP</font>
						</li>
						<li>
								<font face="Verdana" size="2">URL</font>
						</li>
						<li>
								<font face="Verdana" size="2">XML/HTML/GIF/JPEG/etc (Resource Representations)</font>
						</li>
						<li>
								<font face="Verdana" size="2">text/xml, text/html, image/gif, image/jpeg, etc (MIME Types)</font>
						</li>
				</ul>
				<h2>
						<font face="Verdana" size="2">The Classic REST System</font>
				</h2>
				<font face="Verdana" size="2">The Web is a REST system! Many of those Web services that you have been using these many years - book-ordering services, search services, online dictionary services, etc - are REST-based Web services. Alas, you have been using REST, building REST services and you didn't even know it.</font>
				<p>
				</p>
				<font face="Verdana" size="2">REST is concerned with the "big picture" of the Web. It does not deal with implementation details (e.g., using Java servlets or CGI to implement a Web service). So let's look at an example of creating a Web service from the REST "big picture" perspective. </font>
				<h2>
						<font face="Verdana" size="2">Parts Depot Web Services</font>
				</h2>
				<font face="Verdana" size="2">Parts Depot, Inc (<b>fictitious company</b>) has deployed some web services to enable its customers to: </font>
				<ul>
						<li>
								<font face="Verdana" size="2">get a list of parts</font>
						</li>
						<li>
								<font face="Verdana" size="2">get detailed information about a particular part</font>
						</li>
						<li>
								<font face="Verdana" size="2">submit a Purchase Order (PO)</font>
						</li>
				</ul>
				<font face="Verdana" size="2">Let's consider how each of these services are implemented in a RESTful fashion. </font>
				<h3>
						<font face="Verdana" size="2">Get Parts List</font>
				</h3>
				<font face="Verdana" size="2">The web service makes available a URL to a parts list resource. For example, a client would use this URL to get the parts list:</font>
				<p>
				</p>
				<form action="">
						<blockquote>
								<pre>http://www.parts-depot.com/parts
</pre>
						</blockquote>
				</form>
				<font face="Verdana" size="2">Note that "how" the web service generates the parts list is completely transparent to the client. All the client knows is that if he/she submits the above URL then a document containing the list of parts is returned. Since the implementation is transparent to clients, Parts Depot is free to modify the underlying implementation of this resource without impacting clients. This is <b>loose coupling</b>.</font>
				<p>
						<font face="Verdana" size="2">Here's the document that the client receives:</font>
				</p>
				<p>
				</p>
				<form action="">
						<blockquote>
								<pre>&lt;?xml version="1.0"?&gt;
&lt;p:Parts xmlns:p="http://www.parts-depot.com" 
         xmlns:xlink="http://www.w3.org/1999/xlink"&gt;
      &lt;Part id="00345" xlink:href="http://www.parts-depot.com/parts/00345"/&gt;
      &lt;Part id="00346" xlink:href="http://www.parts-depot.com/parts/00346"/&gt;
      &lt;Part id="00347" xlink:href="http://www.parts-depot.com/parts/00347"/&gt;
      &lt;Part id="00348" xlink:href="http://www.parts-depot.com/parts/00348"/&gt;
&lt;/p:Parts&gt;
</pre>
						</blockquote>
				</form>
				<font face="Verdana" size="2">[Assume that through content negotiation the service determined that the client wants the representation as XML (for machine-to-machine processing).] Note that the parts list has links to get detailed info about each part. This is a key feature of REST. The client transfers from one state to the next by examining and choosing from among the alternative URLs in the response document. </font>
				<h3>
						<font face="Verdana" size="2">Get Detailed Part Data</font>
				</h3>
				<font face="Verdana" size="2">The web service makes available a URL to each part resource. Example, here's how a client requests part 00345:</font>
				<p>
				</p>
				<form action="">
						<blockquote>
								<pre>http://www.parts-depot.com/parts/00345
</pre>
						</blockquote>
				</form>
				<font face="Verdana" size="2">Here's the document that the client receives:</font>
				<p>
				</p>
				<form action="">
						<blockquote>
								<pre>&lt;?xml version="1.0"?&gt;
&lt;p:Part xmlns:p="http://www.parts-depot.com"   
        xmlns:xlink="http://www.w3.org/1999/xlink"&gt;
      &lt;Part-ID&gt;00345&lt;/Part-ID&gt;
      &lt;Name&gt;Widget-A&lt;/Name&gt;
      &lt;Description&gt;This part is used within the frap assembly&lt;/Description&gt;
      &lt;Specification xlink:href="http://www.parts-depot.com/parts/00345/specification"/&gt;
      &lt;UnitCost currency="USD"&gt;0.10&lt;/UnitCost&gt;
      &lt;Quantity&gt;10&lt;/Quantity&gt;
&lt;/p:Part&gt;
</pre>
						</blockquote>
				</form>
				<font face="Verdana" size="2">Again observe how this data is linked to still more data - the specification for this part may be found by traversing the hyperlink. Each response document allows the client to drill down to get more detailed information. </font>
				<h3>
						<font face="Verdana" size="2">Submit PO</font>
				</h3>
				<font face="Verdana" size="2">The web service makes available a URL to submit a PO. The client creates a PO instance document which conforms to the PO schema that Parts Depot has designed (and publicized in a WSDL document). The client submits PO.xml as the payload of an HTTP POST.</font>
		</blockquote>
		<p>
		</p>
		<blockquote>
				<font face="Verdana" size="2">The PO service responds to the HTTP POST with a URL to the submitted PO. Thus, the client can retrieve the PO any time thereafter (to update/edit it). The PO has become a piece of information which is shared between the client and the server. The shared information (PO) is given an address (URL) by the server and is exposed as a Web service. </font>
				<h2>
						<font face="Verdana" size="2">Logical URLs versus Physical URLs</font>
				</h2>
				<font face="Verdana" size="2">A resource is a conceptual entity. A representation is a concrete manifestation of the resource. This URL: </font>
				<form action="">
						<blockquote>
								<pre>http://www.parts-depot.com/parts/00345
</pre>
						</blockquote>
				</form>
				<font face="Verdana" size="2">is a logical URL, not a physical URL. Thus, there doesn't need to be, for example, a static HTML page for each part. In fact, if there were a million parts then a million static HTML pages would not be a very attractive design.</font>
				<p>
				</p>
				<font face="Verdana" size="2">[Implementation detail: Parts Depot could implement the service that gets detailed data about a particular part by employing a Java Servlet which parses the string after the host name, uses the part number to query the parts database, formulate the query results as XML, and then return the XML as the payload of the HTTP response.]</font>
				<p>
				</p>
				<font face="Verdana" size="2">As a matter of style URLs should not reveal the implementation technique used. You need to be free to change your implementation without impacting clients or having misleading URLs. </font>
				<h2>
						<font face="Verdana" size="2">REST Web Services Characteristics</font>
				</h2>
				<font face="Verdana" size="2">Here are the characteristics of REST: </font>
				<ul>
						<li>
								<font face="Verdana" size="2">Client-Server: a pull-based interaction style: consuming components pull representations.</font>
						</li>
						<li>
								<font face="Verdana" size="2">Stateless: each request from client to server must contain all the information necessary to understand the request, and cannot take advantage of any stored context on the server.</font>
						</li>
						<li>
								<font face="Verdana" size="2">Cache: to improve network efficiency responses must be capable of being labeled as cacheable or non-cacheable.</font>
						</li>
						<li>
								<font face="Verdana" size="2">Uniform interface: all resources are accessed with a generic interface (e.g., HTTP GET, POST, PUT, DELETE).</font>
						</li>
						<li>
								<font face="Verdana" size="2">Named resources - the system is comprised of resources which are named using a URL.</font>
						</li>
						<li>
								<font face="Verdana" size="2">Interconnected resource representations - the representations of the resources are interconnected using URLs, thereby enabling a client to progress from one state to another.</font>
						</li>
						<li>
								<font face="Verdana" size="2">Layered components - intermediaries, such as proxy servers, cache servers, gateways, etc, can be inserted between clients and resources to support performance, security, etc.</font>
						</li>
				</ul>
				<h2>
						<font face="Verdana" size="2">Principles of REST Web Service Design</font>
				</h2>
				<font face="Verdana" size="2">1. The key to creating Web Services in a REST network (i.e., the Web) is to identify all of the conceptual entities that you wish to expose as services. Above we saw some examples of resources: parts list, detailed part data, purchase order.</font>
				<p>
						<font face="Verdana" size="2">2. Create a URL to each resource. The resources should be nouns, not verbs. For example, do not use this:</font>
				</p>
				<p>
				</p>
				<blockquote>
						<form action="">
								<blockquote>
										<pre>http://www.parts-depot.com/parts/getPart?id=00345
</pre>
								</blockquote>
						</form>
						<font face="Verdana" size="2">Note the verb, getPart. Instead, use a noun:</font>
						<p>
						</p>
						<form action="">
								<blockquote>
										<pre>http://www.parts-depot.com/parts/00345
</pre>
								</blockquote>
						</form>
				</blockquote>
				<font face="Verdana" size="2">3. Categorize your resources according to whether clients can just receive a representation of the resource, or whether clients can modify (add to) the resource. For the former, make those resources accessible using an HTTP GET. For the later, make those resources accessible using HTTP POST, PUT, and/or DELETE.</font>
				<p>
				</p>
				<font face="Verdana" size="2">4. All resources accessible via HTTP GET should be side-effect free. That is, the resource should just return a representation of the resource. Invoking the resource should not result in modifying the resource.</font>
				<p>
				</p>
				<font face="Verdana" size="2">5. No man/woman is an island. Likewise, no representation should be an island. In other words, put hyperlinks within resource representations to enable clients to drill down for more information, and/or to obtain related information.</font>
				<p>
				</p>
				<font face="Verdana" size="2">6. Design to reveal data gradually. Don't reveal everything in a single response document. Provide hyperlinks to obtain more details.</font>
				<p>
				</p>
				<font face="Verdana" size="2">7. Specify the format of response data using a schema (DTD, W3C Schema, RelaxNG, or Schematron). For those services that require a POST or PUT to it, also provide a schema to specify the format of the response.</font>
				<p>
				</p>
				<font face="Verdana" size="2">8. Describe how your services are to be invoked using either a WSDL document, or simply an HTML document. </font>
				<h2>
						<font face="Verdana" size="2">Summary</font>
				</h2>
				<font face="Verdana" size="2">This article described REST as an architectural style. In fact, it's the architectural style of the Web. REST describes what makes the Web work well. Adhering to the REST principles will make your services work well in the context of the Web.</font>
				<p>
				</p>
				<font face="Verdana" size="2">In a future article I will write about the evolution of the Web using the REST principles. </font>
				<h2>
						<font face="Verdana" size="2">Acknowledgement</font>
				</h2>
				<font face="Verdana" size="2">Thanks to Robert Leftwich and Philip Eskelin for their very helpful comments in creating this document. </font>
				<h2>
						<font face="Verdana" size="2">References</font>
				</h2>
				<blockquote>
						<font face="Verdana" size="2">[1] <a href="http://www.ebuilt.com/fielding/pubs/dissertation/top.htm">http://www.ebuilt.com/fielding/pubs/dissertation/top.htm</a></font>
						<p>
								<br />原文：<a href="http://www.xfront.com/REST-Web-Services.html">http://www.xfront.com/REST-Web-Services.html</a></p>
				</blockquote>
		</blockquote>
<img src ="http://www.blogjava.net/hopeshared/aggbug/66907.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hopeshared/" target="_blank">hopeshared</a> 2006-08-31 17:17 <a href="http://www.blogjava.net/hopeshared/archive/2006/08/31/66907.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：使用Jena 处理 RSS 1.0</title><link>http://www.blogjava.net/hopeshared/archive/2006/07/20/59132.html</link><dc:creator>hopeshared</dc:creator><author>hopeshared</author><pubDate>Thu, 20 Jul 2006 02:36:00 GMT</pubDate><guid>http://www.blogjava.net/hopeshared/archive/2006/07/20/59132.html</guid><wfw:comment>http://www.blogjava.net/hopeshared/comments/59132.html</wfw:comment><comments>http://www.blogjava.net/hopeshared/archive/2006/07/20/59132.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hopeshared/comments/commentRss/59132.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hopeshared/services/trackbacks/59132.html</trackback:ping><description><![CDATA[作者：Brian McBride<br />发表时间：2000年9月2日<br />原文链接：<a href="http://www.hpl.hp.co.uk/people/bwm/rdf/jena/rssinjena.htm"> http://www.hpl.hp.co.uk/people/bwm/rdf/jena/rssinjena.htm</a><br />译者：<a href="mailto:unruly_wind@sina.com">dlee</a><br />翻译时间：2001年5月26日<br /><br />    <a href="http://purl.org/rss/1.0/">RSS 1.0</a> 是最近宣布的一个格式，顺从于 W3C 的 RDF (资源定义框架)，用来分发(distributing) 站点摘要 (site summary) 和企业联合 (syndication) 元数据。一个站点摘要文档的例子可以在规范中找到。Jena 是一套实验性的用来处理 RDF 的 Java API。这篇笔记描述了一个应用程序使用 Jena 来将一个站点摘要文档翻译成 HTML。整个程序的源代码作为 RenderToHTML 可以在 Jena 发布的例子包里得到。<br /><br />    这篇文章和例子代码基于 RSS 规范候选发布版本1 (Release Candidate 1 version)。<br />    这个应用程序以创建一个 RDF 模型开始，实际上在内存中是一个 RDF statement 的集合。然后解析站点摘要文档，使用一个 RDF 解析器，并加载 statement 到新创建的模型中。<br /><br />      Model model = new ModelMem();<br />      model.read("<a href="http://www.xml.com/xml/news.rss"> http://www.xml.com/xml/news.rss</a>");<br /><br />    在写出一个样板 HTML 头后，程序列出和处理在输入流中的每个 channel。在 RDF 术语中，channel 是具有一个 rdf:type 属性的 rss:channel 的资源。我们使用 Jena API 来列出具有一个有这个值的 rdf:type 属性的所有的资源。在下面的代码中，假设输出是一个接收 HTML 输出的 PrintWriter。<br /><br />      ResIterator channels =  model.listSubjectsWithProperty(RDF.type, RSS.channel);<br />      while (channels.hasNext()) {<br />          renderChannel(channels.next(), out);<br />      }<br /><br />    为了呈现 (render) 一个 channel，程序首先写出它的 title，description 和相关的 image 和 textinput 字段 (如果有的话)。getProperty 方法用来得到 channel 的 title，link 和 description 属性，随后这些可以被呈现为 HTML。<br /><br />      void renderChannel(Resource channel, PrintStream out) <br />             throws RDFException {<br />          String url = null;<br />          String title = null;<br />          String desc = null;<br /><br />          url = channel.getProperty(RSS.link).getString();<br />          title = channel.getProperty(RSS.title).getString();<br />          desc = channel.getProperty(RSS.description).getString(); <br /><br />    一个 channel 可以有一个相关联的 image 和 textinput，测试是否存在这些属性和是否需要调用合适的方法来呈现它们是很简单的。<br /><br />      if (channel.hasProperty(RSS.image)) {<br />          renderImage(channel.getProperty(RSS.image) .getResource(), out);<br />      }<br />      if (channel.hasProperty(RSS.textinput)) {<br />          renderImage(channel.getProperty(RSS.textinput) .getResource(), out);<br />      } <br /><br />    为了处理一个 image，同样的调用被用来确定 image 的属性。<br /><br />      String url = null;<br />      String title = null;<br /><br />      // does the image have a link?<br />      if (image.hasProperty(RSS.link)) {<br />          url = image.getProperty(RSS.link).getString();<br />      }<br /><br />      // does the image have a title?<br />      if (image.hasProperty(RSS.title)) {<br />          title = image.getProperty(RSS.title).getString();<br />      } image.getProperty(SSF.title).getString();<br /><br />    然后这个 image 可以被呈现成为 output stream。textinput 以 相似的方法处理。<br /><br />    channel 有一个 items 属性，它的值为一个 RDF sequence。因此使用 getProperty 方法得到这个 sequence 就很简单的了。然后迭代每一个元素以呈现它。<br /><br />      if (channel.hasProperty(RSS.items)) {<br />          Seq items = channel.getProperty(RSS.items).getSeq();<br />          for (int i=1; i&lt;= items.size(); i++) {<br />              renderItem(items.getResource(i), out);<br />          }<br />      }<br /><br />    以相同的模式呈现每一个 items。首先得到需要呈现的 items 的属性，然后写出 HTML。<br /><br />      void renderItem(Resource item, PrintWriter out) {<br />          String url = item.getProperty(RSS.link).getString();<br />          String title = item.getProperty(RSS.title).getString();<br />          String desc = item.getProperty(RSS.description) .getString();<br />          ...<br />      }<br /><br />    使用 Jena 来处理 RSS 1.0 流是简单和直接的。<br /><br />    Brian McBride<br />    HP实验室，2000年9月2日<br />    修改于2000年12月2日 <img src ="http://www.blogjava.net/hopeshared/aggbug/59132.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hopeshared/" target="_blank">hopeshared</a> 2006-07-20 10:36 <a href="http://www.blogjava.net/hopeshared/archive/2006/07/20/59132.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：jUDDI简单安装使用</title><link>http://www.blogjava.net/hopeshared/archive/2006/07/18/58755.html</link><dc:creator>hopeshared</dc:creator><author>hopeshared</author><pubDate>Tue, 18 Jul 2006 07:04:00 GMT</pubDate><guid>http://www.blogjava.net/hopeshared/archive/2006/07/18/58755.html</guid><wfw:comment>http://www.blogjava.net/hopeshared/comments/58755.html</wfw:comment><comments>http://www.blogjava.net/hopeshared/archive/2006/07/18/58755.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hopeshared/comments/commentRss/58755.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hopeshared/services/trackbacks/58755.html</trackback:ping><description><![CDATA[jUDDI，发音（Judy），是服务于WebServices 的UDDI的java实现开源包。 
<h2>1 安装</h2><h3>1.1 下载</h3>下载地址：http://ws.apache.org/juddi/releases.html <br /><br />目前的jUDDI的最新版本是0.9rc3（Release Candidate #3 for Version 0.9），不过在这个版本中有一些的bug。 <br /><br />juddi0.9版本发布应该是不会久，可以参考下面这段话，是Viens Stephen（juddi主要开发者之一）在mail list中说的：we've closed 40+ issues since January 1, 2005. We'll be releasing a 0.9rc4 as soon as Axis 1.2 final is released and then releasing a 0.9 final a few weeks after that. （March 22, 2005） 
<h3>1.2 数据库安装</h3>UDDI需要有一个地方来存储注册的数据，因此首先要选择一个关系数据库安装。JUDDI可以使用任何支持ANSI standard SQL关系数据库（ 例如MySQL, DB2, Sybase, JdataStore等）。本实例使用MySQL。 <br /><br />数据库安装完成后，在MySQL数据库中运行juddi-0.9rc3\\sql\\mysql\\create_database.sql， juddi-0.9rc3\\sql\\mysql\\insert_publishers.sql。数据库准备完成。 
<h3>1.3 安装juddi及配置</h3>首先将juddi-0.9rc3\\webapp下的juddi文件夹复制到Tomcat下的webapps中，并将 mysql-connector-java-3.1.7\\mysql-connector-java-3.1.7-bin.jar复制到Tomcat 5.0\\webapps\\juddi\\WEB-INF\\lib下。 <br /><br />下面就是连接数据库的配置，在Tomcat/conf/server.xml的Host element中加入： <br /><pre>&lt;Context path="/juddi" docBase="juddi" debug="5" reloadable="true" crossContext="true"&gt;<br />  &lt;Logger className="org.apache.catalina.logger.FileLogger" prefix="localhost_juddiDB_log" <br />  suffix=".txt" timestamp="true"/&gt;<br />  &lt;Resource name="jdbc/juddiDB" auth="Container" type="javax.sql.DataSource"/&gt;<br />  &lt;ResourceParams name="jdbc/juddiDB"&gt;<br />    &lt;parameter&gt;<br />      &lt;name&gt;factory&lt;/name&gt;<br />      &lt;value&gt;org.apache.commons.dbcp.BasicDataSourceFactory&lt;/value&gt;<br />    &lt;/parameter&gt;<br />    &lt;!-- Maximum number of dB connections in pool. Make sure you<br />         configure your mysqld max_connections large enough to handle<br />         all of your db connections. Set to 0 for no limit. --&gt;<br />    &lt;parameter&gt;&lt;name&gt;maxActive&lt;/name&gt;&lt;value&gt;100&lt;/value&gt;&lt;/parameter&gt;<br />    &lt;!-- Maximum number of idle dB connections to retain in pool.<br />         Set to 0 for no limit. --&gt;<br />    &lt;parameter&gt;&lt;name&gt;maxIdle&lt;/name&gt;&lt;value&gt;30&lt;/value&gt;&lt;/parameter&gt;<br />    &lt;parameter&gt;&lt;name&gt;maxWait&lt;/name&gt;&lt;value&gt;10000&lt;/value&gt;&lt;/parameter&gt;<br />    &lt;!-- MySQL dB username and password for dB connections 帐号密码根据数据库安装配置修改 --&gt;<br />    &lt;parameter&gt;&lt;name&gt;username&lt;/name&gt;&lt;value&gt;root&lt;/value&gt;&lt;/parameter&gt;<br />    &lt;parameter&gt;&lt;name&gt;password&lt;/name&gt;&lt;value&gt;****&lt;/value&gt;&lt;/parameter&gt;<br />    &lt;!-- Class name for mysql JDBC driver --&gt;<br />    &lt;parameter&gt;<br />      &lt;name&gt;driverClassName&lt;/name&gt;<br />      &lt;value&gt;com.mysql.jdbc.Driver&lt;/value&gt;<br />    &lt;/parameter&gt;<br />    &lt;!-- The JDBC connection url for connecting to your MySQL dB.<br />         The autoReconnect=true argument to the url makes sure that the<br />         mm.mysql JDBC Driver will automatically reconnect if mysqld closed the<br />         connection.  mysqld by default closes idle connections after 8 hours. <br />        数据库url连接配置<br />    --&gt;<br />    &lt;parameter&gt;<br />      &lt;name&gt;url&lt;/name&gt;<br />      &lt;value&gt;jdbc:mysql://host.domain.com:3306/juddi?autoReconnect=true&lt;/value&gt;<br />    &lt;/parameter&gt;<br />    &lt;parameter&gt;<br />           &lt;name&gt;validationQuery&lt;/name&gt;<br />           &lt;value&gt;select count(*) from PUBLISHER&lt;/value&gt;<br />    &lt;/parameter&gt;<br />  &lt;/ResourceParams&gt;<br />&lt;/Context&gt;<br /></pre><h3>1.4 本地安装检查</h3>访问http://127.0.0.1:8080/juddi/happyjuddi.jsp页面，此页面检查了jUDDI所必须的包和配置的正确性，并测试数据库连接是否成功。 如果没有红色文字，即本地安装成功，即可进行webservices的发布发现等服务。 
<h2>2 测试实例</h2><br /><br />以上安装成功的是UDDI的服务器端，而进行发布、查找服务的客户端的应用则要用jUDDI、UDDI4J等包来进行开发。我们可以直接使用jUDDI自 带的测试代码来进行客户端使用的学习。 
<h3>2.1 使用uddi4j测试</h3>使用uddi4j作为客户端进行测试。 <br /><br />代码位置：juddi-0.9rc3\\src\\uddi4j\\org\\apache\\juddi\\uddi4j <br /><br />新建立好一个工程并引入此代码，然后对代码进行必要的修改，主要是包名和配置。引入必要的包，比如：junit.jar、 uddi4j.jar、juddi.jar、soap.jar等（因为欧的代码库中有很多种代码，对应很多包，不知道其他哪些是必须的了：）。 <br /><br />接着是数据库的初始化，需要插入一个可以添加其他Publisher的Publisher,sql 语句： INSERT INTO PUBLISHER (PUBLISHER_ID,PUBLISHER_NAME,ENABLIED,ADMIN) VALUES ('juddi','juddi user','true','true'); <br /><br />调试代码后，运行TestAll测试，您可能会发现测试FAILURE很多，这些当中有些是测试代码的错误，也有可能是juddi-0.9rc3的缺陷（ juddi-0.9rc3不是正式发布版）。 <br /><br />以下列举一些本测试案例测试失败的可能出现的修改方法： 
<h3>2.1.1 加载配置文件时访问不到samples.prop</h3>我的解决办法是将建立一个新配置文件位置，在工程目录下的：conf\\samples.prop。 <br /><br />在Configurator.load（）方法中代码可以这样修改： <pre>    Properties config = new Properties();<br />    try {<br />        config.load(new java.io.FileInputStream("./conf/samples.prop"));<br />    }<br />    catch (Exception e) {<br />        System.out.println("Error loading samples property file\\n" + e);<br />    }<br /></pre>解决方法很多，您可以自己思索。 
<h3>2.1.2 TransportClassName配置错误</h3>如果错误提示中有这样的报告，即可能是此错误： <br />org.xml.sax.SAXParseException: Element or attribute do not match QName production: QName::=(NCName':')?NCName. <br /><br />在当前测试实例代码中的默认配置（samples.prop）中，TransportClassName定义成org.uddi4j.transport.ApacheSOAPTransport， 而我们使用的包是axis.jar，因此需要修改成相应的类，代码修改如下： <pre># -----------------------------------------------------------------------<br /><br /># Transport classname. Typically defined on commandline as<br /><br /># -Dorg.uddi4j.TransportClassName=xxx.<br /><br /># -----------------------------------------------------------------------<br /><br />#TransportClassName=org.uddi4j.transport.ApacheSOAPTransport<br /><br /> TransportClassName=org.uddi4j.transport.ApacheAxisTransport<br /><br /># TransportClassName=org.uddi4j.transport.HPSOAPTransport<br /></pre><h3>2.1.3 TestFindBusiness案例不通过</h3>TestFindBusiness中有大小写匹配测试，但是在juddi-0.9rc3中的大小写匹配（caseSensitiveMatch）有bug，因此可以将大小写匹配的测 试案例注释掉。 
<h3>2.1.4 PublisherManager的代码错误</h3>在测试Test_save_tModel的时候_testAuthTokenExpired()中，我们测试过期验证时，在错误匹配的时候，会出现测试失败，如果捕捉这个 匹配的结果，你会发现，出错的类型是E_authTokenRequired而不是期待的E_authTokenExpired。 <br /><br />这是因为在我们所获得的AuthToken是空的，在根源就是在PublisherManager. getExpiredAuthToken(String, String)方法中，代码： <pre>RegistryProxy proxy = new RegistryProxy();<br /></pre>proxy的实例的配置是空的。因此，我们修改这个方法变成： <pre>  /**<br /><br />   * changed by xio<br /><br />   * @param publisher String<br /><br />   * @param password String<br /><br />   * @param testprops Properties:增加的参数，传入基本配置<br /><br />   * @return String<br /><br />   */<br /><br />public static String getExpiredAuthToken(String publisher, String password,<br /><br />                                           Properties testprops) {<br /><br />    Properties props = new Properties();<br /><br />    props.setProperty(RegistryProxy.ADMIN_ENDPOINT_PROPERTY_NAME,<br /><br />                      testprops.getProperty("adminURL"));<br /><br />    props.setProperty(RegistryProxy.INQUIRY_ENDPOINT_PROPERTY_NAME,<br /><br />                      testprops.getProperty("inquiryURL"));<br /><br />    props.setProperty(RegistryProxy.PUBLISH_ENDPOINT_PROPERTY_NAME,<br /><br />                      testprops.getProperty("publishURL"));<br /><br /><br /><br />    RegistryProxy proxy = new RegistryProxy(props);<br /><br />    AuthToken token = null;<br /><br />    AuthInfo authInfo = null;<br /><br />    String ret = null;<br /><br />    try {<br /><br />      token = proxy.getAuthToken(publisher, password);<br /><br />      authInfo = token.getAuthInfo();<br /><br />      ret = authInfo.getValue();<br /><br />      System.out.println("getExpiredAuthToken:" + authInfo);<br /><br />      proxy.discardAuthToken(authInfo);<br /><br />    }<br /><br />    catch (Exception ex) {<br /><br />      ex.printStackTrace();<br /><br />    }<br /><br />    return ret;<br /><br />  }<br /></pre><h3>2.2 使用jUDDI测试</h3>在juddi-0.9rc3版本中自带的代码中没有客户端的使用实例，虽然附带了整个项目代码的测试代码，但是估计没什么人喜欢从这里抽取学 习客户端使用的学习。 <br /><br />当然，学习的实例还是有的，在cvs当前的工程代码中，有个samples的文件夹，这部分代码便是一个十分齐全的实例（有几个类没完成， 但不影响：）。 <br /><br />Cvs服务器数据：http://ws.apache.org/juddi/cvs.html <br /><br />Wincvs的使用请网上下载阅读。 <br /><br />其他：在进行代码学习的同时，建议阅读webservices相关资料文档。强烈建议阅读：理解 UDDI 注册中心的 WSDL 系列 (http://www-900.ibm.com/developerWorks/cn/webservices/ws-uwsdl/part1/) <br /><br />参考资料：<br /><a href="http://wiki.apache.org/ws/jUDDI_HOW-TOs"><font color="#000000">http://wiki.apache.org/ws/jUDDI_HOW-TOs</font></a><br /><a href="http://ws.apache.org/juddi/lists.html"><font color="#000000">http://ws.apache.org/juddi/lists.html</font></a><br /><br /><p align="left">原作者：xio@qq.com<br />来 源：http://xio.mblogger.cn<br /><br /><br /><br />原文地址：<a href="http://it.13520.org/ArticleView/2005-9-7/Article_View_121697.Htm">http://it.13520.org/ArticleView/2005-9-7/Article_View_121697.Htm</a></p><img src ="http://www.blogjava.net/hopeshared/aggbug/58755.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hopeshared/" target="_blank">hopeshared</a> 2006-07-18 15:04 <a href="http://www.blogjava.net/hopeshared/archive/2006/07/18/58755.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：解读UDDI和JAXR</title><link>http://www.blogjava.net/hopeshared/archive/2006/07/18/58698.html</link><dc:creator>hopeshared</dc:creator><author>hopeshared</author><pubDate>Tue, 18 Jul 2006 02:16:00 GMT</pubDate><guid>http://www.blogjava.net/hopeshared/archive/2006/07/18/58698.html</guid><wfw:comment>http://www.blogjava.net/hopeshared/comments/58698.html</wfw:comment><comments>http://www.blogjava.net/hopeshared/archive/2006/07/18/58698.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hopeshared/comments/commentRss/58698.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hopeshared/services/trackbacks/58698.html</trackback:ping><description><![CDATA[在过去的数年中，许多开发人员都使用了各种版本的J2EE，使服务器端软件编程的情形得到了很大的改观，现在，他们将再次挑战SOAP，在服务器端软件编程方面取得更大的进展。 <br />SOAP服务的支持者认为： <br />·企业级应用服务器是服务（或事务）的集合。 <br />·可以使用的服务应当很方便地列出来供用户浏览、搜索和访问。 <br />·象现在的基于组件的开发模式那样，将应用服务器设计为服务的集合将鼓励开发人员采用更好的设计模式。 <br />·这些事务能够被重新定位、负载平衡、替代等。 <br />而对SOAP持怀疑态度的人认为，SOAP是推广CORBA和COM的又一次尝试。他们指出，要简单地访问一个对象，需要完成太多的准备性工作，而且，UDDI带来的好处也被夸大了。 <br />那么，到底哪一种观点更合理呢？对于一些思想开放的人士而言，在决定是否采用SOAP服务前，他们一定希望了解其中的一些核心技术。 <br />解密UDDI <br />我们首先来看看UDDI代表什么？UDDI是Universal Description, Discovery and Integration（统一描述、发现和集成）的缩写。UDDI的意图是作为一个注册簿，就象黄页是一个地区企业的注册簿一样。象在黄页中那样，在UDDI注册簿中，企业将在不同的目录下注册它们自己或其服务。通过浏览一个UDDI注册簿，开发人员能够查找一种服务或一个公司，并发现如何调用该服务。 <br />除了黄页外，UDDI还使用了白页和绿页。白页是企业实体列表，绿页是调用一项服务所必需的文档。 <br />UDDI的定义非常全面，足以适应不同种类的服务。一个UDDI服务定义可能代表一个传真服务或电话服务。作为一种注册簿，UDDI一般使用数据库一类的软件来实现，在该数据库中，存在一个允许发布或查询服务的有关信息。 <br />UDDI数据模型 <br />UDDI数据模型包括下面的主要元素： <br />·businessEntity：表示一个实际的企业。 <br />·businessService：表示一个企业提供的服务。 <br />·bindingTemplate：如何调用服务的说明。 <br />·tModel&gt;: Good luck understanding this! (Just kidding, I will explain this later.) <br />为了加深对UDDI数据模型的理解，我们来看看这些数据元素的UML表示法。图1是这四种主要元素之间的关系图： <br /><img src="http://www.wyt2008.com/Article/UploadFiles/200603/200632611743220.gif" /><br />从上面的图中我们可以知道，一个businessEntity（一家公司）有一个能够告诉我们更多有关公司信息的描述性URL和联系人清单，此外，businessEntity还有一个商业服务清单。每种服务可能有多种调用方法，每种调用都由一个绑定模板描述。绑定模板详细地描述了如何访问一个服务，它受益于一系列描述用户如何访问这一服务的文档。绑定模板和其必要的文档之间的联系是通过所谓的tModel完成的。在上面的图中，这种联系被简单地描述为一个绑定模板有许多tModels。在进一步地解释tModels与绑定模板的关系前，我们必须先弄清楚tModels是什么。 <br />TModel是什么？ <br />我们可以把tModel想象成数据库库中的一个独立的表，其中包含下面的字段：名字、描述、URL、唯一的关健字。实际上，tModel就是包括有名字和描述，那么使用数据库表表示它是否是一种浪费呢？我们下面就会讨论这一问题： <br />下面是一个假想的tModel数据库表中的二个实体： <br />键 名字 描述 URL <br />1 Java-class 表示一个具备完全资格的java类的名字 http://www.javasoft.com/ <br />2 Jndi-home 表示一个JNDI名字 http://www.javasoft.com/ <br /><br />在将tModel比作数据库表方面，有几点值得注意。首先，tModel是一个独立的表，意味着它可以不依赖其他软件而存在；其次，tModel是查找表，提供了键与键的表示之间的转换关系。从这一点来看，tModel象词典那样，是一个引用表。在一些数据库中，这样的表也被称作是码集。 <br />因此，如果在上面的tModel中存在下面的记录： <br />com.mycompany.HelloWorld, 1 <br />com.mycompany.HelloWorldHome, 2 <br />就意味着字符串com.mycompany.HelloWorld是一个有完整资格的Java类；而字符串com.mycompany.HelloWorldHome是一个JNDI名。 <br /><br />因此在一定程度上，tModels中唯一的键与“名字空间”这个概念差不多。为了进一步地说明这个问题，我们来看一下下面的数字： <br />904-555-1212 <br />904-555-1213 <br />1-56592-391-x <br />你能够分清这些数字的意义吗？我们需要在一个环境或名字空间中来确认，904-555-1212是电话号码，904-555-1213是传真号，1-56592-391-x是一个ISBN号。 <br />因此在tModel数据库表中，我们将需要定义三个实体：一个是电话号码；一个是传真号码，一个是ISBN号码。 <br />下面我们以mycompany公司公布了一条号码为1-800-my-helpline的电话支持热线，并在UDDI中注册。那么，我们的数据模型为： <br />company name: mycompany <br />Service name: helpline <br />tModel: key=11 (representing telephoneline), name=telephone, <br />description=telephone stuff, url: <br />some at&amp;t url <br />binding: <br />accesspoint: 1-800-my-helpline <br />tModelInstanceInfo: 11 <br /><br />有了对tModel的基本理解后，我们就可以利用UML图表来研究绑定模板与tModels之间的关系了。我在上面曾经说过，这将使我们对绑定模板如何完成UDDI的“如何调用一项服务”的要求有一个直观的理解。 <br /><img src="http://www.wyt2008.com/Article/UploadFiles/200603/200632611743600.gif" /><br />在图2中，我们讨论了一个绑定模板与tModels之间的关系。从图表中我们可以看出，一个绑定模板可以指向一个由一个tModel确定的技术规格，技术规格有二部分组成： <br />·规格的类型。（例如电子邮件、传真、WSDL、SOAP等。） <br />·确定输入和输出的文档（在SOAP服务中，这些文档可以是XML输入/输出消息格式。） <br />既然我们已经对tModels有了一定程度的详细了解，就该再讨论UDDI中更复杂的东西了，也就是身份包和类别包。 <br />理解标识符包和类别包 <br />如果说从概念上理解tModels是理解UDDI需要跨越的第一道障碍，那么理解标识符包和类别包则是需要跨越的第二道障碍。下面的例子可以帮助我们理解这二个概念。 <br />例如，您的公司在美国开展业务需要有一个税号，如果还在另外的国家（例如墨西哥）开展业务，就需要有一个墨西哥的税号。为了能够在UDDI注册簿中获取您的公司的这些信息，在UDDI中应当包括下面的内容： <br />公司名字：mycompany <br />标识符： <br />美国税号：111111 <br />墨西哥税号：2223344 <br />其他国家税号： 333333 <br /><br />...其他的xml内容 <br />&lt;identifierBag&gt; <br />&lt;keyedReference tModelKey="US-tax-code" <br />keyName="taxnumber" keyValue="1111111"&gt; <br />&lt;keyedReference tModelKey="Mexico-tax-code" <br />keyName="taxnumber" keyValue="2223344"&gt; <br />&lt;keyedReference tModelKey="other-stuff" <br />keyName="taxnumber" keyValue="333333"&gt; <br />&lt;/identifiedBag&gt; <br />... 其他的xml内容 <br />现在明白tModels如何被用作名字空间了吧。为了进一步地深化对标识符包的理解，我们在下面的图中再次解释了标识符和类别包的概念： <br /><img src="http://www.wyt2008.com/Article/UploadFiles/200603/200632611743959.gif" /><br />从上面的图中我们能够看出，标识符包是一个在特定环境中的键/值对集合，这个环境从本质上说就是能够唯一地解析名字/值对儿的名字空间，它是由tModel确定的。类别包也是如此，二者之间唯一的区别就是类别包中由tModel确定的名字空间是一个预先确定好的类别。 <br />类别包 <br />我想将公司归类于饭店，其地理位置位于杰克逊维尔。 <br />公司名字：mycompany <br />适用类： <br />企业类型：饭店 <br />所在城市：杰克逊维尔 <br />&lt;categoryBag&gt; <br />&lt;keyedReference tModelKey="BusinessTypeClassification" <br />keyName="restaurant" keyValue=".."&gt; <br />&lt;keyedReference tModelKey="CityClassification" <br />keyName="JAX" keyValue=".."&gt; <br />&lt;/categoryBag&gt; <br />现在，我们已经搞清楚了tModels是如何用在标识符和类别包中的。从本质上说，tModels就是名字空间。 <br /><br />tModels也能被分类吗？ <br />我们已经明白了企业实体是如何利用使用了类别包的。另外，UDDI也允许tModels本身被分类。 <br />我们用分层次的文件系统进行说明。目录是用来对文件进行分类的，但目录还可以在父目录下再被分类。象硬盘上的目录那样，tModels也可以被分层次地进行组织。 <br />下面我们来讨论名字为getUniversalTime()的服务，该服务将返回当前全球任一地方的时间。二家存在竞争关系的公司可能会提供这一服务的不同实现。商业服务只限于在公司内部使用，公司之外的用户是不可使用的： <br />company1:getTime() <br />company1:getCurrentTime() <br />这二者的作用相同，为了表明它们实现的是同一个被称作getUniversalTime()的服务，我们可以定义如下所示的tModel： <br />tModel <br />name：: Get Universal Time <br />category: uddi-org:types, wsdl <br />[意味着这是一个由WSDL文档定义的服务] <br />上面的定义表明getUniversalTime()是一个WSDL服务，可以由任何公司实现。 <br />既然已经阐明了tModels和包之间的关系，我们下面可以看看一个tModel的UML表示： <br /><img src="http://www.wyt2008.com/Article/UploadFiles/200603/200632611743333.gif" /><br />从上面的图表中，我们可以看出tModel基本上就是一个名字和描述，另外，它也可以包含一个URL，以提供更进一步的详细资料。它可以由一个标识符包确定和由一个类别包进行分类。 <br />我们已经知道，一个tModel所属于的类别是由UDDI━━WSDL、SOAP等预先定义好的，下面是一个uddi-org:types名字空间中预先定义类别的清单： <br />tModel <br />identifier （唯一标识符） <br />namespace <br />categorization <br />specification <br />xmlSpec <br />soapSpec <br />wsdlSpec <br />protocol <br />transport <br />signatureComponent <br />如何开始在UDDI中创建一个服务？ <br />在开始定义服务的tModel时，要求我们为服务指定一个名字和上面所列出的服务类型中的一个。当然了，如果不喜欢上面的分类可以自己创建类别。 <br />我们可以针对上面定义的tModel开发一个商业服务。在商业服务定义中，我们需要指定一个指向定义了服务的输入/输出的WSDL文档的URL。 <br /><br />在UDDI中为什么需要tModels？ <br />在UDDI中使用tModels的目的如下： <br />·对商业实体进行标识和分类 <br />·对商业服务进行标识和分类 <br />·对tModels进行标识和分类 <br />·将商业服务绑定到它们抽象的tModel定义上 <br />UDDI名词的快速参考 <br />在看有关UDDI的资料时，如果看到很深奥的术语是一件很烦人的事儿，下面我们就把一些经常用到的与UDDI有关的概念搜集起来，通过比较帮助我们对UDDI概念的理解： <br />接口和实现 <br />服务绑定是一个容器，接口依赖于其实现；绑定元素详细说明了tModelInstaceInfo和instanceDetail， 我们将再通过一个例子加深对这一问题的例子。对于“获得统一时间”服务而言，细节将提供定义了输入、输出的实际的WSDL文档，绑定的访问点将提供实现服务的物理机器和端口。了解了这些，我们可以得出如下的结论： <br />·为一种服务定义的tModel是允许多家公司提供该服务的多个实现的界面。 <br />·服务绑定是具体的实现。 <br />名字空间 <br />Java、C++和XML中都有名字空间的概念，尽管其叫法可能不同，但它们都提供了使名字有意义的环境。在UDDI中，tModel象征着“名字”。当把这个名字作为目录使用时，你的本意是，“我属于这个名字”。从这个意义上说，tModel表示的是名字空间。 <br />技术指纹 <br />当一种服务被注册为tModel时，我们可以注册用来与该服务通讯的协议（例如WSDL、SOAP等）。因此根据所使用的协议不同，tModel有WSDL指纹或SOAP指纹。因此tModel被认为是技术性指纹，每种指纹与一种特定的协议有关。如果说一种tModel可以代表一个“技术性指纹”，我们也可以说tModel能够表示一种“协议”。 <br />分类 <br />分类与类别、名字空间类似，它提供了一种环境，只有在这种环境下，一些数字和名字才有意义。例如， <br />白页 <br />UDDI注册簿中的企业实体列表和根据名字搜索企业的能力。 <br />黄页 <br />黄页将企业实体按企业类别或其他适用的类别分类。 <br />绿页（技术规格） <br />绿页有助于我们理解服务的定义和访问服务的要求，serviceBindings和tModels也有助于这一目标的实现。 <br />JAXR <br />JAXR是在服务注册中使用的一种Java XML API。我们以前曾经讨论过，UDDI中的所有元素都用XML文档进行描述。从某种意义上说，嘦我们能够发送包含有服务描述的XML消息，UDDI注册簿就能够对它进行注册或更新。下面我们讨论在没有工具的情况下如何完成这一任务： <br />1、编写必要的服务描述XML文档。 <br />2、理解SOAP头部，以便能够将XML文件作为一个SOAP附件发送给UDDI注册簿。 <br />3、使用SOAP客户端Java API完成第二步中的任务。 <br />4、通过编程的方式处理SOAP消息。 <br />5、根据UDDI服务的描述，构造消息完成该UDDI服务的任务。 <br />6、对每个消息，完成第2、3步中的操作。 <br />如果使用JAXR，我们可以更好地完成这一任务。因为JAXR允许我们在发送XML消息时无需考虑SOAP头部，而且是一种严格的面向消息的协议。使用JAXR，上面的任务将简化为： <br />1、编写必要的服务描述XML文档。 <br />2、使用JAXM API发送和接收XML消息，JAXR隐藏了SOAP信息。 <br />3、根据UDDI服务构建消息完成该UDDI服务。（例如，向UDDI注册簿注册UDDI服务包含有4次信息交换过程。）这意味着我们仍然需要与XML内容打交道。 <br />使用这种方式，我们只需处理高层次的Java API即可，这些Java API能够产生必需的消息并通过JAXR传输它们。需要指出的一点是，JAXR也用来完成该任务。 <br />下面列出了JAXR的一些目标： <br />·支持业界标准的XML注册功能 <br />·支持成员机构和企业的注册 <br />·支持任意注册内容的存储和提交 <br />·支持XML、非XML注册内容的管理 <br />·支持注册内容间用户定义的结合 <br />·支持用户定义的注册内容的多级分类 <br />·支持基于定义的分类计划的注册内容查询 <br />·支持基于复杂查询的注册内容查询 <br />·支持基于关健词的注册内容查询 <br />·支持Web服务的共享 <br />·支持合作伙伴间商业过程的共享 <br />·支持合作伙伴间计划的共享 <br />·支持合作伙伴间商业文档的共享 <br />·支持合作伙伴间贸易伙伴协议的谈判 <br />·支持计划汇编 <br />·支持异类分布注册 <br />·支持参与各方发布/订阅XML消息 <br />JAXR将不仅仅支持UDDI，还会支持其他的类似注册服务标准（例如ebXML）。 <br /><br /><br />原文地址：<a href="http://www.wyt2008.com/Article/java/web/200603/Article_921.html">http://www.wyt2008.com/Article/java/web/200603/Article_921.html</a><img src ="http://www.blogjava.net/hopeshared/aggbug/58698.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hopeshared/" target="_blank">hopeshared</a> 2006-07-18 10:16 <a href="http://www.blogjava.net/hopeshared/archive/2006/07/18/58698.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：配置XFire</title><link>http://www.blogjava.net/hopeshared/archive/2006/06/04/50321.html</link><dc:creator>hopeshared</dc:creator><author>hopeshared</author><pubDate>Sun, 04 Jun 2006 11:53:00 GMT</pubDate><guid>http://www.blogjava.net/hopeshared/archive/2006/06/04/50321.html</guid><wfw:comment>http://www.blogjava.net/hopeshared/comments/50321.html</wfw:comment><comments>http://www.blogjava.net/hopeshared/archive/2006/06/04/50321.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hopeshared/comments/commentRss/50321.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hopeshared/services/trackbacks/50321.html</trackback:ping><description><![CDATA[原文地址：<a href="http://javaresearch.org/article/showarticle.jsp?column=5&amp;thread=50134">http://javaresearch.org/article/showarticle.jsp?column=5&amp;thread=50134</a><br /><br /><br />在进行所有的开发之前，自然是到<a href="http://xfire.codehaus.org/">http://xfire.codehaus.org</a>下载最新的xfire的发布版本，在写这篇文档的时候，xfire最新的版本是xfire-distribution-1.1-beta-1版，从官方网站下载到本地机器后，解压，目录结构如下：<br /><br />xfire-distribution-1.1-beta-1<br /><br />|____api (javadoc文档)<br /><br />|____sample (几个xfire例子)<br /><br />|____lib (xfire所需的jars)<br /><br />|____modules (xfire 模块)<br /><br />|____xfire-all-1.1-beta-1.jar<br /><br />|____几个授权和说明TXT文档<br /><br /> <br /><br />它所提供的例子需要Maven2编译执行，如果你还没有安装Maven，可以到apache网站下载安装。在你阅读的这篇教程的例子中，我将采用ant进行编译，毕竟Ant才是大家所常用的项目管理编译工具。<br /><br /> <br /><br />在你的tomcat的webapps建立一个web应用程序，例如xfire，目录结构如下：<br /><br />       xfire<br /><br />         |____WEB_INF<br /><br />                |____web.xml<br /><br />             |____classes<br /><br />             |____lib<br /><br /> <br /><br />将下载解压的xfire-distribution-1.1-beta-1\lib文件夹下的所有的jar放入的这个lib文件夹下(tomcat/webapps/xfire/WEB-INF/lib)、将xfire-distribution-1.1-beta-1\xfire-all-1.1-beta-1.jar放入到tomcat/webapps/xfire/WEB-INF/lib文件夹下。<br /><br />将xfire-distribution-1.1-beta-1\examples\book\src\webapp\WEB-INF下的web.xml文件复制到tomcat/webapps/xfire/WEB-INF文件夹下。<br /><br />Web.xml的内容如下：<br /><div class="codeStyle"><ol><li><i><font color="#339900">&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;</font></i></li><li></li><li><i><font color="#339900">&lt;!-- START SNIPPET: webxml --&gt;</font></i></li><li></li><li><i><font color="#339900">&lt;!DOCTYPE web-app</font></i></li><li></li><li><i><font color="#339900">    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"</font></i></li><li></li><li><i><font color="#339900">    "http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</font></i></li><li></li><li><i><font color="#339900">   </font></i></li><li></li><li><i><font color="#339900">&lt;web-app&gt;</font></i></li><li></li><li><i><font color="#339900"></font></i></li><li></li><li><i><font color="#339900">  &lt;servlet&gt;</font></i></li><li></li><li><i><font color="#339900">    &lt;servlet-name&gt;XFireServlet&lt;/servlet-name&gt;</font></i></li><li></li><li><i><font color="#339900">    &lt;display-name&gt;XFire Servlet&lt;/display-name&gt;</font></i></li><li></li><li><i><font color="#339900">    &lt;servlet-class&gt;</font></i></li><li></li><li><i><font color="#339900">        org.codehaus.xfire.transport.http.XFireConfigurableServlet</font></i></li><li></li><li><i><font color="#339900">    &lt;/servlet-class&gt;</font></i></li><li></li><li><i><font color="#339900">  &lt;/servlet&gt;</font></i></li><li></li><li><i><font color="#339900"></font></i></li><li></li><li><i><font color="#339900">  &lt;servlet-mapping&gt;</font></i></li><li></li><li><i><font color="#339900">    &lt;servlet-name&gt;XFireServlet&lt;/servlet-name&gt;</font></i></li><li></li><li><i><font color="#339900">    &lt;url-pattern&gt;/servlet/XFireServlet/*&lt;/url-pattern&gt;</font></i></li><li></li><li><i><font color="#339900">  &lt;/servlet-mapping&gt;</font></i></li><li></li><li><i><font color="#339900"></font></i></li><li></li><li><i><font color="#339900">  &lt;servlet-mapping&gt;</font></i></li><li></li><li><i><font color="#339900">    &lt;servlet-name&gt;XFireServlet&lt;/servlet-name&gt;</font></i></li><li></li><li><i><font color="#339900">    &lt;url-pattern&gt;/services/*&lt;/url-pattern&gt;</font></i></li><li></li><li><i><font color="#339900">  &lt;/servlet-mapping&gt;</font></i></li><li></li><li><i><font color="#339900">&lt;/web-app&gt;</font></i></li></ol></div><br />启动tomcat,然后打开浏览器，在浏览器地址栏中输入http://localhost:8080/xfire/services/，如何能够正常显示页面，说明xfire就配置成功了。<br /><br /> <br />这样，我们的XFire就配置完成了。<br /><img src ="http://www.blogjava.net/hopeshared/aggbug/50321.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hopeshared/" target="_blank">hopeshared</a> 2006-06-04 19:53 <a href="http://www.blogjava.net/hopeshared/archive/2006/06/04/50321.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：WSIF应用(翻译的) </title><link>http://www.blogjava.net/hopeshared/archive/2006/05/15/46255.html</link><dc:creator>hopeshared</dc:creator><author>hopeshared</author><pubDate>Mon, 15 May 2006 09:31:00 GMT</pubDate><guid>http://www.blogjava.net/hopeshared/archive/2006/05/15/46255.html</guid><wfw:comment>http://www.blogjava.net/hopeshared/comments/46255.html</wfw:comment><comments>http://www.blogjava.net/hopeshared/archive/2006/05/15/46255.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hopeshared/comments/commentRss/46255.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hopeshared/services/trackbacks/46255.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Applying the Web services invocation framework 																										Calling services independent of protocols 																独立于协议的服务调用											...&nbsp;&nbsp;<a href='http://www.blogjava.net/hopeshared/archive/2006/05/15/46255.html'>阅读全文</a><img src ="http://www.blogjava.net/hopeshared/aggbug/46255.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hopeshared/" target="_blank">hopeshared</a> 2006-05-15 17:31 <a href="http://www.blogjava.net/hopeshared/archive/2006/05/15/46255.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：无 SOAP 的 Web 服务</title><link>http://www.blogjava.net/hopeshared/archive/2006/05/15/46251.html</link><dc:creator>hopeshared</dc:creator><author>hopeshared</author><pubDate>Mon, 15 May 2006 09:20:00 GMT</pubDate><guid>http://www.blogjava.net/hopeshared/archive/2006/05/15/46251.html</guid><wfw:comment>http://www.blogjava.net/hopeshared/comments/46251.html</wfw:comment><comments>http://www.blogjava.net/hopeshared/archive/2006/05/15/46251.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hopeshared/comments/commentRss/46251.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hopeshared/services/trackbacks/46251.html</trackback:ping><description><![CDATA[即使 SOAP 只是众多访问 Web 服务的可能的绑定之一，它已几乎成为 Web 服务的同义词。这意味着使用 Web 服务的应用程序通常通过绑到 SOAP 的特定实现的 API 来完成工作。本系列文章将描述一个更通用的、独立于 SOAP 的调用 Web 服务的方法，称之为“Web 服务调用框架”（Web Service Invocation Framework（WSIF））。它专门设计来直接调用用“Web 服务描述语言”（Web Services Description Language（WSDL））描述的 Web 服务，隐藏了底层访问协议（比如 SOAP）的复杂性。<br /><br /><p>Web 服务承诺为因特网分布式计算提供基于标准的平台，集中在简易性和灵活性。一种关键的 Web 服务技术是 WSDL，即“Web 服务描述语言”。使用 WSDL，开发者可以以抽象的形式描述 Web 服务，与用在其它分布式计算框架（比如 CORBA）的现有“接口描述语言”（Interface Description Language（IDL））类似。WSDL 也使 Web 服务开发者能够给服务指定具体的绑定。并且这些绑定描述怎样将抽象服务描述映射到特定访问协议。WSDL 的这部分是可扩展的，这就是说任何人都可以提出他们自己的绑定，使之可能通过某个定制的协议访问服务。</p><p>因此，从某种程度来说，使用 Web 服务是一种挑战。对于同样的服务可以有多个绑定。这些绑定中的一些可能适合于一些情形，其它可能适合于另外的情形。绑定本身可以代表抽象服务描述到用来访问服务的任意一种协议的映射。虽然有多种选择使用服务和允许绑定扩展是很有用的，但这给客户机以统一方式查看服务造成了困难。</p><p>我以当前客户机端 API 及其性能的讨论开始这篇文章。我将通过讨论来激发人们对 WSIF，即“Web 服务调用框架”的需要，然后继续进行 WSIF 的概述。</p><p><a name="1"></a><a name="h3919"><span class="atitle2">当前的调用风格及其缺点</span></a><br />用于 Web 服务的 SOAP 绑定是 WSDL 规范的一部分。在大多数编程语言中，该协议有可用的实现和工具，在许多情况下是免费的。这样，它使得开发者能以微乎其微的成本进行用于 Web 服务的独立于平台的开发。</p><p>因此，下述情况是不足为奇的：大多数开发者当想到使用 Web 服务时，在他们头脑中出现的是使用某个 SOAP 客户机 API 来装配一个 SOAP 消息并将它经由网络发送到服务端点。例如，使用 Apache SOAP，客户机将创建和植入一个 Call 对象。它封装了服务端点、要调用的 SOAP 操作的标识、必须发送的参数等等。而这是对 SOAP 而言，它仅限于将其用作调用 Web 服务的一般模型，这是因为下面的原因：</p><ul><li><b>Web 服务不仅仅是 SOAP 服务</b><br />将 Web 服务视为 SOAP 上提供的服务的同义词。这是对 Web 服务狭隘的见解。带有功能方面和访问协议 WSDL 描述的任何一段代码均可以被认为是 Web 服务。WSDL 规范为 Web 服务定义了 SOAP 绑定，但是原则上可能要添加绑定扩展，这样，例如，使用 RMI/IIOP 作为访问协议，EJB 就可以作为 Web 服务来提供。或者您甚至可以想象任意一个 Java 类可以被当作 Web 服务，以本机 Java 调用作为访问协议。就这个更广阔的 Web 服务定义来说，您需要用于服务调用的独立于绑定的机制。 
</li><li><b>将客户机代码绑到一个特殊的协议实现要受到限制</b><br />将客户机代码紧密地绑定到特殊的协议实现的客户机库造成了难以维护的代码。让我们假设您在客户机端有一个用 Apache SOAP v2.1 调用 Web 服务的应用程序。如果您想利用 v2.2 中出现的新的功能和错误修正，您将不得不更新所有的客户机代码，这是一项耗时的任务，将涉及到常见的令人头痛的迁移问题。类似的，如果您想从 Apache SOAP 移到一个不同的 SOAP 实现，这个过程并非无关紧要。所需要的是用于服务调用的独立于协议实现的机制。 
</li><li><b>将新的绑定融入到客户机代码是很困难的。</b><br />WSDL 允许有定义新的绑定的可扩展性元素。这使开发者能够定义绑定，这种绑定允许使用某种定制协议的代码作为 Web 服务。但是，事实上实现起来是很困难的。将不得不设计使用该协议的客户机 API 。应用程序本身可能正是使用 Web 服务的抽象接口，因此将必须编写一些工具来生成启用抽象层的存根。这些又一次是并非无关紧要的而且耗时的任务。所需要的是使绑定能够被更新或新的绑定能够容易地插入的服务调用机制。 
</li><li><b>可以以灵活的方式使用多绑定</b><br />例如，设想您已经成功地部署了一个应用程序，该应用程序使用提供多绑定的 Web 服务。为了使这个示例更具体，假设您有用于服务的 SOAP 绑定和允许您将本地服务实现（一个 Java 类）作为 Web 服务的本地 Java 绑定。显而易见，如果客户机部署在与服务本身相同的环境中，只能使用面向服务的本地 Java 绑定，并且如果情况确实如此，通过直接进行 Java 调用而不是使用 SOAP 绑定与服务进行通信将高效得多。Java 绑定作为一种快捷访问机制。接下来，想要利用多绑定可用性的客户机将必须具有一种能力 — 根据运行时信息对要用的实际绑定进行切换的能力。因此为了利用提供多绑定的 Web 服务，您需要一种服务调用机制，允许您在运行时在可用的服务绑定之间进行切换，而不需要生成或重编译存根。</li></ul><p><a name="2"></a><a name="h8285"><span class="atitle2">介绍 WSIF</span></a><br />“Web 服务调用框架”（WSIF）是为调用 Web 服务提供简单 API 的工具箱，而不管服务怎样提供或由哪里提供。它具有上面讨论中我确定的所有功能：</p><p></p><ul><li>有给任何 Web 服务提供独立于绑定访问的 API。 
</li><li>提供端口类型编译器来生成允许使用抽象服务接口的调用的存根。 
</li><li>允许无存根（完全动态）的 Web 服务调用。 
</li><li>可以在运行时将更新的绑定实现插入到 WSIF。 
</li><li>可以在运行时插入的新的绑定。 
</li><li>允许将绑定选择延后到运行时。</li></ul><p></p><p><a name="h9119"><span class="atitle3">分析 WSIF 的客户机 API</span></a><br />为了进行讨论，我将使用很常见的股票报价程序 — Web 服务的“Hello World”示例。请考虑下面<a href="http://www-900.ibm.com/developerWorks/cn/webservices/ws-wsif/part1/index.shtml#listing1">清单 1</a> 所示的使用 WSDL 的抽象服务描述。</p><p><a name="listing1"></a><b>清单 1：股票报价 Web 服务的 WSDL 描述</b></p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">&lt;?</span><span style="COLOR: #ff00ff">xml version="1.0" </span><span style="COLOR: #0000ff">?&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">definitions </span><span style="COLOR: #ff0000">targetNamespace</span><span style="COLOR: #0000ff">="http://www.ibm.com/namespace/wsif/samples/stockquote-interface"</span><span style="COLOR: #ff0000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />             xmlns:tns</span><span style="COLOR: #0000ff">="http://www.ibm.com/namespace/wsif/samples/stockquote-interface"</span><span style="COLOR: #ff0000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />             xmlns:xsd</span><span style="COLOR: #0000ff">="http://www.w3.org/1999/XMLSchema"</span><span style="COLOR: #ff0000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />             xmlns</span><span style="COLOR: #0000ff">="http://schemas.xmlsoap.org/wsdl/"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">message </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="GetQuoteInput"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">part </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="symbol"</span><span style="COLOR: #ff0000"> type</span><span style="COLOR: #0000ff">="xsd:string"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">message</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">message </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="GetQuoteOutput"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">part </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="quote"</span><span style="COLOR: #ff0000"> type</span><span style="COLOR: #0000ff">="xsd:float"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">message</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">portType </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="StockquotePT"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">operation </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="getQuote"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">input </span><span style="COLOR: #ff0000">message</span><span style="COLOR: #0000ff">="tns:GetQuoteInput"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">output </span><span style="COLOR: #ff0000">message</span><span style="COLOR: #0000ff">="tns:GetQuoteOutput"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">operation</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">portType</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">definitions</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div><p><br />足够简单：它描述了只带有由一个端口类型提供一个操作的服务。该操作等待一个字符串，被解释为股票的报价机符号，然后返回当前该股票报价，一个浮点值。为了实际使用该服务，您需要某个定义访问机制的绑定以及该绑定的服务端点。<a href="http://www-900.ibm.com/developerWorks/cn/webservices/ws-wsif/part1/index.shtml#listing2">清单 2</a> 展示了该服务的 SOAP 绑定：</p><p><a name="listing2"></a><b>清单 2：股票报价 Web 服务的 SOAP 绑定</b></p><p></p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">&lt;?</span><span style="COLOR: #ff00ff">xml version="1.0" </span><span style="COLOR: #0000ff">?&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">definitions </span><span style="COLOR: #ff0000">targetNamespace</span><span style="COLOR: #0000ff">="http://www.ibm.com/namespace/wsif/samples/stockquote"</span><span style="COLOR: #ff0000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />             xmlns:tns</span><span style="COLOR: #0000ff">="http://www.ibm.com/namespace/wsif/samples/stockquote"</span><span style="COLOR: #ff0000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />             xmlns:tns-int</span><span style="COLOR: #0000ff">="http://www.ibm.com/namespace/wsif/samples/stockquote-interface"</span><span style="COLOR: #ff0000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />             xmlns:xsd</span><span style="COLOR: #0000ff">="http://www.w3.org/1999/XMLSchema"</span><span style="COLOR: #ff0000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />             xmlns:soap</span><span style="COLOR: #0000ff">="http://schemas.xmlsoap.org/wsdl/soap/"</span><span style="COLOR: #ff0000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />             xmlns:java</span><span style="COLOR: #0000ff">="http://schemas.xmlsoap.org/wsdl/java/"</span><span style="COLOR: #ff0000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />             xmlns</span><span style="COLOR: #0000ff">="http://schemas.xmlsoap.org/wsdl/"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">import </span><span style="COLOR: #ff0000">namespace</span><span style="COLOR: #0000ff">="http://www.ibm.com/namespace/wsif/samples/stockquote-interface"</span><span style="COLOR: #ff0000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          location</span><span style="COLOR: #0000ff">="stockquote-interface.wsdl"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">binding </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="SOAPBinding"</span><span style="COLOR: #ff0000"> type</span><span style="COLOR: #0000ff">="tns-int:StockquotePT"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">soap:binding </span><span style="COLOR: #ff0000">style</span><span style="COLOR: #0000ff">="rpc"</span><span style="COLOR: #ff0000"> transport</span><span style="COLOR: #0000ff">="http://schemas.xmlsoap.org/soap/http"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">operation </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="getQuote"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">soap:operation </span><span style="COLOR: #ff0000">soapAction</span><span style="COLOR: #0000ff">="http://example.com/GetTradePrice"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">input</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">soap:body </span><span style="COLOR: #ff0000">use</span><span style="COLOR: #0000ff">="encoded"</span><span style="COLOR: #ff0000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                   namespace</span><span style="COLOR: #0000ff">="urn:xmltoday-delayed-quotes"</span><span style="COLOR: #ff0000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                   encodingStyle</span><span style="COLOR: #0000ff">="http://schemas.xmlsoap.org/soap/encoding/"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">input</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">output</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">soap:body </span><span style="COLOR: #ff0000">use</span><span style="COLOR: #0000ff">="encoded"</span><span style="COLOR: #ff0000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                   namespace</span><span style="COLOR: #0000ff">="urn:xmltoday-delayed-quotes"</span><span style="COLOR: #ff0000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                   encodingStyle</span><span style="COLOR: #0000ff">="http://schemas.xmlsoap.org/soap/encoding/"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">output</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">operation</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">binding</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">service </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="StockquoteService"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">documentation</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">Stock quote service</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">documentation</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">port </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="SOAPPort"</span><span style="COLOR: #ff0000"> binding</span><span style="COLOR: #0000ff">="tns:SOAPBinding"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">soap:address </span><span style="COLOR: #ff0000">location</span><span style="COLOR: #0000ff">="http://localhost:8080/soap/servlet/rpcrouter"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">port</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">service</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">definitions</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div><p>这是一个标准的 SOAP 绑定，使用 RPC 风格和作为传输协议的 HTTP 与服务进行通信。在文档的 port 部分中，我定义了使用 SOAP 绑定可以访问服务的 URI。在<a href="http://www-900.ibm.com/developerWorks/cn/webservices/ws-wsif/part1/index.shtml#listing3">清单 3</a> 中，我将就通过 Apache SOAP 2.2 客户机端 API 和 WSIF 的客户机 API 使用该服务进行对比。</p><p><a name="listing3"></a><strong>清单 3：用于服务访问的 Apache SOAP API 与 WSIF API 对比<br /></strong></p><div align="left">Apache SOAP API</div><p></p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Step 1: identify the service </span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"> Call call </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Call(); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> call.setTargetObjectURI(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">urn:xmltoday-delayed-quotes</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Step 2: identify the operation </span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"> call.setMethodName(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">getQuote</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> call.setEncodingStyleURI(encodingStyleURI); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Step 3: identify the parameters </span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"> Vector params </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Vector(); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> params.addElement(</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Parameter(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">symbol</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                          String.</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">, symbol, </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> call.setParams(params); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Step 4: execute the operation </span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"> Response resp </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> call.invoke(url, <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                   </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">http://example.com/GetTradePrice</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Step 5: extract the result or fault </span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(resp.generatedFault()) <br /><img id="Codehighlighter1_624_958_Open_Image" onclick="this.style.display='none'; Codehighlighter1_624_958_Open_Text.style.display='none'; Codehighlighter1_624_958_Closed_Image.style.display='inline'; Codehighlighter1_624_958_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_624_958_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_624_958_Closed_Text.style.display='none'; Codehighlighter1_624_958_Open_Image.style.display='inline'; Codehighlighter1_624_958_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /> </span><span id="Codehighlighter1_624_958_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_624_958_Open_Text"><span style="COLOR: #000000">{ <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />   Fault fault </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> resp.getFault(); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />   System.out.println(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Ouch, the call failed: </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />   System.out.println(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">  Fault Code   = </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                      fault.getFaultCode()); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />   System.out.println(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">  Fault String = </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                      fault.getFaultString()); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />   </span><span style="COLOR: #0000ff">throw</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> SOAPException(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Execution failed </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> fault); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" /> }</span></span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> <br /><img id="Codehighlighter1_969_1072_Open_Image" onclick="this.style.display='none'; Codehighlighter1_969_1072_Open_Text.style.display='none'; Codehighlighter1_969_1072_Closed_Image.style.display='inline'; Codehighlighter1_969_1072_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_969_1072_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_969_1072_Closed_Text.style.display='none'; Codehighlighter1_969_1072_Open_Image.style.display='inline'; Codehighlighter1_969_1072_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /> </span><span id="Codehighlighter1_969_1072_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_969_1072_Open_Text"><span style="COLOR: #000000">{ <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />   Parameter result </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> resp.getReturnValue(); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />   </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> ((Float) result.getValue()).floatValue(); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" /> }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div><div align="left"><br />WSIF API</div><p></p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Step 1: identify the service </span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"> Definition def </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> WSIFUtils.readWSDL(</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">,wsdlLocation);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Step 2: identify the operation (choose an <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> appropriate service port) </span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"> WSIFDynamicPortFactory portFactory </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">  WSIFDynamicPortFactory(def, </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Get default port </span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"> WSIFPort port </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> portFactory.getPort(); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> The user can also explicitly select a port  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> to use. <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> WSIFPort port =  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">             portFactory.getPort("SOAPPort"); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Step 3: identify the parameters <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Prepare the input message </span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"> WSIFMessage input </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> port.createInputMessage(); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> input.setPart(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">symbol</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />               </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> WSIFJavaPart(String.</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">, symbol));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Prepare a placeholder for the output value </span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"> WSIFMessage output </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> port.createOutputMessage(); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Step 4: execute the operation </span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"> port.executeRequestResponseOperation(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">getQuote</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                             input, output, </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Step 5: extract the result or fault </span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"> WSIFPart part </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> output.getPart(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">quote</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> ((Float)part.getJavaValue()).floatValue();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div><p><br /></p><p>正如您可以看到的，WSIF 的 API 由以 WSDL 编写的抽象服务描述驱动；它完全从实际使用的绑定中分离出来。该调用 API 是面向 WSDL 的，并且使用它更自然，因为它使用 WSDL 术语引用消息部件（message part）、操作等等。当您阅读一个 WSDL 描述，出于直觉会想到选用支持所需端口类型的端口，然后通过提供必需抽象输入消息（由必要部件组成）调用操作（不用担心怎样将消息映射到特定的绑定协议）；WSIF API 就是这样设计的。</p><p>常用的 API，比如上面所示的 Apache SOAP API 采用了以特殊协议为中心的概念，比如在使用 SOAP 的情况下，目标 URI 和编码风格。这是不可避免的，因为 API 不是普遍适用于 WSDL，而是为特殊的协议设计。</p><p><a name="2"