﻿<?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-Terry.Li-彬-随笔分类-webservice</title><link>http://www.blogjava.net/libin2722/category/27390.html</link><description>虚其心，可解天下之问；专其心，可治天下之学；静其心，可悟天下之理；恒其心，可成天下之业。</description><language>zh-cn</language><lastBuildDate>Thu, 20 Apr 2017 12:43:20 GMT</lastBuildDate><pubDate>Thu, 20 Apr 2017 12:43:20 GMT</pubDate><ttl>60</ttl><item><title>Axis1.4 利用 deploy.wsdd 发布 server-config.wsdd文件</title><link>http://www.blogjava.net/libin2722/archive/2007/11/25/163011.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sun, 25 Nov 2007 12:31:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/archive/2007/11/25/163011.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/163011.html</wfw:comment><comments>http://www.blogjava.net/libin2722/archive/2007/11/25/163011.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/163011.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/163011.html</trackback:ping><description><![CDATA[配置axis环境变量<br />
<p>set JAVA_HOME=D:\j2sdk1.4.1_01<br />
set CATALINA_HOME=D:\Tomcat 5.0<br />
set classpath=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;<br />
set Path=%Path%;%JAVA_HOME%\bin;%CATALINA_HOME%\bin</p>
<p>set AXIS_HOME=E:\Tomcat\webapps\axis<br />
set AXIS_LIB=%AXIS_HOME%\WEB-INF\lib<br />
set AXISCLASSPATH=%AXIS_LIB%\axis.jar;%AXIS_LIB%\commons-discovery.jar;%AXIS_LIB%\commons-logging.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\saaj.jar;%AXIS_LIB%\log4j-1.2.8.jar;%AXIS_LIB%\activation.jar;%AXIS_LIB%\mail.jar;%AXIS_LIB%\wsdl4j-1.5.1.jar;%AXIS_LIB%\axis-ant.jar;%AXIS_LIB%\xmlsec.jar<br />
set classpath=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;%CATALINA_HOME%\common\lib\servlet.jar;</p>
<br />
启动tomcat ，运行-cmd&nbsp; 到deploy.wsdd文件所在目录下使用命令<br />
E:\Java\Tomcat 5.5\webapps\Axis1.4_samples2\WEB-INF&gt;java -Djava.ext.dirs="e:\Jav<br />
a\Tomcat 5.5\webapps\axis\WEB-INF\lib" org.apache.axis.client.AdminClient deploy<br />
.wsdd<br />
<br />
我的Tomca 5.5之间有个空格，所以需要将整个路径使用&#8220;&#8221;包含，运行这个命令后会在E:\Java\Tomcat 5.5\webapps\axis\WEB-INF 下生成一个 server-config.wsdd 这个就是我们需要的<br />
<br />
<br />
我的qq:33614814<br />
e-mail:libin2722@sohu.com
<img src ="http://www.blogjava.net/libin2722/aggbug/163011.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-11-25 20:31 <a href="http://www.blogjava.net/libin2722/archive/2007/11/25/163011.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个简单的WSDL文档（下） </title><link>http://www.blogjava.net/libin2722/archive/2007/11/24/162909.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 24 Nov 2007 15:43:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/archive/2007/11/24/162909.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/162909.html</wfw:comment><comments>http://www.blogjava.net/libin2722/archive/2007/11/24/162909.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/162909.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/162909.html</trackback:ping><description><![CDATA[<div class="postText">
<p>虽然发布的服务很简单，Axis帮我们生成的WSDL文档看起来却是比较复杂的，之所以这样的主要原因是WSDL要考虑到兼容各种实现和具有可扩展性，这就像我们使用一些框架做开发会使代码总量增加，而好处是使逻辑更加清晰。这篇帖子的<a href="http://www.cnblogs.com/bjzhanghao/archive/2004/10/13/51614.aspx">上半部分</a>介绍了WSDL里常用到的名称空间，现在就来说说WSDL里各元素的含义。</p>
<p>一个WSDL文档里一般包含&lt;types&gt;、&lt;message&gt;、&lt;portType&gt;、&lt;binding&gt;和&lt;service&gt;这几个元素，其中&lt;types&gt;、&lt;message&gt;和&lt;portType&gt;可以看作抽象的接口定义，而&lt;binding&gt;和&lt;service&gt;是具体的实现，注：有些时候也把&lt;binding&gt;看作接口的一部分。你也许看过一些WSDL把这两部分分开写在两个xml文件里，并在其中一个文件里引入（import）另一个的情况，这也是为什么要区分接口和实现的原因之一。在现实世界里，接口部分很可能是由某个组织（例如某行业协会）制定好的，该组织的成员在发布自己的Web服务时都要引入它，从而达到统一标准的目的。</p>
<p>&lt;types&gt;标签用来定义Web服务里用到的，XML Schema定义的数据类型以外的自定义数据类型，对于我们自定义的类（Book），会对应到一个&lt;complexType&gt;，其中用&lt;element&gt;元素指定每个参数的类型。JAX-RPC规范中规定了Java语言的数据类型到XML Schema数据类型的映射，例如int&lt;-&gt;xsd:int、java.lang.String&lt;-&gt;xsd:string等等，还有数组的映射方式。</p>
<p>&lt;message&gt;标签定义Web服务里的消息，最常见的就是请求和响应消息。&lt;message&gt;中可以有&lt;part&gt;元素，它对应Java类中各个方法的参数或返回值，例如addBook()方法有一个Book类型的参数，则在WSDL中会有&lt;part&nbsp;name="book" type="tns1:Book"/&gt;的描述。</p>
<p>&lt;portType&gt;标签表示一个服务的类型，就是接口的意思了。WSDL里有些概念很容易混淆，比如port和service的区别，我把service理解为有一个具体URL的服务，而port代表某一地址，portType是service的抽象，不知道对不对。我们看一个WSDL文档，一般就该先找&lt;portType&gt;元素，看看这个WSDL代表的Web服务里都有哪些方法，它们的参数和返回值是什么。这些方法是在&lt;portType&gt;里用&lt;operation&gt;元素表示的，&lt;operation&gt;可以有&lt;input&gt;和&lt;output&gt;子元素，表示方法的输入和输出。注意，方法可以是只有输入或只有输出的。</p>
<p>&lt;binding&gt;元素将portType与具体的传输协议绑定。现在，绝大多数都是与SOAP绑定的，对每一个方法的输入和输出，都要指定SOAP的表示方法。JAX-RPC规范规定，SOAP绑定可以有rpc和document两种类型，分别表示远程过程调用和基于消息的方式。use属性可以是encoded或literal，对于前者要支持rpc的方式，对于后者要支持rpc和document的方式，它们使得SOAP消息的格式有所区别，但我还没有仔细研究，你可以参考一下JAX-RPC 1.1版本的6.3-6.4节。又想起另外一个问题，SOAP和HTTP的关系是怎样的，绑定到SOAP就等于绑定到HTTP了吗，应该不是，那么在哪里指定Web服务绑定的应用层协议（HTTP、SMTP等等）呢？（Update: 由transport属性指定应用层协议）</p>
<p>最后，&lt;service&gt;元素通过&lt;port&gt;子元素把服务联系到一个具体的URL，更确切点，应该是把一个已绑定的portType联系到某个URL，这样就知道该把SOAP消息发给哪个服务器了。</p>
<p>我觉得之所以应该花比较多的时间理解WSDL，因为WSDL在整个Web服务中扮演了十分核心的角色，它是对Web服务的一个比较完整的语法上的描述，同时，它还与XML、SOAP以及UDDI都有着非常密切的联系，因此对于我们更好的认识Web服务体系结构是很重要的。虽然现在的Web服务开发工具都能自动进行Java&lt;-&gt;WSDL的转换，但理解WSDL对于Web服务的不论是设计、开发还是修改调试都是必要的。</p>
<p>参考资料：</p>
<ul>
    <li><a href="http://www.w3.org/TR/wsdl"><font color="#000080">Web Services Description Language (WSDL) 1.1</font></a>
    <li><a href="http://www.cnblogs.com/bjzhanghao/archive/2004/10/09/50216.aspx"><font color="#000080">使用Axis发布简单的Web服务</font></a>
    <li><a href="http://www.cnblogs.com/bjzhanghao/archive/2004/10/13/51614.aspx">一个简单的WSDL文档（上） </a></li>
</ul>
</div>
<img src ="http://www.blogjava.net/libin2722/aggbug/162909.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-11-24 23:43 <a href="http://www.blogjava.net/libin2722/archive/2007/11/24/162909.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个简单的WSDL文档（上） </title><link>http://www.blogjava.net/libin2722/archive/2007/11/24/162908.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 24 Nov 2007 15:42:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/archive/2007/11/24/162908.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/162908.html</wfw:comment><comments>http://www.blogjava.net/libin2722/archive/2007/11/24/162908.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/162908.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/162908.html</trackback:ping><description><![CDATA[<div class="postText">
<p>现在，简单解释一下<a href="http://www.cnblogs.com/bjzhanghao/archive/2004/10/09/50216.aspx">《使用Axis发布简单的Web服务》</a>中发布的Web服务所对应WSDL文档的内容和结构。请注意，同样的Java类在不同的Web服务开发包中得到的WSDL文档不一定完全相同，这里还是以使用Axis的情况作为例子。</p>
<p>虽然比较长，但为了方便起见还是把完整的WSDL贴在下面，然后进行说明。由于我对Web服务的认识还很不够，所以几乎可以肯定会存在一些误解，仅作参考。</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;?</span><span style="color: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"</span><span style="color: #0000ff">?&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdl:definitions&nbsp;</span><span style="color: #ff0000">targetNamespace</span><span style="color: #0000ff">="http://localhost:8080/bookstore/services/BookSvc"</span><span style="color: #ff0000">&nbsp;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;xmlns</span><span style="color: #0000ff">="http://schemas.xmlsoap.org/wsdl/"</span><span style="color: #ff0000">&nbsp;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;xmlns:apachesoap</span><span style="color: #0000ff">="http://xml.apache.org/xml-soap"</span><span style="color: #ff0000">&nbsp;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;xmlns:impl</span><span style="color: #0000ff">="http://localhost:8080/bookstore/services/BookSvc"</span><span style="color: #ff0000">&nbsp;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;xmlns:intf</span><span style="color: #0000ff">="http://localhost:8080/bookstore/services/BookSvc"</span><span style="color: #ff0000">&nbsp;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;xmlns:soapenc</span><span style="color: #0000ff">="http://schemas.xmlsoap.org/soap/encoding/"</span><span style="color: #ff0000">&nbsp;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;xmlns:tns1</span><span style="color: #0000ff">="http://model.bookstore.com"</span><span style="color: #ff0000">&nbsp;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;xmlns:wsdl</span><span style="color: #0000ff">="http://schemas.xmlsoap.org/wsdl/"</span><span style="color: #ff0000">&nbsp;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;xmlns:wsdlsoap</span><span style="color: #0000ff">="http://schemas.xmlsoap.org/wsdl/soap/"</span><span style="color: #ff0000">&nbsp;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;xmlns:xsd</span><span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdl:types</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">schema&nbsp;</span><span style="color: #ff0000">targetNamespace</span><span style="color: #0000ff">="http://model.bookstore.com"</span><span style="color: #ff0000">&nbsp;xmlns</span><span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">import&nbsp;</span><span style="color: #ff0000">namespace</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.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">complexType&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Book"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">sequence</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">element&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="ISDN"</span><span style="color: #ff0000">&nbsp;nillable</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000">&nbsp;type</span><span style="color: #0000ff">="xsd:string"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">element&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="name"</span><span style="color: #ff0000">&nbsp;nillable</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000">&nbsp;type</span><span style="color: #0000ff">="xsd:string"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">element&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="page"</span><span style="color: #ff0000">&nbsp;type</span><span style="color: #0000ff">="xsd:int"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">sequence</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">complexType</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Schema</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">wsdl:types</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdl:message&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="addBookResponse"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">wsdl:message</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdl:message&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="addBookRequest"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdl:part&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="book"</span><span style="color: #ff0000">&nbsp;type</span><span style="color: #0000ff">="tns1:Book"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">wsdl:message</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdl:portType&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="BookSvc"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdl:operation&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="addBook"</span><span style="color: #ff0000">&nbsp;parameterOrder</span><span style="color: #0000ff">="book"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdl:input&nbsp;</span><span style="color: #ff0000">message</span><span style="color: #0000ff">="intf:addBookRequest"</span><span style="color: #ff0000">&nbsp;name</span><span style="color: #0000ff">="addBookRequest"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdl:output&nbsp;</span><span style="color: #ff0000">message</span><span style="color: #0000ff">="intf:addBookResponse"</span><span style="color: #ff0000">&nbsp;name</span><span style="color: #0000ff">="addBookResponse"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">wsdl:operation</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">wsdl:portType</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdl:binding&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="BookSvcSoapBinding"</span><span style="color: #ff0000">&nbsp;type</span><span style="color: #0000ff">="intf:BookSvc"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdlsoap:binding&nbsp;</span><span style="color: #ff0000">style</span><span style="color: #0000ff">="rpc"</span><span style="color: #ff0000">&nbsp;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.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdl:operation&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="addBook"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdlsoap:operation&nbsp;</span><span style="color: #ff0000">soapAction</span><span style="color: #0000ff">=""</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdl:input&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="addBookRequest"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdlsoap:body&nbsp;</span><span style="color: #ff0000">encodingStyle</span><span style="color: #0000ff">="http://schemas.xmlsoap.org/soap/encoding/"</span><span style="color: #ff0000">&nbsp;namespace</span><span style="color: #0000ff">="http://bookstore.com"</span><span style="color: #ff0000">&nbsp;use</span><span style="color: #0000ff">="encoded"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">wsdl:input</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdl:output&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="addBookResponse"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdlsoap:body&nbsp;</span><span style="color: #ff0000">encodingStyle</span><span style="color: #0000ff">="http://schemas.xmlsoap.org/soap/encoding/"</span><span style="color: #ff0000">&nbsp;namespace</span><span style="color: #0000ff">="http://localhost:8080/bookstore/services/BookSvc"</span><span style="color: #ff0000">&nbsp;use</span><span style="color: #0000ff">="encoded"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">wsdl:output</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">wsdl:operation</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">wsdl:binding</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdl:service&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="BookSvcService"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdl:port&nbsp;</span><span style="color: #ff0000">binding</span><span style="color: #0000ff">="intf:BookSvcSoapBinding"</span><span style="color: #ff0000">&nbsp;name</span><span style="color: #0000ff">="BookSvc"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">wsdlsoap:address&nbsp;</span><span style="color: #ff0000">location</span><span style="color: #0000ff">="http://localhost:8080/bookstore/services/BookSvc"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">wsdl:port</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">wsdl:service</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">wsdl:definitions</span><span style="color: #0000ff">&gt;</span></div>
</div>
<p>每个WSDL的根元素都是&lt;definitions&gt;，一般都在这里定义文档中的各种名称空间。对于上面的WSDL，定义了不少名称空间，现在来说说它们的作用。</p>
<p>我们都知道，WSDL应该是格式正确的XML文档。进一步，还应该把它看作一个Schema，因此，&lt;definitions&gt;元素中可以定义targetNamespace属性，表示在这个元素下的所有元素都属于这个目标名称空间。</p>
<p>xmlns表示缺省的名称空间，请注意在上面的文档中，这个缺省名称空间的值和xmlns:wsdl的值是相同的（都是<a href="http://schemas.xmlsoap.org/wsdl/">http://schemas.xmlsoap.org/wsdl/</a>）。因此，在这个WSDL中的很多&lt;wsdl:XXX&gt;元素，例如&lt;wsdl:types&gt;、&lt;wsdl:portType&gt;等等，实际上省略掉前面的&#8220;wsdl:&#8221;效果也是一样的。</p>
<p>名称空间xmlns:apachesoap在文档中并没有使用到，这个应该是Axis为某些情况预留的名称空间，或者是为了兼容以前的版本使用，因为Axis的前身是Apache Soap项目。</p>
<p>名称空间xmlns:intf和xmlns:impl分别代表接口（interface）和实现（implement），可以看出它们的值也是相同的，并且和&lt;definitions&gt;的targetNamespace一致。这是为了在文档中引用已定义的属于该目标名称空间的元素使用的，例如&#8220;&lt;wsdl:binding name="BookSvcSoapBinding" type="intf:BookSvc"&gt;&#8221;，其中的BookSvc一定是在前面某个元素中定义的，并且属于&lt;definitions&gt;中指定的目标名称空间。Axis把intf和impl分开是有道理的，因为在很多情况下，一个WSDL会引用另外一个WSDL，后者可能只定义了数据类型、消息和端口类型这些抽象元素，而前者中定义绑定和服务端口等和实现有关的内容。这里先不做讨论。</p>
<p>名称空间xmlns:soapenc在这个文档里也没有用到，所以先不解释了。</p>
<p>名称空间xmlns:tns1，在很多WSDL里这个名字都叫tns的，没有后面的数字1，不知道Axis为什么起这样的名字。不过没有关系，名称空间的名字本来就没有实际的意义，只是一个代号而已。tns是This NameSpace的缩写，用来对当前WSDL进行引用。由于一个WSDL映射一个包（package），所以Axis为我们生成的WSDL里，tns1的值（<a href="http://model.bookstore.com/">http://model.bookstore.com</a>）包含java包（com.bookstore.model）的信息就是顺理成章的了。请注意，tns1的值和&lt;wsdl:types&gt;里的&lt;schema&gt;元素的targetNamespace值是相同的。</p>
<p>名称空间xmlns:wsdlsoap是在与soap绑定时使用的，例如&lt;wsdlsoap:binding&gt;、&lt;wsdlsoap:operation&gt;等元素会用到。</p>
<p>名称空间xmlns:xsd是对XML Schema中各种数据类型的引用，例如string、boolean等等。想知道XML Schema中一共都定义了哪些数据类型，只要查看该名称空间的值（<a href="http://www.w3.org/2000/10/XMLSchema">http://www.w3.org/2000/10/XMLSchema</a>）即可。</p>
<p>没想到只是名称空间就写了这么多，而WSDL的结构还有不少内容，所以还是分为两部分吧，下一篇说说这个WSDL中的各个元素的作用。</p>
<p>参考资料：</p>
<ul>
    <li><a href="http://www.w3.org/TR/wsdl">Web Services Description Language (WSDL) 1.1</a>
    <li><a href="http://www-900.ibm.com/developerWorks/cn/xml/xml-schema/index.shtml">使用 XML Schema 定义元素的基本知识</a>
    <li><a href="http://www.cnblogs.com/bjzhanghao/archive/2004/10/09/50216.aspx">使用Axis发布简单的Web服务</a></li>
</ul>
</div>
<img src ="http://www.blogjava.net/libin2722/aggbug/162908.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-11-24 23:42 <a href="http://www.blogjava.net/libin2722/archive/2007/11/24/162908.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Axis发布简单的Web服务（补充） </title><link>http://www.blogjava.net/libin2722/archive/2007/11/24/162907.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 24 Nov 2007 15:41:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/archive/2007/11/24/162907.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/162907.html</wfw:comment><comments>http://www.blogjava.net/libin2722/archive/2007/11/24/162907.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/162907.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/162907.html</trackback:ping><description><![CDATA[<p>这篇帖子是对《使用Axis发布简单的Web服务》的补充。</p>
<p>可以看出，在Axis里书写deploy.wsdd并利用org.apache.axis.client.AdminClient发布，其主要工作就是把&lt;service&gt;标签中的内容添加在server-config.wsdd里，所以一般直接编辑server-config.wsdd文件会更方便一些。不过当你还没有server-config.wsdd文件时，使用deploy.wsdd的方法会更方便些，因为AdminClient会帮你生成一些额外的xml元素（&lt;handler&gt;等等），而这些元素是必要的。</p>
<p>服务发布以后，就可以在IE浏览器里看到它的WSDL，一般是服务的URL后面加一个&#8220;?wsdl&#8221;，例如添加图书的WSDL可以通过<a href="http://localhost:8080/bookstore/services/BookSvc?wsdl">http://localhost:8080/bookstore/services/BookSvc?wsdl</a>看到。至于Java类是以何种规则映射到WSDL的，请参考<a href="http://java.sun.com/xml/jaxrpc/index.jsp">JAX-RPC</a>规范；WSDL本身的说明见<a href="http://www.w3.org/TR/wsdl">这里</a>；为了搞清生成的WSDL中各种URL格式的名称空间，最好对XML Schema有所了解，我觉得<a href="http://www-900.ibm.com/developerWorks/cn/xml/xml-schema/index.shtml">这篇文章</a>还不错。</p>
<p>我们还可以通过IE浏览器直接调用服务，方法是在服务URL后加&#8220;method=xxx&#8221;，其中xxx是要调用的方法名称。例如可以通过<a href="http://localhost:8080/bookstore/services/BookSvc?method=addBook">http://localhost:8080/bookstore/services/BookSvc?method=addBook</a>调用添加图书方法，按照我们的服务类，在Tomcat的控制台上应该可以看到打出了&#8220;Book has been added.&#8221;的字样。</p>
<p>因为添加图书方法的参数是一个自定义类型，所以在IE里调用时不能指定参数值（或者是可以以其他格式指定，但我还不知道）；如果参数是简单类型，就可以指定了。例如我们可以为BookSvc增加一个echo()方法，参数是一个java.lang.String类型的值，如下所示，然后重新编译并启动Tomcat（server-config.wsdd文件不必更改）。</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><span style="color: #000000">public&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;echo(String&nbsp;str){<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">Hello&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">+</span><span style="color: #000000">str);<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />}<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /></span></div>
</div>
<p>在IE里输入<a href="http://localhost:8080/bookstore/services/BookSvc?method=echo&amp;str=Mike">http://localhost:8080/bookstore/services/BookSvc?method=echo&amp;str=Mike</a>，就会看到Tomcat的控制台里打出了&#8220;Hello Mike&#8221;。如果有多个参数，只要把这些参数都列在URL里即可。</p> <img src ="http://www.blogjava.net/libin2722/aggbug/162907.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-11-24 23:41 <a href="http://www.blogjava.net/libin2722/archive/2007/11/24/162907.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Axis发布简单的Web服务 </title><link>http://www.blogjava.net/libin2722/archive/2007/11/24/162905.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 24 Nov 2007 15:39:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/archive/2007/11/24/162905.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/162905.html</wfw:comment><comments>http://www.blogjava.net/libin2722/archive/2007/11/24/162905.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/162905.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/162905.html</trackback:ping><description><![CDATA[<p>使用Axis，要发布一个Web服务非常简单，简直不能再简单了，尽管看起来过程和相关代码有些长。我这个帖子里用到了这些软件：Axis 1.1、Eclipse 2.1和Eclipse的Tomcat插件2.2（<a href="http://www.sysdeo.com/eclipse/tomcatPlugin.html">Sysdeo Tomcat plugin</a>）。发布的方法如下：</p>
<p>我要发布的服务是一个图书商店，公布的方法有添加图书addBook、列表图书listBooks、删除图书deleteBook等等，为简单起见这里就只发布一个添加图书方法，因为其他方法的发布是类似的。</p>
<p>1、首先在Eclipse里新建一个名为bookstore的Tomcat工程，注意要安装了前面说的Tomcat插件才有这个选项的。如果没有安装可以建立一个java工程，然后手动建立必要的目录结构（WEB-INF等），并在Tomcat的server.xml里手动增加与项目对应的&lt;context&gt;项。</p>
<p>2、接下来建立图书类（com.bookstore.model.Book），图书有名称、ISDN号和页数三个属性，这是一个Bean类，代码如下：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">package&nbsp;com.bookstore.model;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />public&nbsp;class&nbsp;Book&nbsp;{<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;String&nbsp;name;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;String&nbsp;ISDN;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;page;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;String&nbsp;getISDN()&nbsp;{<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;ISDN;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;String&nbsp;getName()&nbsp;{<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;name;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;getPage()&nbsp;{<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;page;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;setISDN(String&nbsp;string)&nbsp;{<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ISDN&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;string;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;setName(String&nbsp;string)&nbsp;{<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;string;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;setPage(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i)&nbsp;{<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;page&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;i;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />}<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
</div>
<p>3、接下来建立用来提供服务的类（com.bookstore.BookSvc），这个类就是实际的功能类了，它里面只有一个public的addBook()方法，而它的参数只有一个就是要添加的图书。代码如下：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">package&nbsp;com.bookstore;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />import&nbsp;com.bookstore.model.Book;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />public&nbsp;class&nbsp;BookSvc&nbsp;{<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;addBook(Book&nbsp;book){<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">here&nbsp;you&nbsp;save&nbsp;a&nbsp;book&nbsp;into&nbsp;database</span><span style="color: #008000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">Book&nbsp;has&nbsp;been&nbsp;added.</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />}<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
</div>
<p>4、现在，把下载来的Axis解压缩到一个文件夹，这里假设你解到C:\axis-1_1。把C:\axis-1_1\webapps\axis\WEB-INF\lib目录下的所有.jar文件复制到你的这个web应用程序的WEB-INF\lib下，再把C:\axis-1_1\webapps\axis\WEB-INF目录下的web.xml复制到你的web应用程序的WEB-INF下。这个步骤相当于在你的web应用程序中配置了Axis。</p>
<p>5、为了让Axis知道你要发布哪些服务，你得在WEB-INF下建立一个名为server-config.wsdd的文件，内容如下：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;?</span><span style="color: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"</span><span style="color: #0000ff">?&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">deployment&nbsp;</span><span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="http://xml.apache.org/axis/wsdd/"</span><span style="color: #ff0000">&nbsp;xmlns:java</span><span style="color: #0000ff">="http://xml.apache.org/axis/wsdd/providers/java"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">globalConfiguration</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="adminPassword"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="admin"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="attachments.Directory"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="C:\eclipse\workspace\bookstore\WEB-INF\attachments"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="attachments.implementation"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="org.apache.axis.attachments.AttachmentsImpl"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="sendXsiTypes"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="true"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="sendMultiRefs"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="true"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="sendXMLDeclaration"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="true"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="axis.sendMinimizedElements"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="true"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">requestFlow</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">handler&nbsp;</span><span style="color: #ff0000">type</span><span style="color: #0000ff">="java:org.apache.axis.handlers.JWSHandler"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="scope"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="session"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">handler</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">handler&nbsp;</span><span style="color: #ff0000">type</span><span style="color: #0000ff">="java:org.apache.axis.handlers.JWSHandler"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="scope"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="request"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="extension"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">=".jwr"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">handler</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">requestFlow</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">globalConfiguration</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">handler&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="LocalResponder"</span><span style="color: #ff0000">&nbsp;type</span><span style="color: #0000ff">="java:org.apache.axis.transport.local.LocalResponder"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">handler&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Authenticate"</span><span style="color: #ff0000">&nbsp;type</span><span style="color: #0000ff">="java:org.apache.axis.handlers.SimpleAuthenticationHandler"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">handler&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="URLMapper"</span><span style="color: #ff0000">&nbsp;type</span><span style="color: #0000ff">="java:org.apache.axis.handlers.http.URLMapper"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">service&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Version"</span><span style="color: #ff0000">&nbsp;provider</span><span style="color: #0000ff">="java:RPC"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="allowedMethods"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="getVersion"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="className"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="org.apache.axis.Version"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</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.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">service&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="BookSvc"</span><span style="color: #ff0000">&nbsp;provider</span><span style="color: #0000ff">="java:RPC"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="allowedMethods"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="*"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="className"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="com.bookstore.BookSvc"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</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.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">service&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="AdminService"</span><span style="color: #ff0000">&nbsp;provider</span><span style="color: #0000ff">="java:MSG"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="allowedMethods"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="AdminService"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="enableRemoteAdmin"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="false"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="className"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="org.apache.axis.utils.Admin"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">namespace</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">http://xml.apache.org/axis/wsdd/</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">namespace</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</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.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">transport&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="local"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">responseFlow</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">handler&nbsp;</span><span style="color: #ff0000">type</span><span style="color: #0000ff">="LocalResponder"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">responseFlow</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">transport</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">transport&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="http"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">requestFlow</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">handler&nbsp;</span><span style="color: #ff0000">type</span><span style="color: #0000ff">="URLMapper"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">handler&nbsp;</span><span style="color: #ff0000">type</span><span style="color: #0000ff">="java:org.apache.axis.handlers.http.HTTPAuthHandler"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">requestFlow</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">transport</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">deployment</span><span style="color: #0000ff">&gt;</span></div>
</div>
<p>这个文件里发布了三个服务：Version、AdminService和我们的BookSvc。还有一个方法可以生成这个文件，好象Axis推荐使用这种生成的方法，就是在同样目录下写一个deploy.wsdd文件（如果不想看可以直接跳到下一步），内容如下：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">deployment&nbsp;</span><span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="http://xml.apache.org/axis/wsdd/"</span><span style="color: #ff0000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmlns:java</span><span style="color: #0000ff">="http://xml.apache.org/axis/wsdd/providers/java"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">service&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="BookSvc"</span><span style="color: #ff0000">&nbsp;provider</span><span style="color: #0000ff">="java:RPC"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="className"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="com.bookstore.BookSvc"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">parameter&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="allowedMethods"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="*"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</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.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">deployment</span><span style="color: #0000ff">&gt;</span></div>
</div>
<p>也就是说deploy.wsdd里只包含关于我们的服务的描述，确认Tomcat已经启动，然后在同一目录下用下面这个命令生成server-config.wsdd文件：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">java&nbsp;org.apache.axis.client.AdminClient&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">lhttp:</span><span style="color: #008000">//</span><span style="color: #008000">localhost:8080/bookstore/services/AdminService&nbsp;deploy.wsdd</span></div>
</div>
<p>其中bookstore是我这个web应用程序的虚拟路径。</p>
<p align="justify">6、重新启动Tomcat，访问路径<a href="http://localhost:8080/bookstore/services">http://localhost:8080/bookstore/services</a>，就可以看到现在发布了三个Web服务，如下图。点击每个服务后的wsdl链接可以看到对应的WSDL描述。</p>
<p align="center"><img height="396" src="http://www.cnblogs.com/images/cnblogs_com/bjzhanghao/axis-services.gif" width="594" border="0"  alt="" /></p>
<p align="justify">相关链接：</p>
<img src ="http://www.blogjava.net/libin2722/aggbug/162905.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-11-24 23:39 <a href="http://www.blogjava.net/libin2722/archive/2007/11/24/162905.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用axis发布webservices（五）</title><link>http://www.blogjava.net/libin2722/archive/2007/11/24/162845.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 24 Nov 2007 07:01:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/archive/2007/11/24/162845.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/162845.html</wfw:comment><comments>http://www.blogjava.net/libin2722/archive/2007/11/24/162845.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/162845.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/162845.html</trackback:ping><description><![CDATA[Web 服务安全性相关技术和开发工具<br />
<br />
Web 服务安全性规范是一套可以帮助 Web 服务开发者保证 SOAP 消息交换的安全的机制。WS-Security 特别描述了对现有的 SOAP 消息传递的增强，从而通过对 SOAP 消息应用消息完整性、消息机密性和单消息认证提供了保护级别。这些基本机制可以通过各种方式联合，以适应构建使用多种加密技术的多种安全性模型。<br />
<br />
围绕Web服务的安全，有很多相关的技术，比如WS-Security，WS-Trace等，另外，还有以下相关技术：<br />
<br />
XML Digital Signature（XML数字签名） <br />
XML Encryption （XML加密） <br />
XKMS (XML Key Management Specification) <br />
XACML (eXtensible Access Control Markup Language) <br />
SAML (Secure Assertion Markup Language) <br />
ebXML Message Service Security <br />
Identity Management &amp; Liberty Project <br />
由于本文是一个实例性文章，故不对WS-Security做详细的探讨，你可以在develperWorks Web 服务安全专题找到许多相关资料（见参考资料）。<br />
<br />
Trust Services Integration Kit提供了一个WS-Security实现。你可以从http://www.xmltrustcenter.org获得相关库文件，分别是wssecurity.jar和tsik.jar。wssecurity.jar中包含一个WSSecurity类，可以使用它来对XML进行数字签名和验证，加密与解密。<br />
<br />
下面我们使用WS-Security来对SOAP消息进行数字签名，然后再进行验证。<br />
<br />
<br />
<br />
&nbsp;<br />
<br />
<br />
&nbsp;回页首 <br />
&nbsp;<br />
<br />
<br />
<br />
SOAP消息的签名和验证<br />
<br />
使用WSSecurity对SOAP消息数字签名<br />
<br />
在对SOAP消息进行签名前，首先生成一个keystore。keystore包含了进行数字签名所需要的身份信息。通过以下批处理脚本来创建keystore：<br />
<br />
<br />
例程1 创建keystore（server.keystore）<br />
<br />
set SERVER_DN="CN=hellking-Server, OU=huayuan, O=huayuan, L=BEIJINGC, S=BEIJING, C=CN"<br />
set KS_PASS=-storepass changeit<br />
set KS_TYPE=-storetype JKS<br />
set KEYINFO=-keyalg RSA<br />
#生成服务器端keystore。<br />
keytool -genkey -dname %SERVER_DN% %KS_PASS% %KS_TYPE% -keystore <br />
server.keystore %KEYINFO% -keypass changeit<br />
&nbsp;<br />
<br />
<br />
SignAndVerifySoap类中包含了一个对XML进行签名的方法，它就是sign（），这个方法将对SOAP消息进行签名，然后输出和WS-Security兼容的SOAP消息。下面我们看具体代码。<br />
<br />
<br />
例程2 对SOAP消息签名<br />
<br />
&nbsp;&nbsp;&nbsp; package com.hellking.study.webservice;<br />
import com.verisign.messaging.WSSecurity;<br />
...<br />
public class SignAndVerifySoap {<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; final String KEY_STORE = "server.keystore";<br />
&nbsp;&nbsp;&nbsp; final String SOTE_PASS = "changeit";<br />
&nbsp;&nbsp;&nbsp; final String KEY_ALIAS="mykey";<br />
&nbsp;&nbsp;&nbsp; final String TARGET_FILE="signed.xml";//签名后的SOAP消息<br />
&nbsp;&nbsp;&nbsp; final String SOURE_FILE="source.xml";//签名前的SOAP消息<br />
&nbsp;&nbsp;&nbsp; final String KEY_TYPE="JKS";<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp; &nbsp;*对xml进行签名<br />
&nbsp;&nbsp;&nbsp; &nbsp;*/<br />
&nbsp;&nbsp;&nbsp; public void sign()<br />
&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp; <br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; try<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("开始对SOAP消息进行签名，使用的密匙库：" + KEY_STORE + "\n");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 获得私有key和相关证书，请参考JAVA安全编程相关书籍<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; FileInputStream fileInputStream = new FileInputStream(KEY_STORE);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println(java.security.KeyStore.getDefaultType());<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; java.security.KeyStore store = java.security.KeyStore.getInstance(KEY_TYPE);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; store.load(fileInputStream, SOTE_PASS.toCharArray());<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; PrivateKey key = (PrivateKey)store.getKey(KEY_ALIAS, SOTE_PASS.toCharArray());<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; X509Certificate certification = (X509Certificate)store.getCertificate(KEY_ALIAS);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 读取XML源文件到文档中<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Document source = readFile(SOURE_FILE);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; SigningKey signingKey = SigningKeyFactory.makeSigningKey(key);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; KeyInfo keyInfo = new KeyInfo();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; keyInfo.setCertificate(certification);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WSSecurity wsSecurity = new WSSecurity();<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; wsSecurity.setPreferredNamespace("http://schemas.xmlsoap.org/ws/2003/06/secext");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //对SOAP消息进行签名<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; wsSecurity.sign(source, signingKey, keyInfo);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 保存签名后的SOAP消息&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; writeFile(source, new FileOutputStream(TARGET_FILE));<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("把签名后的文件写入： " + TARGET_FILE + "，请查看结果！");<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; catch(Exception e)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;<br />
<br />
<br />
在执行此程序前，请把wssecurity.jar、source.xml和tsik.jar设置到类路径环境变量中。签名前的SOAP为：<br />
<br />
<br />
例程3 签名前的SOAP消息（source.xml）<br />
<br />
&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
&lt;soapenv:Envelope <br />
&nbsp;&nbsp;&nbsp; xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" <br />
&nbsp;&nbsp;&nbsp; xmlns:xsd="http://www.w3.org/2001/XMLSchema" <br />
&nbsp;&nbsp;&nbsp; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;<br />
&nbsp;&lt;soapenv:Body&gt;<br />
&nbsp; &lt;ns1:getTax soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"<br />
xmlns:ns1="http://hellking.webservices.com/"&gt;<br />
&nbsp;&nbsp; &lt;op1 xsi:type="xsd:double"&gt;5000.0&lt;/op1&gt;<br />
&nbsp; &lt;/ns1:getTax&gt;<br />
&nbsp;&lt;/soapenv:Body&gt;<br />
&lt;/soapenv:Envelope&gt;<br />
&nbsp;<br />
<br />
<br />
签名后的SOAP消息如例程4所示。<br />
<br />
<br />
例程4 签名后的SOAP消息（signed.xml）<br />
<br />
&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" <br />
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;<br />
&nbsp;&lt;soapenv:Header&gt;<br />
&lt;wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext"&gt;<br />
&lt;wsse:BinarySecurityToken EncodingType="wsse:Base64Binary" <br />
ValueType="wsse:X509v3" wsu:Id="wsse-ee805a80-cd95-11d8-9cf9-fd6213c0f8be" <br />
xmlns:wsu="http://schemas.xmlsoap.org/ws/2003/06/utility"&gt;MIICUjCCAbsCBEDB0GIwDQYJKoZIhvcNAQE&#8230;VkTkPw==<br />
&lt;/wsse:BinarySecurityToken&gt;<br />
&lt;ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&gt;<br />
&lt;ds:SignedInfo&gt;<br />
&lt;ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/&gt;<br />
&lt;ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/&gt;<br />
&lt;ds:Reference URI="#wsse-ee5308f0-cd95-11d8-9cf9-fd6213c0f8be"&gt;<br />
&lt;ds:Transforms&gt;&lt;ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/&gt;<br />
&lt;/ds:Transforms&gt;&lt;ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/&gt;<br />
&lt;ds:DigestValue&gt;ZjRVnI2g7kcX0h9r4JtiltpYQPA=&lt;/ds:DigestValue&gt;&lt;/ds:Reference&gt;<br />
&lt;ds:Reference URI="#wsse-ee4e4e00-cd95-11d8-9cf9-fd6213c0f8be"&gt;<br />
&lt;ds:Transforms&gt;&lt;ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/&gt;<br />
&lt;/ds:Transforms&gt;&lt;ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/&gt;<br />
&lt;ds:DigestValue&gt;moZ0d+8mH1kfNw0VEK39V0Td9EM=&lt;/ds:DigestValue&gt;<br />
&lt;/ds:Reference&gt;<br />
&lt;/ds:SignedInfo&gt;<br />
&lt;ds:SignatureValue&gt;fPpYrf0uNP8W2XVVIQNc3OQt2Wn90M/0uJ0dDZTNRR0NxBBBX36wSXt7NfI5Fmh4ru44Wk34EGI7mqMAE5O0<br />
/wtIlFRJt3zAvA6k3nhgcYj6tn/9kZwwxh1RkFTfTX9xdQ6Xn+P6m+YBm1YEEcTWkJd7XcxdyDEns2kYOhONx1U=<br />
&lt;/ds:SignatureValue&gt;<br />
&lt;ds:KeyInfo&gt;&lt;wsse:SecurityTokenReference&gt;<br />
&lt;wsse:Reference URI="#wsse-ee805a80-cd95-11d8-9cf9-fd6213c0f8be"/&gt;<br />
&lt;/wsse:SecurityTokenReference&gt;<br />
&lt;/ds:KeyInfo&gt;<br />
&lt;/ds:Signature&gt;&lt;/wsse:Security&gt;<br />
&lt;wsu:Timestamp xmlns:wsu="http://schemas.xmlsoap.org/ws/2003/06/utility"&gt;<br />
&lt;wsu:Created wsu:Id="wsse-ee4e4e00-cd95-11d8-9cf9-fd6213c0f8be"&gt;2004-07-04T08:41:23Z&lt;/wsu:Created&gt;<br />
&lt;/wsu:Timestamp&gt;&lt;/soapenv:Header&gt;<br />
&lt;soapenv:Body wsu:Id="wsse-ee5308f0-cd95-11d8-9cf9-fd6213c0f8be" <br />
&nbsp;&nbsp;&nbsp; xmlns:wsu="http://schemas.xmlsoap.org/ws/2003/06/utility"&gt;<br />
&nbsp; &lt;ns1:getTax soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" <br />
&nbsp; &nbsp;&nbsp;&nbsp; xmlns:ns1="http://hellking.webservices.com/"&gt;<br />
&nbsp;&nbsp; &lt;op1 xsi:type="xsd:double"&gt;5000.0&lt;/op1&gt;<br />
&nbsp; &lt;/ns1:getTax&gt;<br />
&nbsp;&lt;/soapenv:Body&gt;<br />
&lt;/soapenv:Envelope&gt;<br />
&nbsp;<br />
<br />
<br />
签名后的SOAP消息中，头部包含了签名信息以及验证SOAP消息所需要的key。&lt;SignedInfo&gt; &lt;/SignedInfo&gt; 描述了已签署的消息内容。&lt;SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/&gt; 指出了签名算法（Signature Method Algorithm）。这个算法被用来将规范算法的输出转换成签名值（Signature Value）。Key Info 元素包含的部分就是数字证书本身。<br />
<br />
对签名的SOAP消息进行验证<br />
<br />
对SOAP消息进行验证就是使用keystore的信息生成TrustVerifier对象，然后调用WSSecurity的verify方法进行验证。<br />
<br />
<br />
例程5 验证签名后的SOAP消息<br />
<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp; &nbsp;*验证已经签名的SOAP消息<br />
&nbsp;&nbsp;&nbsp; &nbsp;*/<br />
&nbsp;&nbsp;&nbsp; public void verify()<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; try<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("开始检验SOAP消息，使用的密匙库：" + KEY_STORE + "\n");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 获得私有key和相关证书，请参考JAVA安全编程相关书籍<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; FileInputStream fileInputStream = new FileInputStream(KEY_STORE);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; java.security.KeyStore store = java.security.KeyStore.getInstance(KEY_TYPE);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; store.load(fileInputStream, SOTE_PASS.toCharArray());<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 读取XML源文件到文档中<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Document source = readFile(TARGET_FILE);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; org.xmltrustcenter.verifier.TrustVerifier verifier =<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new org.xmltrustcenter.verifier.X509TrustVerifier(store);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WSSecurity wsSecurity = new WSSecurity();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; com.verisign.messaging.MessageValidity[] resa =<br />
&nbsp;&nbsp;&nbsp;&nbsp; wsSecurity.verify(source,verifier,null,null);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("检验结果：");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; for (int len = 0; len &lt; resa.length; len++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("result[" + len + "] = " + (resa[len].isValid()?"验证通过":"验证不通过"));<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; catch(Exception e)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
&nbsp;<br />
<br />
<br />
执行SignAndVerifySoap的verify方法，可以看到类似以下的结果。<br />
<br />
<br />
图1 对SOAP消息进行验证<br />
&nbsp;<br />
<br />
<br />
&nbsp;<br />
<br />
<br />
&nbsp;回页首 <br />
&nbsp;<br />
<br />
<br />
<br />
在AXIS下实现WS-Security的应用框架<br />
<br />
待开发的应用开发框架基于Handler实现，将达到以下目标：此框架基于JAX-RPC环境下实现WS-Security应用，它可以部署到任何需要实现WS-Security的axis环境下的Web服务应用中，同时具体的应用程序不做任何编码修改。<br />
<br />
由于此基于Handler实现，我们有必要回顾一下Handler的一些基础知识。<br />
<br />
SOAP消息Handler能够访问代表RPC请求或者响应的SOAP消息。在JAX-RPC技术中，SOAP消息Handler可以部署在服务端，也可以在客户端使用。<br />
<br />
SOAP消息Handler非常像Servlet技术中的Filter，它们共同的特点是请求发送到目标前，Handler/Filter可以截取这些请求，并对请求做一些处理，从而达到一些辅助的功能。多个Handler可以组成一个Handler链，链上的每个Handler都完成某个特定的任务。比如有的Handler进行权限验证，有的Handler进行日志处理等。关于Handler更详细的介绍，请参考本系列文章《 J2EE Web服务开发系列之六: 使用Handler来增强Web服务的功能》。 <br />
<br />
实现原理<br />
<br />
图2是此例子具体实现原理图。<br />
<br />
<br />
图2 Handler结合WSSecurity实现Web服务安全的工作原理<br />
&nbsp;<br />
<br />
处理流程如下：<br />
<br />
1、 客户端（WSSClient）发出调用Web服务请求；<br />
<br />
2、 客户端Handler（WSSecurityClientHandler）截获请求的SOAP消息；<br />
<br />
3、 客户端Handler对截获的SOAP消息进行数字签名（使用client.keystore作为签名依据）；<br />
<br />
4、 客户端Handler对签名后的SOAP消息进行加密（使用RSA算法加密）；<br />
<br />
5、 被加密的SOAP消息通过互联网传送到目标Web服务端口；<br />
<br />
6、 服务器端Handler（WSSecurityServerHandler）截获加密的SOAP消息；<br />
<br />
7、 服务器端Handler对加密的SOAP消息进行解密；<br />
<br />
8、 服务器端Handler对SOAP消息进行身份验证（server.truststore包含了所信任的身份信息），如果验证不通过，将抛出异常；<br />
<br />
9、 服务器端Handler删除被解密后的SOAP消息中与WS-Security相关的元素；<br />
<br />
10、 解密后的原始SOAP消息被发送到目标Web服务端口（如TaxService）；<br />
<br />
11、 目标Web服务对Web服务请求进行处理，然后返回响应的SOAP消息； <br />
12、 服务器端Handler截获响应的SOAP消息；<br />
<br />
13、 服务器端Handler对截获的SOAP消息进行数字签名（使用server.keystore作为签名依据）；<br />
<br />
14、 服务器端Handler对签名后的SOAP消息进行加密（使用RSA算法加密）；<br />
<br />
15、 被加密的SOAP消息通过互联网传送到目客户端；<br />
<br />
16、 客户端Handler截获加密的SOAP消息；<br />
<br />
17、 客户端Handler对加密的SOAP消息进行解密；<br />
<br />
18、 客户端Handler对SOAP消息进行身份验证（client.truststore包含了所信任的身份信息），如果验证不通过，将抛出异常；<br />
<br />
19、 客户端Handler删除被解密后的SOAP消息中与WS-Security相关的元素；<br />
<br />
20、 被解密后的SOAP消息发送到目标客户端，客户端输出调用结果。<br />
<br />
从上面可以看出，在一个SOAP调用回合中，要对SOAP消息进行四次处理。基本上都是"签名'加密'解密'验证"的过程。<br />
<br />
创建相关密匙库<br />
<br />
客户端和服务端都有相关的密匙库，其中：<br />
<br />
client.keystore：客户端自身的身份信息； <br />
client.truststore：客户端所信任的身份信息，在此例中也就是包含了服务器的身份信息； <br />
server.keystore：服务器自身的身份信息； <br />
server.truststore：服务器所信任的身份信息（即客户端身份信息）。 <br />
你可以使用以下的批处理脚本创建上面四个密匙库。<br />
<br />
<br />
例程6 创建相关密匙库（gen-cer-store.bat）<br />
<br />
set SERVER_DN="CN=hellking-Server, OU=huayuan, O=huayuan, L=BEIJINGC, S=BEIJING, C=CN"<br />
set CLIENT_DN="CN=hellking-Client, OU=tsinghua, O=tsinghua, L=BEIJING, S=BEIJING, C=CN"<br />
set KS_PASS=-storepass changeit<br />
set KEYINFO=-keyalg RSA<br />
#生成server.keystore。<br />
keytool -genkey -dname %SERVER_DN% %KS_PASS% -keystore server.keystore %KEYINFO% -keypass changeit<br />
#从server.keystore导出数字证书。<br />
keytool -export -file test_axis.cer %KS_PASS% -keystore server.keystore<br />
#从服务器的数字证书导出到客户端信任的truststore中。<br />
keytool -import -file test_axis.cer %KS_PASS% -keystore client.truststore -alias serverkey -noprompt<br />
<br />
#生成client.keystore。<br />
keytool -genkey -dname %CLIENT_DN% %KS_PASS% -keystore client.keystore %KEYINFO% -keypass changeit<br />
#从client.keystore导出数字证书。<br />
keytool -export -file test_axis.cer %KS_PASS% -keystore client.keystore<br />
#从客户端的数字证书导出到服务器信任的truststore中。<br />
keytool -import -file test_axis.cer %KS_PASS% -keystore server.truststore -alias clientkey -noprompt<br />
<br />
#end<br />
&nbsp;<br />
<br />
<br />
签名、加密、解密、身份验证的实现<br />
<br />
对SOAP消息的签名、加密、解密、身份验证都放在一个名为WSSHelper的类中进行。<br />
<br />
<br />
例程7 签名、加密、解密、身份验证功能的实现――WSSHelper.java<br />
<br />
package com.hellking.study.webservice;<br />
import com.verisign.messaging.WSSecurity;<br />
...<br />
public class WSSHelper {<br />
&nbsp;&nbsp;&nbsp; static String PROVIDER="ISNetworks";//JSSE安全提供者。&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp; //添加JSSE安全提供者，你也可以使用其它安全提供者。只要支持DESede算法。<br />
&nbsp;&nbsp;&nbsp; static<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; java.security.Security.addProvider(new com.isnetworks.provider.jce.ISNetworksProvider());<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; *对XML文档进行数字签名。<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public static void sign(Document doc, String keystore, String storetype,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; String storepass, String alias, String keypass) throws Exception {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; FileInputStream fileInputStream = new FileInputStream(keystore);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; java.security.KeyStore keyStore = java.security.KeyStore.getInstance(storetype);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; keyStore.load(fileInputStream, storepass.toCharArray());<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; PrivateKey key = (PrivateKey)keyStore.getKey(alias, keypass.toCharArray());<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; X509Certificate cert = (X509Certificate)keyStore.getCertificate(alias);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; SigningKey sk = SigningKeyFactory.makeSigningKey(key);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; KeyInfo ki = new KeyInfo();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ki.setCertificate(cert);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WSSecurity wSSecurity = new WSSecurity();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; wSSecurity.sign(doc, sk, ki);//签名。<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; *对XML文档进行身份验证。<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public static boolean verify(Document doc, String keystore, String storetype,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; String storepass) throws Exception {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; FileInputStream fileInputStream = new FileInputStream(keystore);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; java.security.KeyStore keyStore = java.security.KeyStore.getInstance(storetype);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; keyStore.load(fileInputStream, storepass.toCharArray());<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; TrustVerifier verifier = new X509TrustVerifier(keyStore);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WSSecurity wSSecurity = new WSSecurity();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MessageValidity[] resa = wSSecurity.verify(doc, verifier, null,null);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (resa.length &gt; 0)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return resa[0].isValid();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return false;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp; *对XML文档进行加密。必须有JSSE提供者才能加密。<br />
&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public static void encrypt(Document doc, String keystore, String storetype,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; String storepass, String alias) throws Exception {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; try<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; FileInputStream fileInputStream = new FileInputStream(keystore);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; java.security.KeyStore keyStore = java.security.KeyStore.getInstance(storetype);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; keyStore.load(fileInputStream, storepass.toCharArray());<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; X509Certificate cert = (X509Certificate)keyStore.getCertificate(alias);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; PublicKey pubk = cert.getPublicKey();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede",PROVIDER);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; keyGenerator.init(168, new SecureRandom());<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; SecretKey key = keyGenerator.generateKey();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; KeyInfo ki = new KeyInfo();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ki.setCertificate(cert);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WSSecurity wSSecurity = new WSSecurity();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //加密。<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; wSSecurity.encrypt(doc, key, AlgorithmType.TRIPLEDES, pubk, AlgorithmType.RSA1_5, ki);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; catch(Exception e)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; *对文档进行解密。<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public static void decrypt(Document doc, String keystore, String storetype,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; String storepass, String alias, String keypass) throws Exception {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; FileInputStream fileInputStream = new FileInputStream(keystore);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; java.security.KeyStore keyStore = java.security.KeyStore.getInstance(storetype);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; keyStore.load(fileInputStream, storepass.toCharArray());<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; PrivateKey prvk2 = (PrivateKey)keyStore.getKey(alias, keypass.toCharArray());<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WSSecurity wSSecurity = new WSSecurity();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //解密。<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; wSSecurity.decrypt(doc, prvk2, null);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WsUtils.removeEncryptedKey(doc);//从 WS-Security Header中删除 EncryptedKey 元素<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; public static void removeWSSElements(Document doc) throws Exception {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WsUtils.removeWSSElements(doc);// 删除WSS相关的元素。<br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
}<br />
&nbsp;<br />
<br />
<br />
WSSHelper类中使用了ISNetworks安全提供者，ISNetworks实现了RSA加密、解密算法。当然，你也可以使用其它的安全提供者，并且可以使用不同的加密算法。可以从网络上下载ISNetworks相关包。<br />
<br />
WSSHelper中包含了一个WsUtils类，它的功能就是从加密后的SOAP消息中删除一些WS-Security元素，删除这些元素后的SOAP消息才能被最终的客户端或者Web服务端处理。<br />
<br />
服务器端Handler开发<br />
<br />
当请求到达后，服务端Handler调用handleRequest方法，执行如下过程：对请求SOAP消息解密'身份验证'删除WSS元素'把Document转换成SOAP消息。 Web服务端点对请求做出响应后，将调用handleResponse方法，执行如下过程：对响应的SOAP消息进行数字签名'加密'把Document转换成SOAP消息。<br />
<br />
<br />
例程8 服务器端Handler（WSSecurityServerHandler.java）<br />
<br />
package com.hellking.study.webservice;<br />
...<br />
<br />
//服务器端Handler<br />
public class WSSecurityServerHandler implements Handler <br />
{<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; //密匙库相关信息<br />
private String keyStoreFile = null;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; private String keyStoreType = "JKS";<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 。。。<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; public WSSecurityServerHandler()<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("服务端Handler：构造方法");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; *处理请求<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; *流程：解密--&gt;身份验证--&gt;删除WSS元素'把Document转换成SOAP消息。<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; */&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; public boolean handleRequest(MessageContext messageContext) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("开始处理请求。。。");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (messageContext instanceof SOAPMessageContext){<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp; SOAPMessageContext soapMessageContext = (SOAPMessageContext)messageContext;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; SOAPMessage soapMessage = soapMessageContext.getMessage();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; soapMessage.writeTo(System.out);<br />
&nbsp;&nbsp;&nbsp; Document doc = MessageConveter.convertSoapMessageToDocument(soapMessage);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //解密<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WSSHelper.decrypt(doc, keyStoreFile, keyStoreType,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; keyStorePassword, keyAlias, keyEntryPassword);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //身份验证<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WSSHelper.verify(doc, trustStoreFile, trustStoreType, trustStorePassword);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //删除WSS元素<br />
WSSHelper.removeWSSElements(doc);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; soapMessage = MessageConveter.convertDocumentToSOAPMessage(doc);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; soapMessageContext.setMessage(soapMessage);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } catch (Exception e){<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.err.println("在处理请求时发生了异常： " + e);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return false;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("MessageContext是以下类的实例： " + messageContext.getClass());<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;System.out.println("处理请求完毕！");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; *处理响应<br />
&nbsp;&nbsp;&nbsp;&nbsp; *流程：数字签名--&gt;加密--&gt;把Document转换成SOAP消息。<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp;&nbsp; public boolean handleResponse(MessageContext messageContext) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("开始处理Web服务响应。。。");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (messageContext instanceof SOAPMessageContext){<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; SOAPMessageContext soapMessageContext = (SOAPMessageContext)messageContext;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; SOAPMessage soapMessage = soapMessageContext.getMessage();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Document doc = MessageConveter.convertSoapMessageToDocument(soapMessage);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WSSHelper.sign(doc, keyStoreFile, keyStoreType,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; keyStorePassword, keyAlias, keyEntryPassword);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WSSHelper.encrypt(doc, trustStoreFile, trustStoreType,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; trustStorePassword, certAlias);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; soapMessage = MessageConveter.convertDocumentToSOAPMessage(doc);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; soapMessageContext.setMessage(soapMessage);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } catch (Exception e){<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.err.println("在处理响应时发生以下错误： " + e);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return false;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("处理响应完毕！");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; *初始化，主要是初始化一些相关参数。<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp;&nbsp; public void init(HandlerInfo config) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("WSSecurityServerHandler初始化");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Object param = "";<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Map configs = config.getHandlerConfig();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; keyStoreFile = (String)configs.get("keyStoreFile");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; trustStoreFile = (String)configs.get("trustStoreFile");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &#8230;//其它参数初始化&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &#8230;<br />
}<br />
&nbsp;<br />
<br />
<br />
客户端Handler开发<br />
<br />
客户端Handler可以是任何JAX-RPC兼容的Handler处理器。比如AXIS Handler实现或者SUN 提供的JAX-RPC Handler参考实现。这里使用后者来作为客户端Handler处理器。<br />
<br />
客户端Handler和服务器端Handler原理一样，但处理过程完全相反。<br />
<br />
<br />
例程9 客户端Handler（WSSecurityClientHandler.java）<br />
<br />
package com.hellking.study.webservice;<br />
&#8230;<br />
<br />
//客户端Handler<br />
public class WSSecurityClientHandler implements Handler <br />
{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //密匙库相关信息&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ...<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; *处理请求<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; *流程：数字签名--&gt;加密--&gt;把Document转换成SOAP消息。<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; */&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; public boolean handleRequest(MessageContext messageContext) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("开始处理请求。。。");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WSSHelper.sign(doc, keyStoreFile, keyStoreType,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; keyStorePassword, keyAlias, keyEntryPassword);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WSSHelper.encrypt(doc, trustStoreFile, trustStoreType,<br />
trustStorePassword, certAlias);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; soapMessage = MessageConveter.convertDocumentToSOAPMessage(doc);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; soapMessageContext.setMessage(soapMessage);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &#8230;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;System.out.println("处理请求完毕！");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; *处理响应<br />
&nbsp;&nbsp;&nbsp;&nbsp; *流程：解密--&gt;身份验证--&gt;删除WSS元素'把Document转换成SOAP消息。<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp;&nbsp; public boolean handleResponse(MessageContext messageContext) {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("开始处理Web服务响应。。。");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WSSHelper.decrypt(doc, keyStoreFile, keyStoreType,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; keyStorePassword, keyAlias, keyEntryPassword);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WSSHelper.verify(doc, trustStoreFile, trustStoreType, trustStorePassword);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WSSHelper.removeWSSElements(doc);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; soapMessage = MessageConveter.convertDocumentToSOAPMessage(doc);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("the final message is:");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; soapMessage.writeTo(System.out);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; soapMessageContext.setMessage(soapMessage);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &#8230;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("处理响应完毕！");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; *初始化，主要是初始化一些相关参数。<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp;&nbsp; public void init(HandlerInfo config) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &#8230;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &#8230;<br />
}<br />
&nbsp;<br />
<br />
<br />
部署服务器端Handler<br />
<br />
为了使用Handler，需要在Web服务部署描述符中指定使用此Handler。Handler包含的初始化参数也在此描述，如例程10所示。<br />
<br />
<br />
例程10 服务器端Handler部署代码<br />
<br />
&nbsp; &lt;service name="PersonalTaxServicePort" provider="java:RPC"&gt;<br />
&nbsp; &lt;parameter name="allowedMethods" value="*"/&gt;<br />
&nbsp; &lt;parameter name="className" value="com.hellking.study.webservice.PersonalTaxService"/&gt;<br />
&nbsp; &lt;parameter name="wsdlTargetNamespace" value="http://hellking.webservices.com/"/&gt;<br />
&nbsp; &lt;parameter name="wsdlServiceElement" value="PersonalTaxService"/&gt;<br />
&nbsp; &lt;parameter name="wsdlServicePort" value="PersonalTaxServicePort"/&gt;<br />
&nbsp; &lt;parameter name="wsdlPortType" value="PersonalTaxService"/&gt;<br />
&nbsp; &lt;requestFlow&gt;<br />
&nbsp;&nbsp; &lt;handler type="java:org.apache.axis.handlers.JAXRPCHandler"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;parameter name="scope" value="session"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;parameter name="className"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="com.hellking.study.webservice.WSSecurityServerHandler"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;parameter name="keyStoreFile"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="K:\\jakarta-tomcat-5.0.16\\server.keystore"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;parameter name="trustStoreFile"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="K:\\jakarta-tomcat-5.0.16\\server.truststore"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;parameter name="certAlias" value="clientkey"/&gt;<br />
&nbsp;&nbsp; &lt;/handler&gt;<br />
&nbsp; &lt;/requestFlow&gt;<br />
&nbsp; &lt;responseFlow&gt;<br />
&nbsp;&nbsp; &lt;handler type="java:org.apache.axis.handlers.JAXRPCHandler"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;parameter name="scope" value="session"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;parameter name="className"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="com.hellking.study.webservice.WSSecurityServerHandler"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;parameter name="keyStoreFile"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="K:\\jakarta-tomcat-5.0.16\\server.keystore"/&gt;<br />
<br />
&nbsp;&nbsp;&nbsp; &lt;parameter name="trustStoreFile"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="K:\\jakarta-tomcat-5.0.16\\server.truststore"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;parameter name="certAlias" value="clientkey"/&gt;<br />
&nbsp;&nbsp; &lt;/handler&gt;<br />
&nbsp; &lt;/responseFlow&gt;<br />
&nbsp; &lt;/service&gt;<br />
&nbsp;&nbsp; <br />
<br />
<br />
requestFlow表示Web服务PersonalTaxServicePort的请求处理Handler链。这里只有一个Handler，就是WSSecurityServerHandler。当Web服务请求到达PersonalTaxServicePort时，WSSecurityServerHandler的handleRequest方法将被自动调用。<br />
<br />
注意：部署时，请改变Handler相关参数以和目标的Web服务一致，比如trustStoreFile的路径等。<br />
<br />
调用测试<br />
<br />
这里采用代理的方式来调用Web服务，先编写一个Web服务接口。<br />
<br />
<br />
例程11 TaxServiceInterface<br />
<br />
package com.hellking.study.webservice;<br />
&#8230;<br />
/**<br />
&nbsp;*个人所得税Web服务。<br />
&nbsp;*/<br />
public interface TaxServiceInterface extends Remote<br />
{<br />
&nbsp;&nbsp;&nbsp; public double getTax(double salary)throws java.rmi.RemoteException;<br />
}<br />
&nbsp;<br />
<br />
<br />
WSSClient客户端程序是通过代理的方式来访问Web服务的。由于要使用Handler，所以在访问前通过registerHandlers（）方法注册了WSSecurityClientHandler，并且初始化了WSSecurityClientHandler的相关参数。当然，JAX-RPC"参考实现"还支持在Web服务客户端配置文件中描述Handler信息，这样就不需要在客户端代码中对Handler进行注册了，你可以参考相关文档。<br />
<br />
<br />
例程12 测试客户端程序（WSSClient）<br />
<br />
package com.hellking.study.webservice;<br />
<br />
...<br />
/**<br />
&nbsp;*调用需要验证的Web服务<br />
&nbsp;*/<br />
public class WSSClient<br />
{<br />
&nbsp;&nbsp;&nbsp; static&nbsp;&nbsp;&nbsp; final double salary=5000;<br />
&nbsp;&nbsp;&nbsp; public static void main(String [] args)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //服务端的url，需要根据情况更改。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String endpointURL = "http://localhost:8080/axis/services/PersonalTaxServicePort";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String wsdlURL=endpointURL+"?wsdl";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.net.URL targetURL= new java.net.URL(wsdlURL);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String nameSpaceUri = "http://hellking.webservices.com/";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String svcName = "PersonalTaxService";&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; String portName = "PersonalTaxServicePort";<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ServiceFactory svcFactory = ServiceFactory.newInstance();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Service svc = svcFactory.createService(targetURL, new QName(nameSpaceUri, svcName));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //cfg表示客户端的配置信息。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.util.HashMap cfg = new java.util.HashMap();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cfg.put("keyStoreFile", "client.keystore");&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cfg.put("trustStoreFile", "client.truststore");&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cfg.put("certAlias", "changeit");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Class hdlrClass = com.hellking.study.webservice.WSSecurityClientHandler.class;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; java.util.List list = svc.getHandlerRegistry().<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getHandlerChain(new QName(nameSpaceUri, portName));<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; list.add(new javax.xml.rpc.handler.HandlerInfo(hdlrClass, cfg, null));<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; registerHandlers (svc);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;TaxServiceInterface myProxy = <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( TaxServiceInterface) svc.getPort(new QName(nameSpaceUri, portName), <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TaxServiceInterface.class);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double ret=myProxy.getTax(5000);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("使用HTTP协议来作为Web服务的传输协议！");&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("已经成功调用。请参看服务端的输出!");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("输入工资"+salary+"元，应交个人所得税："+ret);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Exception e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; //注册Handler<br />
&nbsp;&nbsp;&nbsp; private static void registerHandlers ( Service service ) <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; throws javax.xml.rpc.ServiceException {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; java.util.HashMap cfg = new java.util.HashMap();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cfg.put("keyStoreFile", "client.keystore");&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cfg.put("trustStoreFile", "client.truststore");&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cfg.put("certAlias", "changeit");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /*<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; * 封装客户端Handler到HandlerInfo 中，然后添加到Handler链中。<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; */ <br />
&nbsp;&nbsp;&nbsp; javax.xml.rpc.handler.HandlerInfo info = new javax.xml.rpc.handler.HandlerInfo<br />
&nbsp;&nbsp;&nbsp; (com.hellking.study.webservice.WSSecurityClientHandler.class, cfg, null );<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; java.util.ArrayList handlerList = new java.util.ArrayList();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; handlerList.add(info);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /*<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; * 获得Handler注册<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; javax.xml.rpc.handler.HandlerRegistry handlerRegistry = service.getHandlerRegistry();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /*<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; * 把Handler添加到所有的port中。<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; java.util.Iterator portIterator = service.getPorts();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while ( portIterator.hasNext()) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Object obj=portIterator.next();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; QName portName = (QName) obj;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; handlerRegistry.setHandlerChain(portName, handlerList);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
}<br />
&nbsp;<br />
<br />
<br />
注意：由于客户端使用了SUN公司提供的"JAX-RPC参考实现"，所以必须把jaxrpc-impl.jar包设置在CLASSPATH环境变量中，并且不要把axis.jar设置在客户端CLASSPATH环境变量，否则会出现ClassCastException异常。这是因为axis也是JAX-RPC的实现，如果它在CLASSPATH环境变量中，当调用：<br />
<br />
ServiceFactory svcFactory = ServiceFactory.newInstance()方法时，就可能初始化一个axis的ServiceFactory 实现。<br />
<br />
本文源代码中client目录下wss-client.bat文件包含了执行WSSClient脚本，修改了部分环境变量参数后，才能执行。<br />
<img src ="http://www.blogjava.net/libin2722/aggbug/162845.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-11-24 15:01 <a href="http://www.blogjava.net/libin2722/archive/2007/11/24/162845.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用axis发布webservices（四） </title><link>http://www.blogjava.net/libin2722/archive/2007/11/24/162844.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 24 Nov 2007 07:00:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/archive/2007/11/24/162844.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/162844.html</wfw:comment><comments>http://www.blogjava.net/libin2722/archive/2007/11/24/162844.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/162844.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/162844.html</trackback:ping><description><![CDATA[使用axis的Handler进行访问控制<br />
<br />
axis为Web服务的访问控制提供了相关的配置描述符，并且提供了一个访问控制的简单Handler（关于Handler的详细介绍见" J2EE Web服务开发系列之六: 使用Handler来增强Web服务的功能"）。默认情况下，你只要在配置描述符中添加用户，然后在Web服务器的部署描述符中自动允许的角色即可。 <br />
<br />
首先在axis的配置文件users.lst（位于WEB-INF目录下）中添加一个用户，如"axisuser pass"，表示用户名为axisuser，密码为pass。然后把案例的Web服务重新部署，在server-config.wsdd中添加例程7所示的部署代码。<br />
<br />
<br />
例程7 重新部署PersonalTaxService<br />
<br />
&nbsp; &lt;service name="PersonalTaxService2" provider="java:RPC"&gt;<br />
&nbsp; &lt;parameter name="allowedMethods" value="*"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;parameter name="className" value="com.hellking.study.webservice.PersonalTaxService"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter name="allowedRoles" value="axisuser"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;requestFlow&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;handler name="authen"<br />
&nbsp;type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/requestFlow&gt;<br />
&nbsp; &lt;/service&gt;<br />
&nbsp;&nbsp; <br />
<br />
<br />
在这个部署描述符中，指定PersonalTaxService2服务只能被axisuser访问，要想使访问控制生效，还必须把SimpleAuthenticationHandler添加到请求Handler链中。<br />
<br />
你只要修改AuthClient代码的服务端点URL和访问用户名、密码，就可以测试新的Web服务了，如例程8所示。<br />
<br />
<br />
例程8 HandlerAuthClient<br />
<br />
public class HandlerAuthClient<br />
{<br />
。。。&nbsp; <br />
String endpointURL = "http://localhost:8080/axis/services/PersonalTaxService2?wsdl";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 。。。<br />
&nbsp;&nbsp; call.getMessageContext().setUsername("axisuser");//axis中的用户名。<br />
&nbsp;&nbsp; call.getMessageContext().setPassword("pass");//密码<br />
。。。<br />
&nbsp;<br />
<br />
<br />
执行HandlerAuthClient，能够顺利访问Web服务；如果修改用户名或者密码，那么就不能访问，这说明Axis的Handler对Web服务的访问权限进行了有效的控制。<br />
<br />
使用Servlet过滤器（Filter）进行访问控制 Axis的Web服务端本质上是以Servlet方式在运行，所有我们完全可以在Web应用上部署一个Servlet过滤器，通过此过滤器来达到访问控制的效果。<br />
<br />
Web应用中的过滤器截取从客户端进来的请求，然后进行一系列处理，最后把请求发送到目标Servlet。过滤器的工作原理如下图所示。<br />
<br />
<br />
图1 过滤器工作原理<br />
&nbsp;<br />
<br />
过滤器可以说是外部进入Web服务器的第一道关，它能决定请求是否继续向前转发，也能对请求中的信息进行处理。如果过滤器用于对Web服务进行访问控制，那么它能根据客户端信息决定目标的服务是否能调用成功。<br />
<br />
将要开发的过滤器将根据客户端IP地址进行过滤，如果客户端的IP地址在限制范围中，那么就不能访问目标的Web服务。过滤器部分代码如下。<br />
<br />
<br />
例程9 用过滤器限制Web服务的访问权限<br />
<br />
package com.hellking.study.webservice;<br />
<br />
import javax.servlet.FilterChain;<br />
。。。<br />
public class WebServicesFilter implements Filter<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp; //没有权限访问的IP地址<br />
&nbsp;&nbsp;&nbsp; static final String[] deniedIPList=new String[]{<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "123.201",<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "192.168",<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "25.46",<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "124.0.0.1"<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;public boolean isIPDenied(String ipAddr)<br />
&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &#8230;<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; //过滤处理的方法<br />
&nbsp;&nbsp;&nbsp; public void doFilter(final ServletRequest req,final ServletResponse res,FilterChain chain)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; throws IOException,ServletException<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;HttpServletRequest hreq = (HttpServletRequest)req;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpServletResponse hres = (HttpServletResponse)res;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //HttpSession session = hreq.getSession();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String clientIp=req.getRemoteAddr();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("开始过滤。。。");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(isIPDenied(clientIp))<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;//验证不成功，让用户登录。<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; throw new ServletException("无权限访问此Web服务！");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; }&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;else<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; //验证成功，继续处理<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; chain.doFilter(req,res);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}&nbsp;&nbsp;&nbsp; &nbsp;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &#8230;<br />
}<br />
&nbsp;<br />
<br />
<br />
WebServicesFilter 过滤器限制了deniedIPList中指定的所有客户端。编写了过滤器后，需要在Web应用的部署描述符中指定使用此过滤器，并且把过滤器映射到目标URL上。当然，你也可以开发其它过滤器进行访问控制，比如Web服务客户端登录时，把登录信息保存在HTTP会话中，当客户端访问受限的资源时，读取HTTP会话中客户端信息以决定客户端是否有权限访问目标资源。<br />
<br />
除了编写Servlet过滤器实现类外，还需要在web.xml中对它进行配置，并且把过滤器映射到要过滤的目标URI上。以下是过滤器的部署描述符。<br />
<br />
<br />
例程10 部署过滤器<br />
<br />
&nbsp;&nbsp;&nbsp; &lt;filter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;WebServicesFilter&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-class&gt;com.hellking.study.webservice.WebServicesFilter&lt;/filter-class&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/filter&gt;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;filter-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;WebServicesFilter&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/services/*&lt;/url-pattern&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/filter-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
<br />
<br />
url-pattern指定了过滤器要过滤的范围。"/services/*"表示以"/services"开始的URL将全部被过滤，这正是AxisServlet默认的URL。通过上面的配置，只要客户端调用axis Web服务，就会被WebServicesFilter过滤器过滤。如果客户端IP地址在过滤器的deniedIPList中，那么就不能访问目标服务。<br />
<br />
<br />
<br />
使用SSL作为Web服务的传输协议<br />
<br />
Web服务也可以使用SSL作为传输协议。虽然JAX-RPC并没有强制规定是否使用SSL协议，但在tomcat下使用HTTPS协议。<br />
<br />
相关知识：<br />
<br />
SSL由两个共同工作的协议组成："SSL 记录协议"（SSL Record Protocol）和"SSL 握手协议"（SSL Handshake Protocol）。SSL 记录协议建立在可靠的传输协议（如TCP）之上，为高层协议提供数据封装、压缩、加密等基本功能的支持；SSL 握手协议建立在SSL记录协议之上，用于在实际的数据传输开始前，通信双方进行身份认证、协商加密算法、交换加密密钥等。<br />
<br />
SSL握手协议包含两个阶段，第一个阶段用于建立私密性通信信道，第二个阶段用于客户认证。第一阶段是通信的初始化阶段，在此阶段，首先SSL要求服务器向浏览器出示证书；然后浏览器中的SSL软件发给服务器一个随机产生的传输密钥，此密钥由已验证过的公钥加密，随机产生的传输密钥是核心机密，只有客户的浏览器和此公司的Web服务器知道这个数字序列。第二阶段的主要任务是对客户进行认证，此时服务器已经被认证了。服务器方向客户发出认证请求消息。客户收到服务器方的认证请求消息后，发出自己的证书，并且监听对方回送的认证结果。而当服务器收到客户的证书后，给客户回送认证成功消息，否则返回错误消息。到此为止，握手协议全部结束。<br />
<br />
要使用SSL协议，服务器至少有一个私有密匙和一个用于验证身份的证书。私有密匙在密匙交换算法中用到，证书将发送到客户端，以通知服务器端的身份。如果SSL服务器要验证客户端的身份，那么客户端必须也有自己的密匙库（包含私有密匙和证书）。JSSE中引入了信任库（truststore）的概念，它是用来保存证书的数据库。客户端或者服务器通过信任库来验证对方的身份。<br />
<br />
在使用SSL前，必须确保系统安装了JSSE。JDK1.4版本默认以及安装了JSSE。如果没有安装，把下载安装好的jar文件拷贝到%JAVA_HOME%\ jre\lib\ext目录下。这样，就安装好了JSSE的运行环境。<br />
<br />
下面我们使用JDK自带的工具创建密匙库和信任库。<br />
<br />
1）通过使用一下的命令来创建服务器端的密匙库。<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; keytool -genkey -alias hellking -keystore server.keystore -keyalg RSA<br />
输入keystore密码：&nbsp; changeit<br />
您的名字与姓氏是什么？<br />
&nbsp; [Unknown]：&nbsp; hellking-Server<br />
您的组织单位名称是什么？<br />
&nbsp; [Unknown]：&nbsp; huayuan<br />
您的组织名称是什么？<br />
&nbsp; [Unknown]：&nbsp; huayuan<br />
您所在的城市或区域名称是什么？<br />
&nbsp; [Unknown]：&nbsp; beijing<br />
您所在的州或省份名称是什么？<br />
&nbsp; [Unknown]：&nbsp; beijing<br />
该单位的两字母国家代码是什么<br />
&nbsp; [Unknown]：&nbsp; cn<br />
CN=chen ya qiang, OU=huayuan, O=huayuan, L=beijing, ST=beijing, C=cn 正确吗？<br />
&nbsp; [否]：&nbsp; y<br />
<br />
输入&lt;hellking&gt;的主密码<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （如果和 keystore 密码相同，按回车）：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
<br />
<br />
以上命令执行完成后，将获得一个名为server.keystore的密匙库。<br />
<br />
2)生成客户端的信任库。首先输出RSA证书：<br />
<br />
<br />
keytool -export -file test_axis.cer -storepass changeit -keystore server.keystore<br />
&nbsp;<br />
<br />
<br />
然后把RSA证书输入到一个新的信任库文件中。这个信任库被客户端使用，被用来验证服务器端的身份。<br />
<br />
<br />
keytool -import -file test_axis.cer -storepass changeit -keystore client.truststore -alias serverkey -noprompt<br />
&nbsp;<br />
<br />
<br />
3）创建客户端密匙库。重复步骤1，创建客户端的密匙库。也可以使用以下命令来完成：<br />
<br />
<br />
keytool -genkey -dname " CN=hellking-Client, OU=tsinghua, O=tsinghua, L=BEIJING, S=BEIJING, C=CN"<br />
-storepass changeit -keystore client.keystore -keyalg RSA -keypass changeit<br />
&nbsp;<br />
<br />
<br />
4）生成服务器端的信任库。<br />
<br />
<br />
keytool -export -file test_axis.cer -storepass changeit -keystore client.keystore<br />
keytool -import -file test_axis.cer -storepass changeit -keystore server.truststore -alias clientkey -noprompt<br />
&nbsp;<br />
<br />
<br />
生成了密匙库和信任库，我们把服务器端的密匙库（server.keystore）和信任库（server.truststore）拷贝到Tomcat的某个目录。<br />
<br />
下面需要更改Tomcat的配置文件（server.xml），增加一下部署描述符：<br />
<br />
<br />
例程11 为Tomcat配置SSL协议。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Connector port="8443" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxThreads="150" minSpareThreads="25" maxSpareThreads="75"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enableLookups="false" disableUploadTimeout="true"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; acceptCount="100" debug="0" scheme="https" secure="true"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clientAuth="true" keystoreFile="K:\jakarta-tomcat-5.0.16\server.keystore" keystorePass="changeit"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; truststoreFile="K:\jakarta-tomcat-5.0.16\server.truststore" truststorePass="changeit"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sslProtocol="TLS" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
<br />
<br />
clientAuth参数制定服务器是否要验证客户端证书，如果指定为true，那么客户端必须拥护服务器端可信任的证书后服务器才能响应客户端；如果指定为false，那么服务器不需要验证客户端的证书。<br />
<br />
在此，我们又把PersonalTaxService部署一次，在server-config.wsdd中添加如下部署代码。<br />
<br />
<br />
&lt;service name="PersonalTaxService3" provider="java:RPC"&gt;<br />
&nbsp; &lt;parameter name="allowedMethods" value="*"/&gt;<br />
&nbsp; &lt;parameter name="className" value="com.hellking.study.webservice.PersonalTaxService"/&gt;<br />
&nbsp; &lt;/service&gt;<br />
&nbsp;<br />
<br />
<br />
最后我们需要修改客户端调用程序，如例程12所示。<br />
<br />
<br />
例程12 SSL客户端调用程序<br />
<br />
package com.hellking.study.webservice;<br />
&#8230;.<br />
public class SSLAuthClient<br />
{<br />
&nbsp;&nbsp;&nbsp; static&nbsp;&nbsp;&nbsp; final double salary=5000;<br />
&nbsp;&nbsp;&nbsp; public static void main(String [] args)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //服务端的url，注意使用了SSL协议后，前缀是https。 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String endpointURL = "https://localhost:8443/axis/services/PersonalTaxService3?wsdl";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //由于使用了证书数字证书，所以不使用用户名和密码验证。<br />
//call.getMessageContext().setUsername("hellking");。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //call.getMessageContext().setPassword("simplewebservices");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Double ret = (Double) call.invoke( new Object [] { new Double(salary) });<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("使用SSL协议来作为Web服务的传输协议！");&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("已经成功调用。请参看服务端的输出!");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("输入工资"+salary+"元，应交个人所得税："+ret);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Exception e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
&nbsp;<br />
<br />
<br />
最后使用一下的命令来执行客户端程序：<br />
<br />
<br />
set AXIS_LIB=K:\jakarta-tomcat-5.0.16\webapps\axis\WEB-INF\lib<br />
SET CLASSPATH=.;%CLASSPATH%;%AXIS_LIB%\wsdl4j.jar.jar;%AXIS_LIB%\axis.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%<br />
\saaj.jar;%AXIS_LIB%\commons-discovery.jar;%AXIS_LIB%\commons-logging.jar<br />
java -Djavax.net.ssl.keyStore=client.keystore \<br />
-Djavax.net.ssl.keyStorePassword=changeit \<br />
-Djavax.net.ssl.trustStore=client.truststore \<br />
com.hellking.study.webservice.SSLAuthClient<br />
&nbsp;<br />
<br />
<br />
参数解释：通过-Djavax.net.ssl.keyStore来指定客户端密匙库，-Djavax.net.ssl.trustStore来指定客户端信任库。<br />
<br />
最后的输出结果如下：<br />
<br />
<br />
使用SSL协议来作为Web服务的传输协议！<br />
已经成功调用。请参看服务端的输出!<br />
输入工资5000.0元，应交个人所得税：445.0<br />
<img src ="http://www.blogjava.net/libin2722/aggbug/162844.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-11-24 15:00 <a href="http://www.blogjava.net/libin2722/archive/2007/11/24/162844.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用axis发布webservices（三）</title><link>http://www.blogjava.net/libin2722/archive/2007/11/24/162831.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 24 Nov 2007 06:46:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/archive/2007/11/24/162831.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/162831.html</wfw:comment><comments>http://www.blogjava.net/libin2722/archive/2007/11/24/162831.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/162831.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/162831.html</trackback:ping><description><![CDATA[<p>一、对象参数的传递</p>
<p>首先是我们要传输的变量对象Order，代码如下：</p>
<p>package samples.userguide.example5;<br />
public class Order<br />
{<br />
&nbsp;&nbsp;&nbsp; private String customerName;<br />
<br />
&nbsp;&nbsp;&nbsp; private String shippingAddress;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; public String getCustomerName()<br />
&nbsp;&nbsp;&nbsp; { return customerName; }<br />
&nbsp;&nbsp;&nbsp; public void setCustomerName(String name)<br />
&nbsp;&nbsp;&nbsp; { customerName = name; }<br />
}</p>
<p>要发布的services的代码如下：</p>
<p>package samples.userguide.example5;</p>
<p>public class BeanService<br />
{<br />
&nbsp;&nbsp;&nbsp; public Order getNewOrder(Order order)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; order.setCustomerName("liuyujun");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return order;<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>}</p>
<p>然后我们只要在配置文件server-config.wsdd里加入下面这段就可以发布了</p>
<p>&lt;service name="OrderProcessor" provider="java:RPC"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter name="className" value="samples.userguide.example5.BeanService"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter name="allowedMethods" value="*"/&gt;<br />
<font color="#ff00ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beanMapping qname="myNS:Order" xmlns:myNS="urn:BeanService" languageSpecificType="java:samples.userguide.example5.Order"/&gt;</font><br />
&nbsp;&nbsp;&nbsp; &lt;/service&gt;</p>
<p>特别要注意多了beanMapping这部分，qname指明我们用自己命名空间里的哪个对象，xmlns：myNS则指明了我们的命名空间，后面还一个指明了用到的对象类。</p>
<p>客户端调用程序：</p>
<p>package samples.userguide.example5;</p>
<p>public class Client<br />
{</p>
<p>&nbsp;&nbsp;&nbsp; private final static String targetEndpointAddress = "<a href="http://localhost:8080/axis/services/OrderProcessor">http://localhost:8080/axis/services/OrderProcessor</a>";<br />
&nbsp;&nbsp;&nbsp; private final static QName&nbsp;&nbsp;&nbsp; qn&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = new QName( "urn:BeanService", "Order" );</p>
<p><br />
&nbsp;&nbsp;&nbsp; public static void main(String [] args) throws Exception<br />
&nbsp;&nbsp;&nbsp; {</p>
<p>//创建一个参数对象<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Order order = new Order();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; order.setCustomerName("Glen Daniels");</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Service service = new Service();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Call call = (Call) service.createCall();</p>
<p>//注册对象类型<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call.registerTypeMapping(Order.class, qn,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new org.apache.axis.encoding.ser.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BeanSerializerFactory(Order.class, qn),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new org.apache.axis.encoding.ser.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BeanDeserializerFactory(Order.class, qn));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call.setTargetEndpointAddress(new java.net.URL(targetEndpointAddress));</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call.setOperationName(new QName("OrderProcessor", "getNewOrder"));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call.addParameter("order", qn, ParameterMode.IN);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call.setReturnType(qn, Order.class);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Order&nbsp;&nbsp; newOrder = (Order) call.invoke(new Object[] {order});<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("new custname:"+newOrder.getCustomerName());<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
这样就能看到返回的效果了；</p>
<p>&nbsp;二、获得访问者信息</p>
<p>MessageContext context = MessageContext.getCurrentContext(); <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpServletRequest req = (HttpServletRequest) context.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST); </p>
<p>这样就可以得到ruquest对象获得相关信息了，当然request的有些功能是用不了的，比如，getSession就是无效的</p>
<br />
<img src ="http://www.blogjava.net/libin2722/aggbug/162831.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-11-24 14:46 <a href="http://www.blogjava.net/libin2722/archive/2007/11/24/162831.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用axis发布webservices（二）</title><link>http://www.blogjava.net/libin2722/archive/2007/11/24/162830.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 24 Nov 2007 06:45:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/archive/2007/11/24/162830.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/162830.html</wfw:comment><comments>http://www.blogjava.net/libin2722/archive/2007/11/24/162830.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/162830.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/162830.html</trackback:ping><description><![CDATA[<p>1， 什么是 Web 服务？</p>
<p>Web 是使应用程序可以以与平台和编程语言无关的方式进行相互通信的一项技术。Web 服务是一个软件接口，它描述了一组可以在网络上通过标准化的 XML 消息传递访问的操作。它使用基于 XML 语言的协议来描述要执行的操作或者要与另一个 Web 服务交换的数据。一组以这种方式交互的 Web 服务在面向服务的体系结构（Service-Oriented Architecture，SOA）中定义了特殊的 Web 服务应用程序。</p>
<p>2， 什么是SOAP？</p>
<p>SOAP（Simple Object Access Protocol ）简单对象访问协议是在分散或分布式的环境中交换信息并执行远程过程调用的轻量级协议，是一个基于XML的协议。使用SOAP，不用考虑任何特定的传输协议（最常用的还是HTTP协议），可以允许任何类型的对象或代码，在任何平台上，以任何一种语言相互通信。</p>
<p>SOAP包括四个部分：SOAP封装(envelop)，封装定义了一个描述消息中的内容是什么，是谁发送的，谁应当接受并处理它以及如何处理它们的框架；SOAP编码规则（encoding rules），用于表示应用程序需要使用的数据类型的实例；SOAP RPC表示(RPC representation)，表示远程过程调用和应答的协定；SOAP绑定（binding），使用底层协议交换信息。</p>
<p>应用中比较关注的是envelop，由一个或多个Header和一个Body组成。</p>
<p>3， 什么是Axis?</p>
<p>Axis本质上就是一个SOAP引擎（Apache Axis is an implementation of the SOAP），提供创建服务器端、客户端和网关SOAP操作的基本框架。但Axis并不完全是一个SOAP引擎，它还包括：</p>
<p>是一个独立的SOAP服务器。<br />
是一个嵌入Servlet引擎（例如Tomcat）的服务器。<br />
支持WSDL。<br />
提供转化WSDL为Java类的工具。<br />
提供例子程序。<br />
提供TCP/IP数据包监视工具。</p>
<p>4， Axis相比Soap v2的优点：</p>
<p>Axis是第三代Apache SOAP的实现，从2000年起，SOAP v2开发小组开始讨论如何让Axis更加灵活、可配置，以及能够处理SOAP和来自W3C的各种XML标准。通过不断地讨论和代码编写，Axis目前相比SOAP V2取得了如下成果：</p>
<p>速度提高。 Axis通过基于事件的SAX对XML文档进行处理，从而在速度和效率上比Apache SOAP有所提高。</p>
<p>灵活性提高。</p>
<p>稳定性提高。</p>
<p>提供面向组件的部署。</p>
<p>提供一个简洁的传输抽象框架。其核心引擎完全于传输方式独立。从而使基于何种协议传输的选择更加灵活。</p>
<p>支持WSDL。包括WSDL和客户端代码生成等。</p>
<p>5， 什么是WSDL？</p>
<p>WSDL（Web Service Description Language）Web服务器描述语言是用XML文档来描述Web服务的标准，是Web服务的接口定义语言，由Ariba、Intel、IBM、MS等共同提出，通过WSDL，可描述Web服务的三个基本属性：</p>
<p>&#183;服务做些什么——服务所提供的操作（方法）</p>
<p>&#183;如何访问服务——和服务交互的数据格式以及必要协议</p>
<p>&#183;服务位于何处——协议相关的地址，如URL</p>
<p>WSDL文档以端口集合的形式来描述Web服务，WSDL 服务描述包含对一组操作和消息的一个抽象定义，绑定到这些操作和消息的一个具体协议，和这个绑定的一个网络端点规范。</p>
<p>6， 什么是WSDD？</p>
<p>WSDD就是WEB服务分布描述（Web Service Deployment Descriptor）, 它定义了WEB服务的接口，如服务名、提供的方法、方法的参数等信息。</p>
<p>7， 什么是UDDI？</p>
<p>UDDI就是统一描述、发现和集成（Universal Description, Discovery, and Integration）。UDDI用于集中存放和查找WSDL描述文件，起着目录服务器的作用。</p>
<p>Web 服务中的角色、操作和构件：</p>
<p>服务提供者。从企业的角度看，这是服务的所有者。从体系结构的角度看，这是托管访问服务的平台。 <br />
服务请求者。从企业的角度看，这是要求满足特定功能的企业。从体系结构的角度看，这是寻找并调用服务，或启动与服务的交互的应用程序。服务请求者角色可以由浏览器来担当，由人或无用户界面的程序（例如，另外一个 Web 服务）来控制它。 <br />
服务注册中心。这是可搜索的服务描述注册中心，服务提供者在此发布他们的服务描述。在静态绑定开发或动态绑定执行期间，服务请求者查找服务并获得服务的绑定信息（在服务描述中）。对于静态绑定的服务请求者，服务注册中心是体系结构中的可选角色，因为服务提供者可以把描述直接发送给服务请求者。同样，服务请求者可以从服务注册中心以外的其它来源得到服务描述，例如本地文件、FTP 站点、Web 站点、广告和服务发现（Advertisement and Discovery of Services，ADS）或发现 Web 服务（Discovery of Web Services，DISCO）。</p>
<p>8， AXIS的几种服务类型：</p>
<p>AXIS有四种service styles，分别是：RPC, Document, Wrapped, 和Message。最常用的就是RPC和Message。</p>
<p>RPC：在AXIS中是一个默认选项。当你部署的时候使用下列两种方式： 或则 ，它遵循SOAP RPC和编码规则。每个RPC都包括一个表示名称的外部接点和一些表示参数的内部接点。AXIS会根据规则将一个XML（WSDL文件）文件转化成一个JAVA对象，并对对想赋上在文件中描述的值。也可以根据规则将一个JAVA对象转化成XML文件。 </p>
<p>Document </p>
<p>适合于老的XML schema。</p>
<p>Wrapped </p>
<p>和DOCUMENT一样，适合于老的XML schema。 </p>
<p>在大多书情况下，你不许要担心是DOCUMENT服务还是WRAPPED服务。 </p>
<p>Message </p>
<p>以这种方式部署的话，会使AXIS失去意义，它使你的代码真正的用XML形式，而不需要转化成JAVA对象。以这种方式部署的有以下四种服务方法： </p>
<p>public Element [] method(Element [] bodies); </p>
<p>public SOAPBodyElement [] method (SOAPBodyElement [] bodies); </p>
<p>public Document method(Document body); </p>
<p>public void method(SOAPEnvelope req, SOAPEnvelope resp); </p>
<p>几种服务类型的主要区别：</p>
<p>基于RPC(远程过程调用)方式，这也是Web服务最常用的方式。面向消息/文档的的类型跟RPC不同的是它提供了一个更底层的抽象，要求更多的编程工作。客户端可以传入任何的XML文档，得到的响应不一定是SOAPEnvelope，可以返回任何它所需要的东西，甚至不返回。虽然这对开发者来说非常的灵活，但是这种通讯类型在实际的应用中并不常见。面向消息/文档的Web服务主要适合于下面几种情况，比如批量处理，基于表单的数据导入，有需要返回非XML数据时，Web服务器实现中要求直接访问传输层等等</p>
<p>9、java类与wsdl相互生成工具：</p>
<p>Axis提供了&#8221;WSDL2Java&#8221;工具，可以利用wsdl描述来产生服务的Java代理和框架(proxy and skeletons)。</p>
<p>Axis提供了&#8221;Java2WSDL&#8221;工具，可以由java类生成wsdl文件。</p>
<img src ="http://www.blogjava.net/libin2722/aggbug/162830.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-11-24 14:45 <a href="http://www.blogjava.net/libin2722/archive/2007/11/24/162830.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用axis发布webservices（一） </title><link>http://www.blogjava.net/libin2722/archive/2007/11/24/162829.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 24 Nov 2007 06:44:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/archive/2007/11/24/162829.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/162829.html</wfw:comment><comments>http://www.blogjava.net/libin2722/archive/2007/11/24/162829.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/162829.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/162829.html</trackback:ping><description><![CDATA[首先到apache的网站下载axis的开发包，好久没看了，现在已经开始出2.0的啦，不过好像还不是很成熟，这里，我们还是用1.x的包。最新的是1.3的包（如果是用jbuilder的话是不需要再下载的，可以用其自带的工具发布的，做起来很简单，不过下面是以比较通用的方式来介绍）。
<p>一、服务器端开发</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先编写服务端程序，这时我们完全不用考虑他是不是当作webservcies来发布的，因为在写法上没有什么不同。比如我们写了一个很简单的java程序，代码如下：</p>
<p>package samples.userguide.example2;<br />
public class Calculator {<br />
&nbsp; public int add(int i1, int i2)<br />
&nbsp; {<br />
&nbsp;&nbsp;&nbsp; return i1 + i2;<br />
&nbsp; }<br />
&nbsp; public int subtract(int i1, int i2)<br />
&nbsp; {<br />
&nbsp;&nbsp;&nbsp; return i1 - i2;<br />
&nbsp; }<br />
}</p>
<p>如果我们要把他发布成为services，首先需要把axis-1_3下的lib文件复制到我们的web服务的web-inf 的lib下。&nbsp;然后在web.xml里增加以下内容</p>
<p>&nbsp; &lt;servlet&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;display-name&gt;Apache-Axis Servlet&lt;/display-name&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;AxisServlet&lt;/servlet-name&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;servlet-class&gt;org.apache.axis.transport.http.AxisServlet&lt;/servlet-class&gt;<br />
&nbsp; &lt;/servlet&gt;<br />
&nbsp; &lt;servlet-mapping&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;AxisServlet&lt;/servlet-name&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/servlet/AxisServlet&lt;/url-pattern&gt;<br />
&nbsp; &lt;/servlet-mapping&gt;<br />
&nbsp; &lt;servlet-mapping&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;AxisServlet&lt;/servlet-name&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;*.jws&lt;/url-pattern&gt;<br />
&nbsp; &lt;/servlet-mapping&gt;<br />
&nbsp; &lt;servlet-mapping&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;AxisServlet&lt;/servlet-name&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/services/*&lt;/url-pattern&gt;<br />
&nbsp; &lt;/servlet-mapping&gt;</p>
<p>第一个是制定AxisServlet的类是必须的，余下的是配置servlet mapping的，可根据需要进行修改，比如不需要对 *.jws做mapping的时候就可以去掉相应的部分。完成了上边的必须配置我们就有两种方式来发布了：</p>
<p>1、动态发布，直接把Calculator 的java文件复制到webroot下，把Calculator.java更名为Calculator.jws，然后通过<a href="http://localhost:8080/Calculator.jws">http://localhost:8080/Calculator.jws</a>&nbsp;访问就可以 ，通过 <a href="http://localhost:8080/Calculator.jws?wsdl">http://localhost:8080/Calculator.jws?wsdl</a> 就可以看到相应的wsdl。这种方式调试起来比较麻烦，而且我再测试的时候也不能带package的信息，而且一些高级的配置无法实施，不建议采用。</p>
<p>2、静态发布，就是通过配置文件发布，这时候我们类的编译和普通的web方式没有不同，只是在web-inf下多了一个配置文件，默认的名称为server-config.wsdd</p>
<p>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
&lt;deployment name="defaultClientConfig"<br />
&nbsp;&nbsp;&nbsp; xmlns:java="<a href="http://xml.apache.org/axis/wsdd/providers/java">http://xml.apache.org/axis/wsdd/providers/java</a>"<br />
&nbsp;&nbsp;&nbsp; xmlns:handler="<a href="http://xml.apache.org/axis/wsdd/providers/handler">http://xml.apache.org/axis/wsdd/providers/handler</a>" xmlns="<a href="http://xml.apache.org/axis/wsdd/">http://xml.apache.org/axis/wsdd/</a>"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;globalConfiguration name="defaultClientConfig"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;requestFlow name="RequestFlow1" type=""&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;handler name="Handler1" type="java:org.apache.axis.handlers.JWSHandler"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter name="scope" value="session"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/handler&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;handler name="Handler2" type="java:org.apache.axis.handlers.JWSHandler"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter name="scope" value="request"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter name="extension" value=".jwr"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/handler&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/requestFlow&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/globalConfiguration&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;handler name="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;transport name="http" type=""&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;requestFlow name="RequestFlow1" type=""&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;handler name="Handler1" type="URLMapper"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;handler name="Handler2" type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/requestFlow&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/transport&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;transport name="local" type=""&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;responseFlow name="ResponseFlow1" type=""&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;handler name="Handler1" type="LocalResponder"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/responseFlow&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/transport&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;service name="AdminService" type="" provider="java:MSG"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter name="allowedMethods" value="AdminService"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter name="enableRemoteAdmin" value="false"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter name="className" value="org.apache.axis.utils.Admin"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;namespace&gt;http://xml.apache.org/axis/wsdd/&lt;/namespace&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/service&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;service name="Version" type="" provider="java:RPC"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter name="allowedMethods" value="getVersion"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter name="className" value="org.apache.axis.Version"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/service&gt;<br />
&nbsp;&nbsp;&nbsp;<font color="#ff9900"> &lt;service name="Calculator" type="" provider="java:RPC" style="rpc" use="encoded"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter name="scope" value="Request"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter name="className" value="samples.userguide.example2.Calculator"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter name="allowedMethods" value="*"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;namespace&gt;http://example2.userguide.samples&lt;/namespace&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/service&gt;<br />
</font>&nbsp;&nbsp;&nbsp; &lt;service name="OrderProcessor" provider="java:RPC"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter name="className" value="samples.userguide.example5.BeanService"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter name="allowedMethods" value="*"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beanMapping qname="myNS:Order" xmlns:myNS="urn:BeanService" languageSpecificType="java:samples.userguide.example5.Order"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/service&gt;<br />
&lt;/deployment&gt;</p>
<p>其中要发布的每个service都需要加上一个service的节点描述，其他多余的servie节点可以删除的，这样重启tomcat后，我们就可以以<a href="http://localhost:8080/services/Calculator">http://localhost:8080/services/Calculator</a>&nbsp;来访问这个service了，同样以<a href="http://localhost:8080/services/Calculator?wsdl">http://localhost:8080/services/Calculator?wsdl</a> 访问到它的wsdl描述文件。</p>
<p>二、客户端开发</p>
<p>在开发工具中引进lib下的jar包；然后编写客户端程序</p>
<p>package samples.userguide.example2;</p>
<p>import org.apache.axis.client.Call;<br />
import org.apache.axis.client.Service;<br />
import org.apache.axis.encoding.XMLType;<br />
import org.apache.axis.utils.Options;</p>
<p>import javax.xml.rpc.ParameterMode;</p>
<p>public class CalcClient<br />
{<br />
&nbsp;&nbsp; public static void main(String [] args) throws Exception {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String endpoint = "<a href="https://localhost:8440/services/Calculator">https://localhost:8440/services/Calculator</a>";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Integer i1 = new Integer(1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Integer i2 = new Integer(2);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Service service = new Service();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Call call = (Call) service.createCall();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call.setTargetEndpointAddress(new java.net.URL(endpoint));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call.setOperationName("add");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call.addParameter("i1", XMLType.XSD_INT, ParameterMode.IN);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call.addParameter("i2", XMLType.XSD_INT, ParameterMode.IN);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call.setReturnType(XMLType.XSD_INT);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Integer ret = (Integer) call.invoke(new Object[] {i1, i2});</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Got result : " + ret);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(Exception e){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; }<br />
}</p>
<p>其中 setOperationName就是指定执行的方法，addParameter就是指定参数<br />
运行一下吧</p>
<img src ="http://www.blogjava.net/libin2722/aggbug/162829.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-11-24 14:44 <a href="http://www.blogjava.net/libin2722/archive/2007/11/24/162829.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Axis序列化/反序列化器开发指南</title><link>http://www.blogjava.net/libin2722/archive/2007/11/24/162828.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 24 Nov 2007 06:42:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/archive/2007/11/24/162828.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/162828.html</wfw:comment><comments>http://www.blogjava.net/libin2722/archive/2007/11/24/162828.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/162828.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/162828.html</trackback:ping><description><![CDATA[<strong>前言</strong><br />
　　<br />
　　Axis是Apache组织推出的SOAP引擎，Axis项目是Apache组织著名的SOAP项目的后继项目。Axis为开发者提供了大量的序列化/反序列化器，能够基本满足大部分应用。但在某些情况下，对特定的对象，现有的序列化/反序列化器不能胜任，于是只有开发人员自己实现专用于此对象的序列化/反序列化器插入到Axis中来完成序列化工作。考虑到Web Service是一门新兴技术，中文资料大多是泛泛的讲解，关于序列化/反序列化器的开发鲜有较为深入的介绍，本文提供一份较为完整的开发指南，并提供了一个十分有用的实现，即序列化JDOM模型的Element,使其可以通过Web 服务在网络上传输，我想这一扩展是许多采用JDOM作为XML解析工具的开发人员都梦寐以求的功能。通过本文的介绍和实例，希望能起到抛砖引玉的作用，读者在阅读完本文之后可以轻松的实现针对于任何非符合BEAN规范的对象的序列化/反序列化器。<br />
　　<br />
　　本文所面对的读者需要有一定的使用Axis做Web服务开发的开发经验，因此关于如何Axis的基础知识并不在本文的介绍范围，如果读者对此感兴趣，可以参考本文最后的参考资料部分，去相应的网站进行学习。<br />
　　<br />
　　<strong>序列化/反序列化器简介</strong><br />
　　<br />
　　序列化/反序列化器在英文中的对应翻译是Serializer/Deserializer，一个序列化器的功能是遵循一定的映射规则和编码风格，将一种类型的JAVA对象通过某种特定的机制，转换成为XML描述的形式；反序列化器的功能是序列化器所做工作的逆操作，两者相辅相成，成对出现。Axis中的序列化/反序列化器采用设计范式中的工厂模式，每一个Serializer唯一对应一个SerializerFactory；每一个Deserializer唯一对应一个DeserializerFactory。一种类型的JAVA对象具体要采用哪个序列化/反序列化器需要在提供Web服务的服务器和调用Web服务的客户端分别配置，关于这一部分如何配置，我将在本文后面的内容中进行详细介绍。Axis已经为开发者提供了丰富的序列化/反序列化器,对于java的基本数据类型，绝大部分常用的容器类(比如数组类型，Vector类型等)都提供了实现，特别是提供了对W3C的DOM对象(比如Document, Element等)和符合Bean规范的JAVA对象提供了功能完善的序列化/反序列化器，因此我们在需要的时候只要在配置文件中配置一下就可以直接使用。如果对象中包含其它类型的对象，比如Vector中包含一组Bean对象，Axis会自动叠代的调用序列化器，最终拼装成唯一的XML表述。在还原成JAVA对象时，也遵循这样的叠代操作逆向进行。关于Axis到底内置了哪些序列化/反序列化器，您可以参照Axis的API文档中包org.apache.axis.encoding.ser下的类的名称"望文生义"的了解一下，在以后的开发中做到心中有数。但对于一些特殊类型的对象(其实我们自己开发的很大一部分类都是这种特殊类型的对象，很少有绝对符合Bean规范的)，需要通过Web服务进行传递，我们不得不开发自己的序列化/反序列化器。<br />
　　<br />
　　<strong>开发篇</strong><br />
　　<br />
　　开发自己的序列化/反序列化器是一个激动人心的工作，但是却并不复杂,需要做的事情包括实现名成为org.apache.axis.encoding的包中的SerializerFactory，Serializer，DeserializerFactory和Deserializer这四个接口。下面我将结合一个实例来讲解序列化/反序列化器的开发方法，希望读者能够一边参看本文提供的源代码一边学习。<br />
　　<br />
　　JDOM作为一款比较"另类"的XML解析工具(因为它不符合W3C的DOM模型，自己另立一套)默默地占领着java世界里的xml解析器的半壁江山，由于其简洁的设计和方便灵活的API调用，已经渐渐成为了许多开发人员在进行XML开发的首选。但是Axis是建立在W3C的DOM模型的基础之上，师出名们正派，自然不屑与JDOM为伍。因此当开发人员想将自己已经写好的基于JDOM的应用模块采用Web服务的方式发布的时候，不可避免的会遇到如何将JDOM模型下的对象如Document, Element等序列化的问题。在软件工程师不会自己扩展Axis的序列化/反序列化器的时候，我们只能有两个办法达到这个目的，第一个就是更改以前应用模块内的API设计,使暴露的入口参数和返回值参数都是W3C的对象类型，但这种做法并不现实，因为这一应用模块往往不是独立存在，牵一发将动全身，导致旧有系统架构的崩塌；另一种做法就是为这个模块做一个代理类，它做的工作就对外接收或返回DOM模型的对象，对内转换成JDOM模型的对象，然后转发给应用模块，繁琐且效率低下。当我们向Axis注入了针对于JDOM模型的序列化/反序列化器后，这一工作便可以由Axis代劳了。下面我们将逐个开发这四个类：<br />
　　<br />
　　JDomElementSerializerFactory<br />
　　<br />
　　JDomElementSerializerFactory是一个工厂类，需要通过某种机制注册到Axis引擎(具体方法见下面"服务器端应用篇")；Axis通过调用它，来实例化JDomElementSerializer。Axis 提供了BaseSerializerFactory,这个类是一个抽象类，并实现其中包含了一些可重用的代码。我们自己开发的工厂类只需简单继承这个类就可以。构造函数中需要调用父类的构造函数将序列器类下面是它的源代码：<br />
　　<br />
　　package org.apache.axis.encoding.ser;<br />
　　<br />
　　public class JDomElementSerializerFactory<br />
　　extends BaseSerializerFactory {<br />
　　<br />
　　public JDomElementSerializerFactory() <br />
　　}<br />
　　<br />
　　JDomElementSerializer<br />
　　<br />
　　JDomElementSerializer实现org.apache.axis.encoding.Serializer接口，其核心API是serialize()，我们需要在这个方法的内部完成对JDOM模型的Element的序列化工作,序列化的结果要保存在入口参数传入的序列化上下文对象（SerializationContext）中：<br />
　　<br />
　　public void serialize(QName name, Attributes attributes, Object value,<br />
　　SerializationContext context) throws java.io.IOException {<br />
　　<br />
　　if (!(value instanceof Element))<br />
　　throw new IOException(<br />
　　Messages.getMessage("cant Serialize Object"));<br />
　　<br />
　　//获取符合JDOM的Element对象<br />
　　Element root=(Element)value;<br />
　　<br />
　　//输出到StringWriter<br />
　　XMLOutputter outputter=new XMLOutputter();//创建一个JDOM的XML输出器<br />
　　StringWriter sw=new StringWriter();<br />
　　outputter.output(root,sw);<br />
　　<br />
　　//用支持W3C的DOM模型的Xerces解析器解析文本流<br />
　　DOMParser parser=new DOMParser();//创建一个DOM的XML解析器<br />
　　try {<br />
　　parser.parse(new org.xml.sax.InputSource(<br />
　　new java.io.StringReader(sw.toString())));<br />
　　}catch (Exception ex) {<br />
　　throw new java.io.IOException("序列化时产生错误");<br />
　　}<br />
　　<br />
　　//获取符合DOM模型的Element对象<br />
　　org.w3c.dom.Element w3c_root =<br />
　　parser.getDocument().getDocumentElement();<br />
　　<br />
　　//放入序列化上下文对象中<br />
　　context.startElement(name, attributes);<br />
　　context.writeDOMElement(w3c_root);<br />
　　context.endElement();<br />
　　}<br />
　　<br />
　　JDomElementDeserializerFactory<br />
　　<br />
　　反序列化器的工厂类同序列化器的工厂类一样的设计，在此不在赘述。代码：<br />
　　<br />
　　package org.apache.axis.encoding.ser;<br />
　　<br />
　　public class JDomElementDeserializerFactory<br />
　　extends BaseDeserializerFactory {<br />
　　<br />
　　public JDomElementDeserializerFactory() <br />
　　<br />
　　}<br />
　　<br />
　　JDomElementDeserializer<br />
　　<br />
　　用过SAX解析XML的读者，对反序列化的实现比较容易理解，反序列化也采用了消息触发的机制，我们只需继承org.apache.axis.encoding.DeserializerImpl类，并覆盖其中的onEndElement方法：<br />
　　<br />
　　/**<br />
　　* 在元素结束触发反序列化的方法<br />
　　* @param namespace String 命名空间<br />
　　* @param localName String 本地名称<br />
　　* @param context DeserializationContext 反序列化上下文<br />
　　* @throws SAXException<br />
　　*/<br />
　　public void onEndElement(String namespace, String localName,<br />
　　DeserializationContext context) throws SAXException {<br />
　　<br />
　　try {<br />
　　//从反序列化上下文对象中获取原始的消息元素<br />
　　MessageElement msgElem = context.getCurElement();<br />
　　if (msgElem != null) {<br />
　　MessageContext messageContext = context.getMessageContext();<br />
　　Boolean currentElement = (Boolean) messageContext.getProperty(<br />
　　DESERIALIZE_CURRENT_ELEMENT);<br />
　　<br />
　　//如果当前的消息元素本身需要反序列化<br />
　　if (currentElement != null &amp;&amp; currentElement.booleanValue()) {<br />
　　org.w3c.dom.Element element = msgElem.getAsDOM();<br />
　　org.jdom.input.DOMBuilder db=new org.jdom.input.DOMBuilder();<br />
　　value=db.build(element);<br />
　　messageContext.setProperty(DESERIALIZE_CURRENT_ELEMENT,<br />
　　Boolean.FALSE);<br />
　　return;<br />
　　}<br />
　　<br />
　　//反序列化消息元素中的消息体<br />
　　java.util.ArrayList children = msgElem.getChildren();<br />
　　if (children != null) {<br />
　　<br />
　　//取得消息体<br />
　　msgElem = (MessageElement) children.get(0);<br />
　　if (msgElem != null) {<br />
　　org.w3c.dom.Element ret = msgElem.getAsDOM();<br />
　　org.jdom.input.DOMBuilder db=new org.jdom.input.DOMBuilder();<br />
<img src ="http://www.blogjava.net/libin2722/aggbug/162828.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-11-24 14:42 <a href="http://www.blogjava.net/libin2722/archive/2007/11/24/162828.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个服务返回一个ArrayList，如何使用Axis序列化/反序列化啊</title><link>http://www.blogjava.net/libin2722/archive/2007/11/24/162827.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 24 Nov 2007 06:41:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/archive/2007/11/24/162827.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/162827.html</wfw:comment><comments>http://www.blogjava.net/libin2722/archive/2007/11/24/162827.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/162827.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/162827.html</trackback:ping><description><![CDATA[<table style="height: 100%" cellspacing="0">
    <tbody>
        <tr>
            <td class="content" csdnid="Topic_Body">我的代码如下： <br />
            这是发布到服务器上面的代码： <br />
            package &nbsp; com; <br />
            import &nbsp; java.util.*; <br />
            public &nbsp; class &nbsp; ArrayListService &nbsp; { <br />
            public &nbsp; ArrayList &nbsp; myAL(){ <br />
            ArrayList &lt;String&gt; &nbsp; myAL &nbsp; = &nbsp; new &nbsp; ArrayList &lt;String&gt; (); <br />
            String &nbsp; str=new &nbsp; String( "这是一个WebService &nbsp; Of &nbsp; ArrayList &nbsp; ! "); <br />
            myAL.add(str); <br />
            return &nbsp; myAL; <br />
            }} <br />
            <br />
            客户端的代码： <br />
            package &nbsp; com; <br />
            import &nbsp; org.apache.axis.client.Call; <br />
            import &nbsp; org.apache.axis.client.Service; <br />
            import &nbsp; java.util.*; <br />
            <br />
            public &nbsp; class &nbsp; ArrayListClient &nbsp; { <br />
            public &nbsp; static &nbsp; void &nbsp; main(String[] &nbsp; args) &nbsp; { &nbsp; &nbsp; <br />
            try &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; <br />
            String &nbsp; wsdlUrl &nbsp; = &nbsp; "http://127.0.0.1:8080/axis/services/ArrayListService?wsdl "; &nbsp; &nbsp; &nbsp; &nbsp; <br />
            &nbsp; &nbsp; &nbsp; <br />
            Service &nbsp; service &nbsp; = &nbsp; new &nbsp; Service(); &nbsp; &nbsp; &nbsp; &nbsp; <br />
            Call &nbsp; call &nbsp; = &nbsp; null; &nbsp; &nbsp; &nbsp; &nbsp; <br />
            call &nbsp; = &nbsp; (Call) &nbsp; service.createCall(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
            <br />
            call.setOperationName( "myAL "); &nbsp; &nbsp; &nbsp; &nbsp; <br />
            call.setTargetEndpointAddress(new &nbsp; java.net.URL(wsdlUrl)); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
            //ArrayList &nbsp; al=(ArrayList)call.invoke(new &nbsp; Object[] &nbsp; {}); <br />
            call.invoke(new &nbsp; Object[] &nbsp; {}); <br />
            System.out.println( "请求信息： "); <br />
            call.getMessageContext().getRequestMessage().writeTo(System.out); <br />
            System.out.println( " "); <br />
            System.out.println( "响应信息： "); <br />
            call.getMessageContext().getResponseMessage().writeTo(System.out); <br />
            System.out.println( " "); <br />
            } &nbsp; <br />
            catch &nbsp; (Exception &nbsp; ex) &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; ex.printStackTrace(); &nbsp; &nbsp; &nbsp; &nbsp; }}} <br />
            打印出来的请求和响应消息也正常。 <br />
            可是服务器返回的是一个ArrayList，当用这一句时&#8220;ArrayList &nbsp; al=(ArrayList)call.invoke(new &nbsp; Object[] &nbsp; {});&#8221;就报错： <br />
            java.lang.ClassCastException: &nbsp; [Ljava.lang.Object; <br />
            at &nbsp; com.ArrayListClient.main(ArrayListClient.java:17) <br />
            这是什么原因啊，如何把响应消息里面的数据返回成ArrayList呢？ <br />
            <br />
            注：server-config.wsdd <br />
            &lt;service &nbsp; name= "ArrayListService " &nbsp; provider= "java:RPC "&gt; &nbsp; &nbsp; <br />
            &nbsp; &nbsp; &lt;parameter &nbsp; name= "className " &nbsp; value= "com.ArrayListService "/&gt; <br />
            &nbsp; &nbsp; &lt;parameter &nbsp; name= "allowedMethods " &nbsp; value= "* "/&gt; <br />
            &nbsp; &nbsp; &lt;requestFlow&gt; <br />
            &nbsp; &nbsp; &lt;handler &nbsp; type= "loging "/&gt; <br />
            &nbsp; &nbsp; &lt;/requestFlow&gt; <br />
            &nbsp; &nbsp; &lt;responseFlow&gt; <br />
            &nbsp; &nbsp; &lt;handler &nbsp; type= "loging "/&gt; <br />
            &nbsp; &nbsp; &lt;/responseFlow&gt; <br />
            &nbsp; &lt;/service&gt; <br />
            <br />
            这是服务响应消息： <br />
            &lt;?xml &nbsp; version= "1.0 " &nbsp; encoding= "utf-8 "?&gt; <br />
            &lt;soapenv:Envelope &nbsp; xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/ " &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; xmlns:xsd= "http://www.w3.org/2001/XMLSchema " &nbsp; <br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance "&gt; <br />
            &lt;soapenv:Body&gt; <br />
            &lt;myALResponse &nbsp; soapenv:encodingStyle= "http://schemas.xmlsoap.org/soap/encoding/ "&gt; <br />
            &lt;myALReturn &nbsp; href= "#id0 "/&gt; <br />
            &lt;/myALResponse&gt; <br />
            &lt;multiRef &nbsp; id= "id0 " &nbsp; soapenc:root= "0 " &nbsp; soapenv:encodingStyle= "http://schemas.xmlsoap.org/soap/encoding/ " &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; soapenc:arrayType= "xsd:anyType[1] " &nbsp; xsi:type= "soapenc:Array " &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; xmlns:soapenc= "http://schemas.xmlsoap.org/soap/encoding/ "&gt; <br />
            &lt;multiRef &nbsp; xsi:type= "soapenc:string "&gt; &#x8FD9;&#x662F;&#x4E00;&#x4E2A;WebService &nbsp; Of &nbsp; ArrayList &nbsp; ! &lt;/multiRef&gt; <br />
            &lt;/multiRef&gt; <br />
            &lt;/soapenv:Body&gt; <br />
            &lt;/soapenv:Envelope&gt; </td>
        </tr>
        <tr>
            <td class="modify" csdnid="topicModifyInfo"></td>
        </tr>
        <tr>
            <td class="file" csdnid="topicRelatedLinks"></td>
        </tr>
        <tr>
            <td class="function"><span><label>问题点数：</label><var id="point" csdnid="point">20</var>&nbsp;<label>回复次数：<var csdnid="replyCount">3</var></label></span> <select onchange="changeViewMode(this);">
            <option value="0" selected>显示所有回复</option>
            <option value="1">显示星级回复</option>
            <option value="2">显示楼主回复</option>
            </select> <input onclick="window.location.href='#replyachor'" type="button" value="我来回答" /> <input onclick="window.location.href='mai'+'lto:'+'myc'+'sdn@c'+'sdn.n'+'et?subject=CSDN Topic Report';return false" type="button" value="举报" /> <input onclick="window.location.href='#top'" type="button" value="TOP" /> </td>
        </tr>
    </tbody>
</table>
<div class="ad topicad01"><iframe id="Topic_Zone" style="height: 4px" marginwidth="0" marginheight="0" src="/u/AD/Topic_Zone.aspx" frameborder="0" width="100%" scrolling="no" height="0"></iframe></div>
<a name="rp_38833569"></a>
<table class="item reply" cellspacing="1" csdnid="reply_38833569">
    <tbody>
        <tr>
            <td class="info">
            <ul>
                <li class="username"><a onmouseover="javascript:showUserCard();" href="http://hi.csdn.net/zzmdegm" target="_blank"><img class="userstatus" style="background-image: url(http://webim.csdn.net/UserOnlineFace/Theme1/zzmdegm.ashx)" alt="" src="http://topic.csdn.net/u/ui/images/blank.gif" /><var csdnid="Reply_Username">zzmdegm</var></a>
                <li class="nickname"><textarea readOnly csdnid="Reply_NickName">剑心</textarea>
                <li class="grade">等 级：<img class="grade user1" alt="" src="http://topic.csdn.net/u/ui/images/blank.gif" csdnid="Reply_UserRank" /></li>
            </ul>
            </td>
            <td class="main">
            <table style="height: 100%" cellspacing="0">
                <tbody>
                    <tr>
                        <td class="floor"><span>发表于：<var csdnid="Reply_Date">2007-01-10 17:29:40</var></span><var csdnid="Reply_Layer">1</var>楼&nbsp;得分:<var csdnid="Reply_Point">0</var></td>
                    </tr>
                    <tr>
                        <td class="content" csdnid="Reply_Body">arrayList &nbsp; ,victor,set,map传输在j2ee &nbsp; web &nbsp; service标准里是有限制的 &nbsp; ，改用数组 <br />
                        <br />
                        初步搞定：（服务如何发布就不详细说了，网上很多） <br />
                        java程序用 &nbsp; Axis做服务时自定义类实体的传送 <br />
                        <br />
                        核心代码： <br />
                        QName &nbsp; qn &nbsp; = &nbsp; new &nbsp; QName( "urn:BeanService ", "MyArryBean "); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; call.registerTypeMapping(MyArryBean.class, &nbsp; qn, <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new &nbsp; BeanSerializerFactory(MyArryBean.class, &nbsp; qn), <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new &nbsp; BeanDeserializerFactory(MyArryBean.class, &nbsp; qn)); <br />
                        这是在客户机端的代码，用于注册服务器上面的自定义类。然后就可以在客户端实例化这个类来使用。（如果MyArryBean &nbsp; 与服 <br />
                        <br />
                        务类不在同一个包里面，即服务需要用 &nbsp; import &nbsp; 来引用的话，这时就要用到 &nbsp; ：包名.MyArryBean.class） <br />
                        <br />
                        在Axis服务端，注册自定义对象的序列化/反序列化器 <br />
                        服务器的server-config.wsdd: <br />
                        ... <br />
                        &lt;service &nbsp; name= "ArrayListService " &nbsp; provider= "java:RPC "&gt; &nbsp; &nbsp; <br />
                        &nbsp; &nbsp; &lt;parameter &nbsp; name= "className " &nbsp; value= "com.ArrayListService "/&gt; <br />
                        &nbsp; &nbsp; &lt;parameter &nbsp; name= "allowedMethods " &nbsp; value= "* "/&gt; <br />
                        &nbsp; &nbsp; &lt;beanMapping &nbsp; languageSpecificType= "java:com.MyArryBean " &nbsp; qname= "ns:MyArryBean " &nbsp; xmlns:ns= "urn:BeanService "/&gt; <br />
                        &nbsp; &nbsp; &lt;requestFlow&gt; <br />
                        &nbsp; &nbsp; &lt;handler &nbsp; type= "loging "/&gt; <br />
                        &nbsp; &nbsp; &lt;/requestFlow&gt; <br />
                        &nbsp; &nbsp; &lt;responseFlow&gt; <br />
                        &nbsp; &nbsp; &lt;handler &nbsp; type= "loging "/&gt; <br />
                        &nbsp; &nbsp; &lt;/responseFlow&gt; <br />
                        &nbsp; &lt;/service&gt; <br />
                        ... <br />
                        <br />
                        服务器上面的自定义类（这个类要被传递给客户端）：MyArryBean.java <br />
                        package &nbsp; com; <br />
                        import &nbsp; java.io.Serializable; <br />
                        <br />
                        public &nbsp; class &nbsp; MyArryBean &nbsp; implements &nbsp; Serializable{ <br />
                        private &nbsp; static &nbsp; final &nbsp; long &nbsp; serialVersionUID &nbsp; = &nbsp; -6414428095965735488L; <br />
                        private &nbsp; String &nbsp; str= " "; <br />
                        public &nbsp; MyArryBean(){} <br />
                        public &nbsp; void &nbsp; setBean(String &nbsp; str){this.str=str;} <br />
                        public &nbsp; String &nbsp; getBean(){return &nbsp; this.str;} <br />
                        } <br />
                        <br />
                        服务器上面的服务类：ArrayListService.java <br />
                        package &nbsp; com; <br />
                        <br />
                        public &nbsp; class &nbsp; ArrayListService &nbsp; { <br />
                        //这里返回的是一个int数组 <br />
                        public &nbsp; int[] &nbsp; myAL(){ <br />
                        int &nbsp; myAL[] &nbsp; = &nbsp; new &nbsp; int[5]; <br />
                        for( &nbsp; int &nbsp; i=0;i &lt;5;i++){ <br />
                        myAL[i]=i; <br />
                        } <br />
                        return &nbsp; myAL; <br />
                        } <br />
                        //这里返回的是一个自定义对象 <br />
                        public &nbsp; MyArryBean &nbsp; myAB(String &nbsp; myStr){ <br />
                        MyArryBean &nbsp; _myArryB=new &nbsp; MyArryBean(); <br />
                        _myArryB.setBean(myStr); <br />
                        return &nbsp; _myArryB; <br />
                        } <br />
                        } &nbsp; <br />
                        <br />
                        客户端代码：ArrayListClient.java <br />
                        package &nbsp; com; <br />
                        import &nbsp; org.apache.axis.client.Call; <br />
                        import &nbsp; org.apache.axis.client.Service; <br />
                        import &nbsp; org.apache.axis.encoding.ser.BeanDeserializerFactory; <br />
                        import &nbsp; org.apache.axis.encoding.ser.BeanSerializerFactory; <br />
                        import &nbsp; javax.xml.namespace.QName; <br />
                        <br />
                        public &nbsp; class &nbsp; ArrayListClient &nbsp; { <br />
                        public &nbsp; static &nbsp; void &nbsp; main(String[] &nbsp; args) &nbsp; { &nbsp; &nbsp; <br />
                        try &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; <br />
                        String &nbsp; wsdlUrl &nbsp; = &nbsp; "http://127.0.0.1:8080/axis/services/ArrayListService?wsdl "; &nbsp; &nbsp; &nbsp; &nbsp; <br />
                        String &nbsp; nameSpaceUri &nbsp; = &nbsp; "http://localhost:8080/axis/services/ArrayListService "; <br />
                        <br />
                        Service &nbsp; service &nbsp; = &nbsp; new &nbsp; Service(); &nbsp; &nbsp; &nbsp; &nbsp; <br />
                        Call &nbsp; call &nbsp; = &nbsp; null; &nbsp; &nbsp; &nbsp; &nbsp; <br />
                        call &nbsp; = &nbsp; (Call) &nbsp; service.createCall(); &nbsp; &nbsp; &nbsp; &nbsp; <br />
                        <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //注册MyArryBean的序列化类型 <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; QName &nbsp; qn &nbsp; = &nbsp; new &nbsp; QName( "urn:BeanService ", "MyArryBean "); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; call.registerTypeMapping(MyArryBean.class, &nbsp; qn, <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new &nbsp; BeanSerializerFactory(MyArryBean.class, &nbsp; qn), <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new &nbsp; BeanDeserializerFactory(MyArryBean.class, &nbsp; qn)); <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //这里取得的是一个服务器int数组 <br />
                        call.setOperationName( "myAL "); &nbsp; &nbsp; &nbsp; &nbsp; <br />
                        call.setTargetEndpointAddress(new &nbsp; java.net.URL(wsdlUrl)); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
                        int[] &nbsp; _resp &nbsp; = &nbsp; (int[])call.invoke(new &nbsp; java.lang.Object[] &nbsp; {}); <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; for &nbsp; (int &nbsp; i=0;i &lt;5;i++){ <br />
                        System.out.println( "int数组: "+_resp[i]); <br />
                        } <br />
                        &nbsp; <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //这里取得的是一个服务器自定义对象 <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; //这里实例化服务器上面的映射的自定义类 <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; MyArryBean &nbsp; CmyAB=new &nbsp; MyArryBean(); <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; CmyAB.setBean( "这是的客户端实例化服务器的类！yes "); <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; System.out.println( "return &nbsp; value &nbsp; is &nbsp; " &nbsp; + &nbsp; CmyAB.getBean()); <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; QName &nbsp; getmyABQn &nbsp; = &nbsp; new &nbsp; QName(nameSpaceUri, &nbsp; "myAB "); <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; call.setOperationName(getmyABQn); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; call.setTargetEndpointAddress(new &nbsp; java.net.URL(wsdlUrl)); <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CmyAB &nbsp; = &nbsp; (MyArryBean) &nbsp; call.invoke(new &nbsp; Object[] &nbsp; { &nbsp; "这是调用服务器的类！web " &nbsp; }); <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println( "return &nbsp; value &nbsp; is &nbsp; " &nbsp; + &nbsp; CmyAB.getBean()); &nbsp; <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; System.out.println( "请求信息： "); <br />
                        call.getMessageContext().getRequestMessage().writeTo(System.out); <br />
                        System.out.println( " "); <br />
                        System.out.println( "响应信息： "); <br />
                        call.getMessageContext().getResponseMessage().writeTo(System.out); <br />
                        System.out.println( " "); <br />
                        } &nbsp; <br />
                        catch &nbsp; (Exception &nbsp; ex) &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; ex.printStackTrace(); &nbsp; &nbsp; &nbsp; &nbsp; }}} <br />
                        <br />
                        <br />
                        运行结果： <br />
                        <br />
                        int数组:0 <br />
                        int数组:1 <br />
                        int数组:2 <br />
                        int数组:3 <br />
                        int数组:4 <br />
                        return &nbsp; value &nbsp; is &nbsp; 这是的客户端实例化服务器的类！yes <br />
                        return &nbsp; value &nbsp; is &nbsp; 这是调用服务器的类！web <br />
                        请求信息： <br />
                        &lt;?xml &nbsp; version= "1.0 " &nbsp; encoding= "UTF-8 "?&gt; <br />
                        &nbsp; &lt;soapenv:Envelope &nbsp; xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/ " &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
                        <br />
                        &nbsp; xmlns:xsd= "http://www.w3.org/2001/XMLSchema " &nbsp; <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance "&gt; <br />
                        &nbsp; &nbsp; &lt;soapenv:Body&gt; <br />
                        &nbsp; &nbsp; &nbsp; &lt;ns1:myAB &nbsp; soapenv:encodingStyle= "http://schemas.xmlsoap.org/soap/encoding/ " &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
                        <br />
                        xmlns:ns1= "http://localhost:8080/axis/services/ArrayListService "&gt; <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &lt;ns1:arg0 &nbsp; xsi:type= "soapenc:string " &nbsp; xmlns:soapenc= "http://schemas.xmlsoap.org/soap/encoding/ "&gt; <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#x8FD9;&#x662F;&#x8C03;&#x7528;&#x670D;&#x52A1;&#x5668;&#x7684;&#x7C7B;&#xFF01;web <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &lt;/ns1:arg0&gt; <br />
                        &nbsp; &nbsp; &nbsp; &lt;/ns1:myAB&gt; <br />
                        &nbsp; &nbsp; &lt;/soapenv:Body&gt; <br />
                        &nbsp; &lt;/soapenv:Envelope&gt; <br />
                        响应信息： <br />
                        &lt;?xml &nbsp; version= "1.0 " &nbsp; encoding= "utf-8 "?&gt; <br />
                        &lt;soapenv:Envelope &nbsp; xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/ " &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
                        <br />
                        xmlns:xsd= "http://www.w3.org/2001/XMLSchema " &nbsp; <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance "&gt; <br />
                        &nbsp; &lt;soapenv:Body&gt; <br />
                        &nbsp; &nbsp; &lt;ns1:myABResponse &nbsp; soapenv:encodingStyle= "http://schemas.xmlsoap.org/soap/encoding/ " &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
                        <br />
                        xmlns:ns1= "http://localhost:8080/axis/services/ArrayListService "&gt; <br />
                        &nbsp; &nbsp; &nbsp; &lt;myABReturn &nbsp; href= "#id0 "/&gt; <br />
                        &nbsp; &nbsp; &lt;/ns1:myABResponse&gt; <br />
                        &nbsp; &nbsp; &lt;multiRef &nbsp; id= "id0 " &nbsp; soapenc:root= "0 " &nbsp; soapenv:encodingStyle= "http://schemas.xmlsoap.org/soap/encoding/ " &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
                        <br />
                        &nbsp; &nbsp; &nbsp; xsi:type= "ns2:MyArryBean " &nbsp; xmlns:soapenc= "http://schemas.xmlsoap.org/soap/encoding/ " &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
                        <br />
                        xmlns:ns2= "urn:BeanService "&gt; <br />
                        &nbsp; &nbsp; &nbsp; &lt;bean &nbsp; xsi:type= "soapenc:string "&gt; <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &#x8FD9;&#x662F;&#x8C03;&#x7528;&#x670D;&#x52A1;&#x5668;&#x7684;&#x7C7B;&#xFF01;web <br />
                        &nbsp; &nbsp; &nbsp; &lt;/bean&gt; <br />
                        &nbsp; &nbsp; &lt;/multiRef&gt; <br />
                        &nbsp; &lt;/soapenv:Body&gt; <br />
                        &lt;/soapenv:Envelope&gt; <br />
                        <br />
                        </td>
                    </tr>
                    <tr>
                        <td csdnid="Reply_ModifyInfo"></td>
                    </tr>
                    <tr>
                        <td class="function"><!-- <span>预留的文字链广告位</span> //--><input onclick="window.location.href='mai'+'lto:'+'myc'+'sdn@c'+'sdn.n'+'et?subject=CSDN Topic Report';return false" type="button" value="举报" /> <input onclick="window.location.href='#top'" type="button" value="TOP" /> </td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<a name="rp_38977580"></a>
<table class="item reply" cellspacing="1" csdnid="reply_38977580">
    <tbody>
        <tr>
            <td class="info">
            <ul>
                <li class="username"><a onmouseover="javascript:showUserCard();" href="http://hi.csdn.net/zzmdegm" target="_blank"><img class="userstatus" style="background-image: url(http://webim.csdn.net/UserOnlineFace/Theme1/zzmdegm.ashx)" alt="" src="http://topic.csdn.net/u/ui/images/blank.gif" /><var csdnid="Reply_Username">zzmdegm</var></a>
                <li class="nickname"><textarea readOnly csdnid="Reply_NickName">剑心</textarea>
                <li class="grade">等 级：<img class="grade user1" alt="" src="http://topic.csdn.net/u/ui/images/blank.gif" csdnid="Reply_UserRank" /></li>
            </ul>
            </td>
            <td class="main">
            <table style="height: 100%" cellspacing="0">
                <tbody>
                    <tr>
                        <td class="floor"><span>发表于：<var csdnid="Reply_Date">2007-01-19 16:48:18</var></span><var csdnid="Reply_Layer">2</var>楼&nbsp;得分:<var csdnid="Reply_Point">0</var></td>
                    </tr>
                    <tr>
                        <td class="content" csdnid="Reply_Body">正解： <br />
                        这一版没有把它写成服务\客户端的形式 <br />
                        <br />
                        package &nbsp; com; <br />
                        import &nbsp; java.io.ByteArrayInputStream; <br />
                        import &nbsp; java.io.ByteArrayOutputStream; <br />
                        import &nbsp; java.io.IOException; <br />
                        import &nbsp; java.io.ObjectInputStream; <br />
                        import &nbsp; java.io.ObjectOutputStream; <br />
                        import &nbsp; java.io.Serializable; <br />
                        import &nbsp; java.util.*; <br />
                        <br />
                        public &nbsp; class &nbsp; ArrayListSerializ &nbsp; implements &nbsp; Serializable{ <br />
                        /** <br />
                        &nbsp; * &nbsp; 此例是一个序列化/反序列化的方法 &nbsp; ： <br />
                        &nbsp; * &nbsp; <br />
                        &nbsp; * &nbsp; 主要思想是把一个对象写入对象输出流，然后把这个流里面的数据导入字节数组输出流 <br />
                        &nbsp; * &nbsp; 再把字节数组输出流导入到字节数组。这时，由于byte[]数组是从ObjectOutputStream之后得来的， <br />
                        &nbsp; * &nbsp; 那么是不可以new &nbsp; String(buff)的，因为其中包含了不可见字符，根本不是一个字符串。 <br />
                        &nbsp; * &nbsp; 只能用sun.misc.BASE64Encoder把它翻译成字符串形式。 <br />
                        &nbsp; * &nbsp; 至此，这就完成了序列化成字符串行式的过程 <br />
                        &nbsp; * &nbsp; <br />
                        &nbsp; * &nbsp; 再通过sun.misc.BASE64Decoder().decodeBuffer把字符串转换成一个byte[]， <br />
                        &nbsp; * &nbsp; 然后通过其反思路完成反序列化过程 <br />
                        &nbsp; */ <br />
                        private &nbsp; static &nbsp; final &nbsp; long &nbsp; serialVersionUID &nbsp; = &nbsp; 1L; <br />
                        private &nbsp; static &nbsp; void &nbsp; myArrayListSerializer() <br />
                        { <br />
                        ArrayList &lt;String&gt; &nbsp; myAL=new &nbsp; ArrayList &lt;String&gt; (); <br />
                        myAL.add( "This &nbsp; is &nbsp; a &nbsp; serial &nbsp; programme.author: &nbsp; 张正明 "); <br />
                        System.out.println( "ArrayList 's &nbsp; content： &nbsp; "+myAL.get(0)); <br />
                        //序列化使用的输出流 <br />
                        ObjectOutputStream &nbsp; OOS=null; <br />
                        //序列化后数据流给ByteArrayOutputStream &nbsp; 来保存。 <br />
                        //ByteArrayOutputStream &nbsp; 可转成字符串或字节数组 <br />
                        ByteArrayOutputStream &nbsp; BAOS=new &nbsp; ByteArrayOutputStream(); <br />
                        //ByteArrayInputStream &nbsp; 可接收一个字节数组 "byte[] "。供反序列化做参数 <br />
                        ByteArrayInputStream &nbsp; BAIS=null; <br />
                        //反序列化使用的输入流 <br />
                        ObjectInputStream &nbsp; OIS=null; <br />
                        try &nbsp; { <br />
                        OOS=new &nbsp; ObjectOutputStream(BAOS); <br />
                        OOS.writeObject(myAL); <br />
                        byte[] &nbsp; buff=BAOS.toByteArray(); <br />
                        <br />
                        &nbsp; /*由于byte[]数组是从ObjectOutputStream之后得来的， <br />
                        &nbsp; &nbsp; *那么是不可以new &nbsp; String(buff)的，因为其中包含了不可见字符，根本不是一个字符串 <br />
                        &nbsp; &nbsp; */ <br />
                        System.out.println( "序列化成一个byte[]的字符串形式 &nbsp; : "+buff); <br />
                        //转换成字符串 <br />
                        sun.misc.BASE64Encoder &nbsp; encoder &nbsp; = &nbsp; new &nbsp; sun.misc.BASE64Encoder(); <br />
                        String &nbsp; Sstr &nbsp; = &nbsp; encoder.encode(buff); <br />
                        System.out.println( "序列化成一个字符串： "+Sstr); <br />
                        System.out.println( "检查序列化成一个字符串和序列化成一个byte[]是否为同一个内容： "+ <br />
                        Arrays.equals(buff, &nbsp; new &nbsp; sun.misc.BASE64Decoder().decodeBuffer(Sstr))); <br />
                        OOS.close(); <br />
                        <br />
                        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp; 把字符串转成一个byte[] <br />
                        byte[] &nbsp; DSbuff=new &nbsp; sun.misc.BASE64Decoder().decodeBuffer(Sstr); <br />
                        System.out.println( "反序列化成一个byte[]字符串形式 &nbsp; : "+DSbuff); <br />
                        //实现反序列化 <br />
                        BAIS=new &nbsp; ByteArrayInputStream(DSbuff); <br />
                        OIS=new &nbsp; ObjectInputStream(BAIS); <br />
                        ArrayList &nbsp; c=(ArrayList)(OIS.readObject()); <br />
                        System.out.println( "反序列化后取提ArrayList的数据： &nbsp; "+c.get(0)); <br />
                        OIS.close(); <br />
                        } &nbsp; <br />
                        catch &nbsp; (IOException &nbsp; e) &nbsp; {e.printStackTrace();} <br />
                        catch &nbsp; (Exception &nbsp; ex) &nbsp; {System.out.println( "序列化时产生错误 ");} <br />
                        } <br />
                        public &nbsp; static &nbsp; void &nbsp; main(String[] &nbsp; args){ <br />
                        myArrayListSerializer(); <br />
                        } <br />
                        } <br />
                        </td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/libin2722/aggbug/162827.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-11-24 14:41 <a href="http://www.blogjava.net/libin2722/archive/2007/11/24/162827.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Axis1.4 开发笔记</title><link>http://www.blogjava.net/libin2722/archive/2007/11/22/162444.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Thu, 22 Nov 2007 10:59:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/archive/2007/11/22/162444.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/162444.html</wfw:comment><comments>http://www.blogjava.net/libin2722/archive/2007/11/22/162444.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/162444.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/162444.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 今天终于搞定，贴出来分享一下1、在www.apache.org上下载Axis1.4，将解压后的Axis目录文件复制到%TOMCATHOME%\webapps目录下2、重新启动Tomcat，访问http://localhost:8080/axis,如果能访问，表示Axis环境安装成功3、在eclipse下建立webproject，将axis的jar包导入写2个JavaBean，分别叫做Per...&nbsp;&nbsp;<a href='http://www.blogjava.net/libin2722/archive/2007/11/22/162444.html'>阅读全文</a><img src ="http://www.blogjava.net/libin2722/aggbug/162444.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-11-22 18:59 <a href="http://www.blogjava.net/libin2722/archive/2007/11/22/162444.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>server-config.wsdd配置一例</title><link>http://www.blogjava.net/libin2722/archive/2007/11/22/162436.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Thu, 22 Nov 2007 10:14:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/archive/2007/11/22/162436.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/162436.html</wfw:comment><comments>http://www.blogjava.net/libin2722/archive/2007/11/22/162436.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/162436.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/162436.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &lt;?xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"?&gt;&lt;deployment&nbsp;xmlns="http://xml.apache.org/axis/wsdd/"&nbsp;xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"&gt;&nbsp;&lt;glo...&nbsp;&nbsp;<a href='http://www.blogjava.net/libin2722/archive/2007/11/22/162436.html'>阅读全文</a><img src ="http://www.blogjava.net/libin2722/aggbug/162436.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-11-22 18:14 <a href="http://www.blogjava.net/libin2722/archive/2007/11/22/162436.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>J2EE Web服务开发系列之十二: 实现安全的AXIS Web服务，第1部分</title><link>http://www.blogjava.net/libin2722/archive/2007/11/18/161344.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sun, 18 Nov 2007 02:11:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/archive/2007/11/18/161344.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/161344.html</wfw:comment><comments>http://www.blogjava.net/libin2722/archive/2007/11/18/161344.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/161344.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/161344.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr valign="top">
            <td width="100%">
            <h1><span style="color: #999999">J2EE Web服务开发系列之十二: </span>实现安全的AXIS Web服务，第1部分</h1>
            <img class="display-img" height="6" alt="" src="http://www.ibm.com/i/c.gif" width="1" /></td>
            <td class="no-print" width="192"><img height="18" alt="developerWorks" src="http://www.ibm.com/developerworks/i/dw.gif" width="192" /></td>
        </tr>
    </tbody>
</table>
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr valign="top">
            <td width="10"><img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" /></td>
            <td width="100%">
            <table class="no-print" cellspacing="0" cellpadding="0" width="160" align="right" border="0">
                <tbody>
                    <tr>
                        <td width="10"><img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" /></td>
                        <td>
                        <table cellspacing="0" cellpadding="0" width="150" border="0">
                            <tbody>
                                <tr>
                                    <td class="v14-header-1-small">文档选项</td>
                                </tr>
                            </tbody>
                        </table>
                        <table class="v14-gray-table-border" cellspacing="0" cellpadding="0" border="0">
                            <tbody>
                                <tr>
                                    <td class="no-padding" width="150">
                                    <table cellspacing="0" cellpadding="0" width="143" border="0">
                                        <img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="8" />
                                        <form name="email" action="https://www.ibm.com/developerworks/secure/email-it.jsp">
                                            <input type="hidden" value="本文首先简单介绍Web服务安全性基本概念，然后介绍在axis Web服务开发工具下处理安全性问题的一些常用方法；接下来以安全性实现方法为线索，介绍了怎么在Web应用的基础上配置Web服务的访问控制、怎么使用axis的Handler和Servlet的过滤器进行访问控制，最后讨论怎么在tomcat下配置SSL 以实现Web服务的安全传输。" name="body" /><input type="hidden" value="J2EE Web服务开发系列之十二: 实现安全的AXIS Web服务，第1部分" name="subject" /><input type="hidden" value="cn" name="lang" /> <script language="JavaScript" type="text/javascript">
<!-- document.write('<tr valign="top"><td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt="" /></td><td width="16"><img src="//www.ibm.com/i/v14/icons/em.gif" height="16" width="16" vspace="3" alt="将此页作为电子邮件发送"  /></td><td width="122"><p><a class="smallplainlink" href="javascript:document.email.submit();"><strong>将此页作为电子邮件发送</strong></a></p></td></tr>');
//-->
</script>
                                            <tbody>
                                                <tr valign="top">
                                                    <td width="8"><img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="8" /></td>
                                                    <td width="16"><img height="16" alt="将此页作为电子邮件发送" src="http://www.ibm.com/i/v14/icons/em.gif" width="16" vspace="3" /></td>
                                                    <td width="122">
                                                    <p><a class="smallplainlink" href="javascript:document.email.submit();"><strong>将此页作为电子邮件发送</strong></a></p>
                                                    </td>
                                                </tr>
                                                <noscript>
                                                <tr valign="top">
                                                    <td width="8"><img alt="" height="1" width="8" src="//www.ibm.com/i/c.gif"  /></td>
                                                    <td width="16"><img alt="" width="16" height="16" src="//www.ibm.com/i/c.gif"  /></td>
                                                    <td class="small" width="122">
                                                    <p><span class="ast">未显示需要 JavaScript 的文档选项</span></p>
                                                    </td>
                                                </tr>
                                                </noscript>
                                            </form>
                                        </tbody>
                                    </table>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        <!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- this content will be automatically generated across all content areas --><br />
                        <!--end RESERVED FOR FUTURE USE INCLUDE FILES--><br />
                        </td>
                    </tr>
                </tbody>
            </table>
            <p>级别： 初级</p>
            <p><a href="http://www.ibm.com/developerworks/cn/webservices/ws-secaxis1/#author">陈亚强</a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#99;&#121;&#113;&#99;&#105;&#109;&#115;&#64;&#109;&#97;&#105;&#108;&#46;&#116;&#115;&#105;&#110;&#103;&#104;&#117;&#97;&#46;&#101;&#100;&#117;&#46;&#99;&#110;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#23454;&#29616;&#23433;&#20840;&#30340;&#65;&#88;&#73;&#83;&#32;&#87;&#101;&#98;&#26381;&#21153;&#65292;&#31532;&#49;&#37096;&#20998;&#38;&#97;&#109;&#112;&#59;&#99;&#99;&#61;&#99;&#121;&#113;&#99;&#105;&#109;&#115;&#64;&#109;&#97;&#105;&#108;&#46;&#116;&#115;&#105;&#110;&#103;&#104;&#117;&#97;&#46;&#101;&#100;&#117;&#46;&#99;&#110;">cyqcims@mail.tsinghua.edu.cn</a>), 高级软件工程师<br />
            </p>
            <p>2004 年 8 月 01 日</p>
            <blockquote>本文首先简单介绍Web服务安全性基本概念，然后介绍在axis Web服务开发工具下处理安全性问题的一些常用方法；接下来以安全性实现方法为线索，介绍了怎么在Web应用的基础上配置Web服务的访问控制、怎么使用axis的Handler和Servlet的过滤器进行访问控制，最后讨论怎么在tomcat下配置SSL 以实现Web服务的安全传输。</blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
            <p>axis是流行的Web服务开发工具，如何在axis下开发安全的Web服务，这是摆在每个开发者面前的问题。本文是J2EE Web服务开发系列文章的第十二篇，将首先简单介绍Web服务安全性基本概念，然后介绍在axis Web服务开发工具下处理安全性问题的一些常用方法；接下来以安全性实现方法为线索，介绍了怎么在Web应用的基础上配置Web服务的访问控制、怎么使用axis的Handler和Servlet的过滤器进行访问控制，最后讨论怎么在tomcat下配置SSL 以实现Web服务的安全传输。本文下一篇将介绍怎么在axis中实现WS-Security。</p>
            <p>阅读本文前您需要以下的知识和工具：</p>
            <ul>
                <li>Apache axis1.1，并且会初步使用；
                <li>Tomcat 4.0以上, 并且会初步使用；
                <li>Servlet的开发经验；
                <li>SOAP消息（SOAP Message）编程知识；
                <li>JAX-RPC编程基础知识；
                <li>Java安全编程基础知识。 </li>
            </ul>
            <p>本文的参考资料见 <a href="http://www.ibm.com/developerworks/cn/webservices/ws-secaxis1/#resources">参考资料</a>。 </p>
            <p>本文的全部代码在这里 <a href="http://www.ibm.com/developerworks/cn/webservices/ws-secaxis1/src.rar">下载</a>。 </p>
            <p><a name="N1006D"><span class="atitle">Web服务安全概述</span></a></p>
            <p>安全的Web服务是Web服务成功的必要保证。但众所周知的是，Web服务使用XML来进行数据交换，而XML在默认情况下是明文编码的；同时，大部分Web服务使用HTTP协议作为传输协议，同样，HTTP也是使用明文方式来传输数据的。这就造成了在不加密的传输协议上传输不加密的信息，从而使信息传输的保密性受到威胁。作为企业级的应用，以上的方式不能满足安全性基本要求：</p>
            <ol>
                <li>数据在因特网上传播时不应该被第三方看到；
                <li>双方必须能够确定消息的来源；
                <li>双方必须能够确定被传送的数据没有被篡改。 </li>
            </ol>
            <p>通过使用SSL协议可以解决第一个问题："不应该被第三方看到"；使用数字签名和数字证书可以解决后面两个问题。当使用数字证书方法时，Web 服务请求者必须有一个由可信认证中心签署的数字证书。请求者使用这个证书来表明它们的身份，并对 SOAP 消息进行数字签名。对方系统接收到消息后，就可对消息做时间戳记并进行日志记录。此时，数字签名会得到验证。验证过程将确保消息来自发送方，并且还要验证消息内容在传输过程中没有被篡改。</p>
            <p>IBM、Microsoft 和 Verisign 于2002年十二月份联合发布了一个关于 Web 服务安全性（Web Services Security，WS-Security）的规范，该规范描述如何向 SOAP 消息附加签名和加密报头；另外，它还描述如何向消息附加安全性令牌（包括二进制安全性令牌，如 X.509 证书），提供了一套帮助 Web 服务开发者保护 SOAP 消息交换的机制。</p>
            <p>根据应用的对安全要求的级别不同，可以采用不同的方式来实现安全性，以下是目前最常用的一些实现方式（从低到高排列）：</p>
            <ul>
                <li>J2EE Web应用默认的访问控制（数据是明文的）；
                <li>使用axis的Handler进行访问控制（数据是明文的）；
                <li>使用Servlet过滤器（Filter）进行访问控制（数据是明文的）；
                <li>使用SSL/HTTPS协议来传输（加密的数据传输协议）；
                <li>使用WS-Security规范对信息进行加密与身份认证（数据被加密传输）。 </li>
            </ul>
            <p>前三种方式对于安全级别要求不高的应用是可行的，它能够使用Web应用访问认证机制来进行权限验证，从而保护对资源的访问。但需要注意的是，虽然它们进行了身份验证，但信息的传递还是以明文的方式进行的，不能保证信息在传输过程中不被窃取。SSL是一个安全的传输协议，使用它传输Web服务能保证信息不被第三方窃取。但它有个缺点就是对系统资源消耗大。采用最后一种方式，信息被签名后再加密，然后把加密后的信息网络上传播，这样，即使第三方获得加密后的传输信息，也不能解密。对于安全级别要求高的系统，应该采用WS-Security规范来作为Web服务安全性解决方案。</p>
            <br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
                        <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
                        <table cellspacing="0" cellpadding="0" border="0">
                            <tbody>
                                <tr>
                                    <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                                    </td>
                                    <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/webservices/ws-secaxis1/#main"><strong>回页首</strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N100A0"><span class="atitle">开发、部署示例Web服务</span></a></p>
            <p>作为一个实例性的教程，我们有必要先开发一个简单的Web服务作为示例。关于如何在Axis下开发并部署一个简单的Web服务你可以参考下面这篇文章： <a href="http://www.ibm.com/developerworks/cn/webservices/ws-jax-rpc/part1/index.html">用JAX-RPC开发Web服务：Servlet作为Web服务端点</a>。 </p>
            <p>下面的例子提供的是一个提供个人所得税计算的Web服务。客户端传入工资的金额，Web服务将计算个人所得税金额。</p>
            <br />
            <a name="N100B0"><strong>例程 1 个人所得税Web服务</strong></a><br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">package com.hellking.study.webservice;
                        public class PersonalTaxService
                        {
                        final double base=1200;//所得税上缴基数。
                        public  double getTax(double salary)
                        {
                        double tax_salary=salary-1200;
                        double tax=0.0d;//计算后的所得税。
                        if(0&gt;tax_salary)                             tax=0;
                        else if(0&lt;tax_salary&amp;&amp;tax_salary &lt;=500)      tax=tax_salary*0.05-0;
                        else if(500&lt;tax_salary&amp;&amp;tax_salary&lt;=2000)    tax=tax_salary*0.10-25;
                        &#8230;
                        return tax;
                        }
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>编译后，你只要在Axis的部署配置文件（AXIS_HOME\Web-INF\server-config.wsdd）的适当位置增加以下部署代码，Web服务就可以部署成功。</p>
            <br />
            <a name="N100BD"><strong>例程2 部署示例Web服务</strong></a><br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">    &lt;service name="PersonalTaxService" provider="java:RPC"&gt;
                        &lt;parameter name="allowedMethods" value="*"/&gt;
                        &lt;parameter name="className" value="com.hellking.study.webservice.PersonalTaxService"/&gt;
                        &lt;/service&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>部署后的Web服务URL为： http://localhost:8080/axis/services/PersonalTaxService?wsdl （请先部署好这个Web服务再进行下面的学习。）</p>
            <br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
                        <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
                        <table cellspacing="0" cellpadding="0" border="0">
                            <tbody>
                                <tr>
                                    <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                                    </td>
                                    <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/webservices/ws-secaxis1/#main"><strong>回页首</strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N100CA"><span class="atitle">从Web应用的基本认证说起</span></a></p>
            <p>不管客户端通过什么API来调用Web服务，它总是先构造SOAP消息，然后通过HTTP POST方法把消息发送到Web服务的URL（注1：当然，Web服务也可以通过其它基于文本的协议传输，但是由于非常少见，在这里不讨论）。而我们知道，不管axis部署在哪种服务器上（Tomat还是Websphere），它总是以Servlet方式来运行的。所以最简单实现Web服务安全的方式就是通过在web应用的配置文件（web.xml）来实现访问控制。</p>
            <p>J2EE web应用中有多种认证方式：BASIC（基本认证方法）、FORM（基于表单）、DIGEST（消息摘要）和CLIENT-CERT（数字证书）。关于J2EE Web应用的其它认证方式的配置请参考其它资料，在此不再介绍。</p>
            <p>下面以Tomcat使用服务器为例，使用Web应用模型中基本认证方法来配置Web服务的安全访问。</p>
            <p>Web应用的基本认证是建立在J2EE角色和用户的基础之上，首先在Tomcat角色配置文件中增加一个角色和一个帐号。</p>
            <br />
            <a name="N100DC"><strong>例程3 在tomcat-users.xml中增加角色（Tomcat_Home\conf\tomcat-users.xml）</strong></a><br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">&lt;?xml version='1.0' encoding='utf-8'?&gt;
                        &lt;tomcat-users&gt;
                        &#8230;
                        &lt;role rolename="department-manager"/&gt;
                        &lt;user username="hellking" password="simplewebservices" roles="department-manager"/&gt;
                        &#8230;
                        &lt;/tomcat-users&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>上面配置代码在tomcat配置文件中添加了一个department-manager角色，并且在此角色中添加了一个名为hellking的用户。要使tomcat-users.xml中配置的角色和用户生效，需要配置tomcat使用UserDatabaseRealm。打开Tomcat_Home\conf\server.xml配置文件，在GlobalNamingResources中添加以下描述：</p>
            <br />
            <a name="N100E9"><strong>例程4 在tomcat中添加UserDatabaseRealm</strong></a><br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">  &lt;GlobalNamingResources&gt;
                        ...
                        &lt;Resource name="UserDatabase" auth="Container"
                        type="org.apache.catalina.UserDatabase"
                        description="User database that can be updated and saved"&gt;
                        &lt;/Resource&gt;
                        &lt;ResourceParams name="UserDatabase"&gt;
                        &lt;parameter&gt;
                        &lt;name&gt;factory&lt;/name&gt;
                        &lt;value&gt;org.apache.catalina.users.MemoryUserDatabaseFactory&lt;/value&gt;
                        &lt;/parameter&gt;
                        &lt;parameter&gt;
                        &lt;name&gt;pathname&lt;/name&gt;
                        &lt;value&gt;conf/tomcat-users.xml&lt;/value&gt;
                        &lt;/parameter&gt;
                        &lt;/ResourceParams&gt;
                        &lt;/GlobalNamingResources&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>然后再web应用的部署描述符中指定Web服务资源的访问控制，如下所示：</p>
            <br />
            <a name="N100F6"><strong>例程5 配置对Servlet的访问控制（AXIS_HOME\WEB-INF\web.xml）</strong></a><br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">&lt;security-constraint&gt;
                        &lt;web-resource-collection&gt;
                        &lt;web-resource-name&gt;Tax Web service &lt;/web-resource-name&gt;
                        &lt;url-pattern&gt;/services/PersonalTaxService&lt;/url-pattern&gt;
                        &lt;/web-resource-collection&gt;
                        &lt;auth-constraint&gt;
                        &lt;role-name&gt;department-manager&lt;/role-name&gt;
                        &lt;/auth-constraint&gt;
                        &lt;/security-constraint&gt;
                        &lt;login-config&gt;
                        &lt;auth-method&gt;BASIC&lt;/auth-method&gt;
                        &lt;realm-name&gt;Axis Basic Authentication Area&lt;/realm-name&gt;
                        &lt;/login-config&gt;
                        &lt;security-role&gt;
                        &lt;role-name&gt;department-manager&lt;/role-name&gt;
                        &lt;/security-role&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>url-pattern指定了需要通过角色验证的URL样式，在这里是"/services/PersonalTaxService"；role-name是能够访问制定URL的角色，这里是department-manager。以上配置的意思是只有角色类型是"department-manager"的用户才能访问URL样式为"/services/PersonalTaxService"Web服务。</p>
            <p>下面我们看怎么在axis客户端代码中axis客户端，如例程6所示。</p>
            <br />
            <a name="N10106"><strong>例程6 axis客户端代码</strong></a><br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">package com.hellking.study.webservice;
                        import org.apache.axis.client.Call;
                        import org.apache.axis.client.Service;
                        。。。
                        /**
                        *调用需要验证的Web服务
                        */
                        public class AuthClient
                        {
                        static	final double salary=5000;
                        public static void main(String [] args)
                        {
                        try {
                        //服务端的url，需要根据情况更改。
                        String endpointURL = "http://localhost:8080/axis/services/PersonalTaxService?wsdl";//
                        // Web服务端点地址
                        Service  service = new Service();
                        Call     call    = (Call) service.createCall();
                        call.setTargetEndpointAddress( new java.net.URL(endpointURL) );
                        call.setOperationName( new QName("PersonalTaxService", "getTax") );//设置操作的名称。
                        //由于需要认证，故需要设置调用的用户名和密码。
                        call.getMessageContext().setUsername("hellking");//设置用户名。
                        call.getMessageContext().setPassword("simplewebservices");//设置密码
                        call.addParameter( "op1", XMLType.XSD_DOUBLE, ParameterMode.IN );//参数的类型
                        call.setReturnType( XMLType.XSD_DOUBLE );//返回的数据类型
                        Double ret = (Double) call.invoke( new Object [] { new Double(salary) });//执行调用
                        System.out.println("使用HTTP协议来作为Web服务的传输协议！");
                        System.out.println("已经成功调用。请参看服务端的输出!");
                        System.out.println("输入工资"+salary+"元，应交个人所得税："+ret);
                        。。。
                        }
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>可以看出，通过使用call.getMessageContext().setUsername("hellking")来设置调用的用户名，通过setPassword来设置调用的密码。通过上面的代码可以看出，除了为Call对象设置的用户名和密码外，其它的代码和不使用访问控制时一样。</p>
            <p>下面我们看看它的运行结果：</p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">使用HTTP协议来作为Web服务的传输协议！
                        已经成功调用。请参看服务端的输出!
                        输入工资5000.0元，应交个人所得税：445.0
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>从输出可以看到，客户端成功通过了验证，并且返回了正确的结果。</p>
            <br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
                        <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
                        <table cellspacing="0" cellpadding="0" border="0">
                            <tbody>
                                <tr>
                                    <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                                    </td>
                                    <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/webservices/ws-secaxis1/#main"><strong>回页首</strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N1011D"><span class="atitle">使用axis的Handler进行访问控制</span></a></p>
            <p>axis为Web服务的访问控制提供了相关的配置描述符，并且提供了一个访问控制的简单Handler（关于Handler的详细介绍见" <a href="http://www.ibm.com/developerworks/cn/webservices/ws-handler/index.html">J2EE Web服务开发系列之六: 使用Handler来增强Web服务的功能</a>"）。默认情况下，你只要在配置描述符中添加用户，然后在Web服务器的部署描述符中自动允许的角色即可。 </p>
            <p>首先在axis的配置文件users.lst（位于WEB-INF目录下）中添加一个用户，如"axisuser pass"，表示用户名为axisuser，密码为pass。然后把案例的Web服务重新部署，在server-config.wsdd中添加例程7所示的部署代码。</p>
            <br />
            <a name="N1012D"><strong>例程7 重新部署PersonalTaxService</strong></a><br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">  &lt;service name="PersonalTaxService2" provider="java:RPC"&gt;
                        &lt;parameter name="allowedMethods" value="*"/&gt;
                        &lt;parameter name="className" value="com.hellking.study.webservice.PersonalTaxService"/&gt;
                        &lt;parameter name="allowedRoles" value="axisuser"/&gt;
                        &lt;requestFlow&gt;
                        &lt;handler name="authen"
                        type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/&gt;
                        &lt;/requestFlow&gt;
                        &lt;/service&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>在这个部署描述符中，指定PersonalTaxService2服务只能被axisuser访问，要想使访问控制生效，还必须把SimpleAuthenticationHandler添加到请求Handler链中。</p>
            <p>你只要修改AuthClient代码的服务端点URL和访问用户名、密码，就可以测试新的Web服务了，如例程8所示。</p>
            <br />
            <a name="N1013D"><strong>例程8 HandlerAuthClient</strong></a><br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">public class HandlerAuthClient
                        {
                        。。。
                        String endpointURL = "http://localhost:8080/axis/services/PersonalTaxService2?wsdl";
                        。。。
                        call.getMessageContext().setUsername("axisuser");//axis中的用户名。
                        call.getMessageContext().setPassword("pass");//密码
                        。。。
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>执行HandlerAuthClient，能够顺利访问Web服务；如果修改用户名或者密码，那么就不能访问，这说明Axis的Handler对Web服务的访问权限进行了有效的控制。</p>
            <p>使用Servlet过滤器（Filter）进行访问控制 Axis的Web服务端本质上是以Servlet方式在运行，所有我们完全可以在Web应用上部署一个Servlet过滤器，通过此过滤器来达到访问控制的效果。</p>
            <p>Web应用中的过滤器截取从客户端进来的请求，然后进行一系列处理，最后把请求发送到目标Servlet。过滤器的工作原理如下图所示。</p>
            <br />
            <a name="N10152"><strong>图1 过滤器工作原理</strong></a><br />
            <img height="452" alt="图1 过滤器工作原理" src="http://www.ibm.com/developerworks/cn/webservices/ws-secaxis1/1.gif" width="671" border="0" /> <br />
            <p>过滤器可以说是外部进入Web服务器的第一道关，它能决定请求是否继续向前转发，也能对请求中的信息进行处理。如果过滤器用于对Web服务进行访问控制，那么它能根据客户端信息决定目标的服务是否能调用成功。</p>
            <p>将要开发的过滤器将根据客户端IP地址进行过滤，如果客户端的IP地址在限制范围中，那么就不能访问目标的Web服务。过滤器部分代码如下。</p>
            <br />
            <a name="N10168"><strong>例程9 用过滤器限制Web服务的访问权限</strong></a><br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">package com.hellking.study.webservice;
                        import javax.servlet.FilterChain;
                        。。。
                        public class WebServicesFilter implements Filter
                        {
                        //没有权限访问的IP地址
                        static final String[] deniedIPList=new String[]{
                        "123.201",
                        "192.168",
                        "25.46",
                        "124.0.0.1"
                        };
                        public boolean isIPDenied(String ipAddr)
                        {
                        &#8230;
                        }
                        //过滤处理的方法
                        public void doFilter(final ServletRequest req,final ServletResponse res,FilterChain chain)
                        throws IOException,ServletException
                        {
                        HttpServletRequest hreq = (HttpServletRequest)req;
                        HttpServletResponse hres = (HttpServletResponse)res;
                        //HttpSession session = hreq.getSession();
                        String clientIp=req.getRemoteAddr();
                        System.out.println("开始过滤。。。");
                        if(isIPDenied(clientIp))
                        {
                        //验证不成功，让用户登录。
                        throw new ServletException("无权限访问此Web服务！");
                        }
                        else
                        {
                        //验证成功，继续处理
                        chain.doFilter(req,res);
                        }
                        }
                        &#8230;
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>WebServicesFilter 过滤器限制了deniedIPList中指定的所有客户端。编写了过滤器后，需要在Web应用的部署描述符中指定使用此过滤器，并且把过滤器映射到目标URL上。当然，你也可以开发其它过滤器进行访问控制，比如Web服务客户端登录时，把登录信息保存在HTTP会话中，当客户端访问受限的资源时，读取HTTP会话中客户端信息以决定客户端是否有权限访问目标资源。</p>
            <p>除了编写Servlet过滤器实现类外，还需要在web.xml中对它进行配置，并且把过滤器映射到要过滤的目标URI上。以下是过滤器的部署描述符。</p>
            <br />
            <a name="N10178"><strong>例程10 部署过滤器</strong></a><br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">    &lt;filter&gt;
                        &lt;filter-name&gt;WebServicesFilter&lt;/filter-name&gt;
                        &lt;filter-class&gt;com.hellking.study.webservice.WebServicesFilter&lt;/filter-class&gt;
                        &lt;/filter&gt;
                        &lt;filter-mapping&gt;
                        &lt;filter-name&gt;WebServicesFilter&lt;/filter-name&gt;
                        &lt;url-pattern&gt;/services/*&lt;/url-pattern&gt;
                        &lt;/filter-mapping&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>url-pattern指定了过滤器要过滤的范围。"/services/*"表示以"/services"开始的URL将全部被过滤，这正是AxisServlet默认的URL。通过上面的配置，只要客户端调用axis Web服务，就会被WebServicesFilter过滤器过滤。如果客户端IP地址在过滤器的deniedIPList中，那么就不能访问目标服务。</p>
            <br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
                        <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
                        <table cellspacing="0" cellpadding="0" border="0">
                            <tbody>
                                <tr>
                                    <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                                    </td>
                                    <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/webservices/ws-secaxis1/#main"><strong>回页首</strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N10185"><span class="atitle">使用SSL作为Web服务的传输协议</span></a></p>
            <p>Web服务也可以使用SSL作为传输协议。虽然JAX-RPC并没有强制规定是否使用SSL协议，但在tomcat下使用HTTPS协议。</p>
            <p><a name="N1018E"><span class="smalltitle">相关知识：</span></a></p>
            <p>SSL由两个共同工作的协议组成："SSL 记录协议"（SSL Record Protocol）和"SSL 握手协议"（SSL Handshake Protocol）。SSL 记录协议建立在可靠的传输协议（如TCP）之上，为高层协议提供数据封装、压缩、加密等基本功能的支持；SSL 握手协议建立在SSL记录协议之上，用于在实际的数据传输开始前，通信双方进行身份认证、协商加密算法、交换加密密钥等。</p>
            <p>SSL握手协议包含两个阶段，第一个阶段用于建立私密性通信信道，第二个阶段用于客户认证。第一阶段是通信的初始化阶段，在此阶段，首先SSL要求服务器向浏览器出示证书；然后浏览器中的SSL软件发给服务器一个随机产生的传输密钥，此密钥由已验证过的公钥加密，随机产生的传输密钥是核心机密，只有客户的浏览器和此公司的Web服务器知道这个数字序列。第二阶段的主要任务是对客户进行认证，此时服务器已经被认证了。服务器方向客户发出认证请求消息。客户收到服务器方的认证请求消息后，发出自己的证书，并且监听对方回送的认证结果。而当服务器收到客户的证书后，给客户回送认证成功消息，否则返回错误消息。到此为止，握手协议全部结束。</p>
            <p>要使用SSL协议，服务器至少有一个私有密匙和一个用于验证身份的证书。私有密匙在密匙交换算法中用到，证书将发送到客户端，以通知服务器端的身份。如果SSL服务器要验证客户端的身份，那么客户端必须也有自己的密匙库（包含私有密匙和证书）。JSSE中引入了信任库（truststore）的概念，它是用来保存证书的数据库。客户端或者服务器通过信任库来验证对方的身份。</p>
            <p>在使用SSL前，必须确保系统安装了JSSE。JDK1.4版本默认以及安装了JSSE。如果没有安装，把下载安装好的jar文件拷贝到%JAVA_HOME%\ jre\lib\ext目录下。这样，就安装好了JSSE的运行环境。</p>
            <p>下面我们使用JDK自带的工具创建密匙库和信任库。</p>
            <p>1）通过使用一下的命令来创建服务器端的密匙库。</p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">        keytool -genkey -alias hellking -keystore server.keystore -keyalg RSA
                        输入keystore密码：  changeit
                        您的名字与姓氏是什么？
                        [Unknown]：  hellking-Server
                        您的组织单位名称是什么？
                        [Unknown]：  huayuan
                        您的组织名称是什么？
                        [Unknown]：  huayuan
                        您所在的城市或区域名称是什么？
                        [Unknown]：  beijing
                        您所在的州或省份名称是什么？
                        [Unknown]：  beijing
                        该单位的两字母国家代码是什么
                        [Unknown]：  cn
                        CN=chen ya qiang, OU=huayuan, O=huayuan, L=beijing, ST=beijing, C=cn 正确吗？
                        [否]：  y
                        输入&lt;hellking&gt;的主密码
                        （如果和 keystore 密码相同，按回车）：
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>以上命令执行完成后，将获得一个名为server.keystore的密匙库。</p>
            <p>2)生成客户端的信任库。首先输出RSA证书：</p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">keytool -export -file test_axis.cer -storepass changeit -keystore server.keystore
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>然后把RSA证书输入到一个新的信任库文件中。这个信任库被客户端使用，被用来验证服务器端的身份。</p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">keytool -import -file test_axis.cer -storepass changeit -keystore client.truststore -alias serverkey -noprompt
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>3）创建客户端密匙库。重复步骤1，创建客户端的密匙库。也可以使用以下命令来完成：</p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">keytool -genkey -dname " CN=hellking-Client, OU=tsinghua, O=tsinghua, L=BEIJING, S=BEIJING, C=CN"
                        -storepass changeit -keystore client.keystore -keyalg RSA -keypass changeit
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>4）生成服务器端的信任库。</p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">keytool -export -file test_axis.cer -storepass changeit -keystore client.keystore
                        keytool -import -file test_axis.cer -storepass changeit -keystore server.truststore -alias clientkey -noprompt
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>生成了密匙库和信任库，我们把服务器端的密匙库（server.keystore）和信任库（server.truststore）拷贝到Tomcat的某个目录。</p>
            <p>下面需要更改Tomcat的配置文件（server.xml），增加一下部署描述符：</p>
            <br />
            <a name="N101CF"><strong>例程11 为Tomcat配置SSL协议。</strong></a><br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">                  &lt;Connector port="8443"
                        maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
                        enableLookups="false" disableUploadTimeout="true"
                        acceptCount="100" debug="0" scheme="https" secure="true"
                        clientAuth="true" keystoreFile="K:\jakarta-tomcat-5.0.16\server.keystore" keystorePass="changeit"
                        truststoreFile="K:\jakarta-tomcat-5.0.16\server.truststore" truststorePass="changeit"
                        sslProtocol="TLS" /&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>clientAuth参数制定服务器是否要验证客户端证书，如果指定为true，那么客户端必须拥护服务器端可信任的证书后服务器才能响应客户端；如果指定为false，那么服务器不需要验证客户端的证书。</p>
            <p>在此，我们又把PersonalTaxService部署一次，在server-config.wsdd中添加如下部署代码。</p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">&lt;service name="PersonalTaxService3" provider="java:RPC"&gt;
                        &lt;parameter name="allowedMethods" value="*"/&gt;
                        &lt;parameter name="className" value="com.hellking.study.webservice.PersonalTaxService"/&gt;
                        &lt;/service&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>最后我们需要修改客户端调用程序，如例程12所示。</p>
            <br />
            <a name="N101E6"><strong>例程12 SSL客户端调用程序</strong></a><br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">package com.hellking.study.webservice;
                        &#8230;.
                        public class SSLAuthClient
                        {
                        static	final double salary=5000;
                        public static void main(String [] args)
                        {
                        try {
                        //服务端的url，注意使用了SSL协议后，前缀是https。
                        String endpointURL = "https://localhost:8443/axis/services/PersonalTaxService3?wsdl";
                        &#8230;.
                        //由于使用了证书数字证书，所以不使用用户名和密码验证。
                        //call.getMessageContext().setUsername("hellking");。
                        //call.getMessageContext().setPassword("simplewebservices");
                        &#8230;.
                        Double ret = (Double) call.invoke( new Object [] { new Double(salary) });
                        System.out.println("使用SSL协议来作为Web服务的传输协议！");
                        System.out.println("已经成功调用。请参看服务端的输出!");
                        System.out.println("输入工资"+salary+"元，应交个人所得税："+ret);
                        } catch (Exception e) {
                        e.printStackTrace();
                        }
                        }
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>最后使用一下的命令来执行客户端程序：</p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">set AXIS_LIB=K:\jakarta-tomcat-5.0.16\webapps\axis\WEB-INF\lib
                        SET CLASSPATH=.;%CLASSPATH%;%AXIS_LIB%\wsdl4j.jar.jar;%AXIS_LIB%\axis.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%
                        \saaj.jar;%AXIS_LIB%\commons-discovery.jar;%AXIS_LIB%\commons-logging.jar
                        java -Djavax.net.ssl.keyStore=client.keystore \
                        -Djavax.net.ssl.keyStorePassword=changeit \
                        -Djavax.net.ssl.trustStore=client.truststore \
                        com.hellking.study.webservice.SSLAuthClient
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>参数解释：通过-Djavax.net.ssl.keyStore来指定客户端密匙库，-Djavax.net.ssl.trustStore来指定客户端信任库。</p>
            <p>最后的输出结果如下：</p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">使用SSL协议来作为Web服务的传输协议！
                        已经成功调用。请参看服务端的输出!
                        输入工资5000.0元，应交个人所得税：445.0
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
                        <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
                        <table cellspacing="0" cellpadding="0" border="0">
                            <tbody>
                                <tr>
                                    <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                                    </td>
                                    <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/webservices/ws-secaxis1/#main"><strong>回页首</strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N10201"><span class="atitle">总结、下一步</span></a></p>
            <p>使用Web应用模型中基本认证方法来配置Web服务的安全访问以及使用axis的Handler、Servlet的过滤器来进行访问控制，它们都是一些轻量级控制Web服务安全解决方案，因为都是把未加密的信息在网络上传播。使用了SSL作为传输协议后，信息在网络上是加密传输的，但对资源消耗多，并且对客户端要求严格（必须支持SSL），不能满足Web服务访问的便利性。下一部分将介绍怎么在安全性要求高的环境下在axis开发工具里实现WS-Security。</p>
            <a href="http://www.ibm.com/developerworks/cn/webservices/ws-secaxis1/src.rar">下载样例代码在此。</a> <br />
            <br />
            <p><a name="resources"><span class="atitle">参考资料 </span></a></p>
            <ul>
                <li><a href="http://www.xmltrustcenter.org/">VeriSign Trust Services Integration Kit</a> <br />
                <br />
                <li><a href="http://www.ibm.com/developerworks/cn/security/se-tcssl/index.html">配置Tomcat 4使用SSL</a> <br />
                <br />
                <li><a href="http://www.ibm.com/developerworks/cn/webservices/ws-jax-rpc/part1/index.html">用JAX-RPC开发Web服务：Servlet作为Web服务端点</a> <br />
                <br />
                <li><a href="http://ws.apache.org/axis/">Apache axis User's Guides：http://ws.apache.org/axis/</a> <br />
                <br />
                <li><a href="http://java.sun.com/webservices">JAX-RPC API</a> <br />
                <br />
                <li><a href="http://java.sun.com/products/jdk/1.2/docs/tooldocs/solaris/keytool.html">Keytool－ Key and Certificate Management Tool</a> <br />
                <br />
                <li><a href="http://jakarta.apache.org/tomcat/tomcat-5.0-doc/ssl-howto.html">The Tomcat 5 Servlet/JSP Container SSL Configuration HOW-TO</a> <br />
                <br />
                <li><a href="http://www.ibm.com/developerworks/cn/webservices/ws-handler/index.html">J2EE Web服务开发系列之六: 使用Handler来增强Web服务的功能</a> </li>
            </ul>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/libin2722/aggbug/161344.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-11-18 10:11 <a href="http://www.blogjava.net/libin2722/archive/2007/11/18/161344.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>应用AXIS开始Web 服务之旅</title><link>http://www.blogjava.net/libin2722/archive/2007/11/18/161343.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sun, 18 Nov 2007 02:10:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/archive/2007/11/18/161343.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/161343.html</wfw:comment><comments>http://www.blogjava.net/libin2722/archive/2007/11/18/161343.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/161343.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/161343.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr valign="top">
            <td width="100%">
            <h1>应用AXIS开始Web 服务之旅</h1>
            <img class="display-img" height="6" alt="" src="http://www.ibm.com/i/c.gif" width="1" /></td>
            <td class="no-print" width="192"><img height="18" alt="developerWorks" src="http://www.ibm.com/developerworks/i/dw.gif" width="192" /></td>
        </tr>
    </tbody>
</table>
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr valign="top">
            <td width="10"><img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" /></td>
            <td width="100%">
            <table class="no-print" cellspacing="0" cellpadding="0" width="160" align="right" border="0">
                <tbody>
                    <tr>
                        <td width="10"><img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" /></td>
                        <td>
                        <table cellspacing="0" cellpadding="0" width="150" border="0">
                            <tbody>
                                <tr>
                                    <td class="v14-header-1-small">文档选项</td>
                                </tr>
                            </tbody>
                        </table>
                        <table class="v14-gray-table-border" cellspacing="0" cellpadding="0" border="0">
                            <tbody>
                                <tr>
                                    <td class="no-padding" width="150">
                                    <table cellspacing="0" cellpadding="0" width="143" border="0">
                                        <img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="8" />
                                        <form name="email" action="https://www.ibm.com/developerworks/secure/email-it.jsp">
                                            <input type="hidden" value="本文介绍使用AXIS作为开发环境来体会Web服务的开发过程。" name="body" /><input type="hidden" value="应用AXIS开始Web 服务之旅" name="subject" /><input type="hidden" value="cn" name="lang" /> <script language="JavaScript" type="text/javascript">
<!-- document.write('<tr valign="top"><td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt="" /></td><td width="16"><img src="//www.ibm.com/i/v14/icons/em.gif" height="16" width="16" vspace="3" alt="将此页作为电子邮件发送"  /></td><td width="122"><p><a class="smallplainlink" href="javascript:document.email.submit();"><strong>将此页作为电子邮件发送</strong></a></p></td></tr>');
//-->
</script>
                                            <tbody>
                                                <tr valign="top">
                                                    <td width="8"><img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="8" /></td>
                                                    <td width="16"><img height="16" alt="将此页作为电子邮件发送" src="http://www.ibm.com/i/v14/icons/em.gif" width="16" vspace="3" /></td>
                                                    <td width="122">
                                                    <p><a class="smallplainlink" href="javascript:document.email.submit();"><strong>将此页作为电子邮件发送</strong></a></p>
                                                    </td>
                                                </tr>
                                                <noscript>
                                                <tr valign="top">
                                                    <td width="8"><img alt="" height="1" width="8" src="//www.ibm.com/i/c.gif"  /></td>
                                                    <td width="16"><img alt="" width="16" height="16" src="//www.ibm.com/i/c.gif"  /></td>
                                                    <td class="small" width="122">
                                                    <p><span class="ast">未显示需要 JavaScript 的文档选项</span></p>
                                                    </td>
                                                </tr>
                                                </noscript>
                                            </form>
                                        </tbody>
                                    </table>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        <!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- this content will be automatically generated across all content areas --><br />
                        <!--end RESERVED FOR FUTURE USE INCLUDE FILES--><br />
                        </td>
                    </tr>
                </tbody>
            </table>
            <p>级别： 初级</p>
            <p><a href="http://www.ibm.com/developerworks/cn/webservices/ws-startaxis/index.html#author">刘冬</a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#119;&#105;&#110;&#116;&#101;&#114;&#46;&#108;&#97;&#117;&#64;&#49;&#54;&#51;&#46;&#99;&#111;&#109;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#24212;&#29992;&#65;&#88;&#73;&#83;&#24320;&#22987;&#87;&#101;&#98;&#32;&#26381;&#21153;&#20043;&#26053;">winter.lau@163.com</a>), 软件工程师<br />
            </p>
            <p>2003 年 7 月 01 日</p>
            <blockquote>本文介绍使用AXIS作为开发环境来体会Web服务的开发过程。</blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
            <p><a name="1"><span class="atitle">一． 介绍</span></a></p>
            <p><br />
            本文并不是想介绍Web服务的原理、系统架构等，我们假设您已经了解了关于Web服务的一些基本的概念、原理等知识。本文主要是针对那些已经了解Web服务概念，但是还没有亲身体会Web服务所带来令人欢欣鼓舞的特征的开发人员。在此我们认为你已经具备了Java、XML等基础知识，如果你还有其他开发环境的经验例如VB、VC那是再好不过的了。 </p>
            <p><a name="N10050"><span class="smalltitle">1．Web服务</span></a></p>
            <p><br />
            虽然我们并不想详细讲述Web服务的体系结构，但是大概的介绍一下还是有必要的。Web服务是一种新型的Web应用程序。不同于其他Web应用程序，它是自适应、自我描述、模块化的应用程序，并可以跨越Web进行发布、定位以及调用。简单的Web服务可以提供例如天气预报或者航班信息的服务。一旦部署了Web服务，其他的应用程序就可以发现和调用所部署的服务。 </p>
            <p><a name="N1005B"><span class="smalltitle">2．AXIS项目</span></a></p>
            <p><br />
            Axis框架来自 Apache 开放源代码组织，它是基于JAVA语言的最新的 SOAP 规范（SOAP 1.2）和 SOAP with Attachments 规范（来自 Apache Group ）的开放源代码实现。有很多流行的开发工具都使用AXIS作为其实现支持Web服务的功能，例如JBuilder以及著名的Eclipse J2EE插件Lomboz。AXIS的最新版本是1.1，可以从 <a href="http://ws.apache.org/axis/index.html" target="_blank">http://ws.apache.org/axis/index.html</a>下载。下图是AXIS核心引擎的体系结构图： </p>
            <br />
            <img alt="" src="http://www.ibm.com/developerworks/cn/webservices/ws-startaxis/1_axis_engine.jpg" /> <br />
            <p><strong>图1</strong> </p>
            <p>整个AXIS项目包括以下几个部分：</p>
            <ol>
                <li>消息流子系统 <br />
                消息流子系统提供了灵活的消息传递框架，这个消息传递框架包括处理程序、链、序列化程序和反序列化程序。处理程序是一个处理请求、响应和故障流的对象。处理程序可被组合在一起成为链，而且可以使用一个灵活的部署描述符来配置这些处理程序的顺序。
                <li>传输框架子系统 <br />
                提供了一个传输框架，这个传输框架可以帮助您创建自己的可插式传输发送器和传输侦听器。
                <li>数据编码子系统 <br />
                AXIS完全按照 XML Schema 规范提供各种数据类型的自动序列化，并且提供功能扩展接口来使用您自己定制的序列化器和反序列化器。
                <li>其他 <br />
                AXIS完全支持 WSDL 以及日志记录、出错以及故障处理机制。它同时提供一些工具用来讲WSDL文档转换成客户端的调用框架以及根据类来产生WSDL定义文档。 </li>
            </ol>
            <p>AXIS目前版本支持的标准是：W3C SOAP 1.1 和 1.2；WSDL 1.1；SAAJ 1.1（SUN公司：SOAP with Attachments API for Java）；JAX-RPC（SUN公司：Java API for XML-Based RPC）1.0。 </p>
            <p>除了前面介绍的AXIS外，本文中还将会用到TOMCAT，这里不再另行介绍。另外为了演示Web服务真正与开发环境无关以及AXIS产生的是标准的、符合规范的Web服务，我们还将用到微软公司的SOAP TOOLKIT以及微软的开发环境VB和VC来做为Web服务的客户端。 </p>
            <br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
                        <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
                        <table cellspacing="0" cellpadding="0" border="0">
                            <tbody>
                                <tr>
                                    <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                                    </td>
                                    <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/webservices/ws-startaxis/index.html#main"><strong>回页首</strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="2"><span class="atitle">二. 环境搭建</span></a></p>
            <p><br />
            由于AXIS本身是基于JAVA语言开发的项目，并且是以Web应用形式发布的，因此它运行时需要一个应用服务器作为支撑。为了方便我们这里选用的是Tomcat。由于AXIS本身需要用到处理XML信息的包，所以我们建议使用JDK1.4并安装Tomcat 4.1.24。下面是环境搭建步骤，读取根据自身情况进行安装。 </p>
            <ol>
                <li>安装JDK1.4.1
                <li>安装Tomcat 4.1.24到C:\Tomcat并验证安装是否成功
                <li>下载AXIS项目打包文件axis-1_1.zip解压缩后将目录中的webapps目录下的axis子目录拷贝到C:\Tomcat\webapps下。
                <li>验证AXIS的安装：重新启动Tomcat服务器后打开浏览器输入网址http://localhost:8080/axis 后应该出现如下图所示页面，点击链接"Validate"来验证Axis所需的几个JAVA包是否齐全。 </li>
            </ol>
            <br />
            <img alt="" src="http://www.ibm.com/developerworks/cn/webservices/ws-startaxis/2_axis_home.jpg" /> <br />
            <p><strong>图2</strong> </p>
            <p>点击超链接Validate后，AXIS会自动检查所需的每一个JAVA组件，这协组件分为：必需组件以及可选组件，必须保证所有必需组件都存在，如下图所示即为验证成功。 </p>
            <br />
            <img alt="" src="http://www.ibm.com/developerworks/cn/webservices/ws-startaxis/3_axis_verify.jpg" /> <br />
            <p><strong>图3</strong> </p>
            <br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
                        <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
                        <table cellspacing="0" cellpadding="0" border="0">
                            <tbody>
                                <tr>
                                    <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                                    </td>
                                    <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/webservices/ws-startaxis/index.html#main"><strong>回页首</strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="3"><span class="atitle">三． Web Service服务端开发</span></a></p>
            <p><br />
            经过了前两步之后我们就可以开始Web服务之旅了！大多数人在学习一种编程语言的第一步都是从Hello world程序开始的，我们也不例外。我们将提供这样一个Web服务，通过给它传入姓名，服务返回：你好[姓名]，欢迎来到Web服务的世界。这就是我们的需求。我们将马上根据AXIS的要求完成我们的需求，你就会发现原来Web服务可以这么简单！ </p>
            <p>编写JAVA类Hello.java，内容如下：</p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">public class Hello{
                        public String hello(String name){
                        if(name==null)
                        name = "";
                        return "你好"+name+"，欢迎来到Web服务的世界！";
                        }
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>仅此而已，无需编译，将该文件改名为Hello.jws并拷贝到AXIS应用目录C:\Tomcat\webapps\axis下。 </p>
            <p>下面我们就可以测试该Web服务了，打开浏览器并输入刚刚创建的文件名对应的URL地址 <a href="http://localhost:8080/axis/Hello.jws" target="_blank">http://localhost:8080/axis/Hello.jws</a> 浏览器显示如下结果： </p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">There is a Web Service here
                        <a href="http://localhost:8080/axis/Hello.jws?wsdl" target="_blank">Click to see the WSDL </a>
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>点击页面上的链接查看该Web服务对应的WSDL信息如下所示（我们将在下一小节简单介绍WSDL） </p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
                        -&lt;wsdl:definitions
                        targetNamespace="http://localhost:8080/axis/Hello.jws"
                        xmlns="http://schemas.xmlsoap.org/wsdl/"
                        xmlns="http://www.w3.org/2000/xmlns/"
                        xmlns:apachesoap="http://xml.apache.org/xml-soap"
                        xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
                        xmlns:impl="http://localhost:8080/axis/Hello.jws"
                        xmlns:intf="http://localhost:8080/axis/Hello.jws"
                        xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
                        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"&gt;
                        - &lt;wsdl:message name="helloRequest"&gt;
                        &lt;wsdl:part name="name" type="xsd:string" /&gt;
                        &lt;/wsdl:message&gt;
                        + &lt;wsdl:message name="helloResponse"&gt;
                        - &lt;wsdl:portType name="Hello"&gt;
                        - &lt;wsdl:operation name="hello" parameterOrder="name"&gt;
                        &lt;wsdl:input name="helloRequest" message="intf:helloRequest" /&gt;
                        &lt;wsdl:output name="helloResponse" message="intf:helloResponse" /&gt;
                        &lt;/wsdl:operation&gt;
                        &lt;/wsdl:portType&gt;
                        - &lt;wsdl:binding name="HelloSoapBinding" type="intf:Hello"&gt;
                        &lt;wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" /&gt;
                        - &lt;wsdl:operation name="hello"&gt;
                        &lt;wsdlsoap:operation soapAction="" /&gt;
                        - &lt;wsdl:input name="helloRequest"&gt;
                        &lt;wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
                        namespace="http://DefaultNamespace" /&gt;
                        &lt;/wsdl:input&gt;- &lt;wsdl:output name="helloResponse"&gt;
                        &lt;wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
                        namespace="http://localhost:8080/axis/Hello.jws" /&gt;
                        &lt;/wsdl:output&gt;
                        &lt;/wsdl:operation&gt;
                        &lt;/wsdl:binding&gt;
                        - &lt;wsdl:service name="HelloService"&gt;
                        - &lt;wsdl:port name="Hello" binding="intf:HelloSoapBinding"&gt;
                        &lt;wsdlsoap:address location="http://localhost:8080/axis/Hello.jws" /&gt;
                        &lt;/wsdl:port&gt;
                        &lt;/wsdl:service&gt;
                        &lt;/wsdl:definitions&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>到此我们已经完成了hello的Web服务了，那我们怎么告诉用户如何来使用该服务呢？我们只需要告诉用户我们的Web服务的URL地址： <a href="http://localhost:8080/axis/Hello.jws?wsdl" target="_blank">http://localhost:8080/axis/Hello.jws?wsdl</a> 就可以了！下一节我们将介绍如何通过这个地址来访问对应的Web服务。 </p>
            <br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
                        <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
                        <table cellspacing="0" cellpadding="0" border="0">
                            <tbody>
                                <tr>
                                    <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                                    </td>
                                    <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/webservices/ws-startaxis/index.html#main"><strong>回页首</strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="4"><span class="atitle">四． Web Service客户端开发</span></a></p>
            <p><br />
            在这一节中我们将使用三种不同的语言来访问刚刚创建的Web服务，分别是JAVA、VB、VC。为了使用VB和VC访问Web服务，我们需要安装微软公司的Soap Toolkit 开发工具包，这个工具包可以从微软公司的主页 </p>
            <p><a href="http://download.microsoft.com/download/xml/soap/2.0/W98NT42KMe/EN-US/SoapToolkit20.exe" target="_blank">http://download.microsoft.com/download/xml/soap/2.0/W98NT42KMe/EN-US/SoapToolkit20.exe</a> </p>
            <p>下载，下载该软件包并使用默认方式安装即可。 </p>
            <p>在开始客户端开发之前有两个概念我们必须先粗略的介绍一下。 </p>
            <p>SOAP：简单对象访问协议。这是一种在松散的、分布的环境中使用XML对等地交换结构化的和类型化的信息提供了一个简单且轻量级的机制，它是一个基于XML的协议。它包括四个部分：SOAP封装（envelop），封装定义了一个描述消息中的内容是什么，是谁发送的，谁应当接受并处理它以及如何处理它们的框架；SOAP编码规则（encoding rules），用于表示应用程序需要使用的数据类型的实例; SOAP RPC表示(RPC representation)，表示远程过程调用和应答的协定;SOAP绑定（binding），使用底层协议交换信息。 </p>
            <p>虽然这四个部分都作为SOAP的一部分，作为一个整体定义的，但他们在功能上是相交的、彼此独立的。特别的，信封和编码规则是被定义在不同的XML命名空间(namespace)中，这样使得定义更加简单。 </p>
            <p>SOAP的主要设计目标是简明性和可扩展性。这就意味着有一些传统消息系统或分布式对象系统中的特性将不包含在SOAP的核心规范中。这些特性包括：分布式垃圾收集；批量消息传输/处理；对象引用；对象激活。 </p>
            <p>WSDL：Web Service描述语言。使用了WSDL，我们就可以通过这种跨平台和跨语言的方法使Web Service代理的产生自动化。就像COM和CORBA的IDL文件，WSDL文件由客户和服务器约定。由于WSDL设计成可以绑定除SOAP以外的其他协议，这里我们主要关注WSDL在HTTP上和SOAP的关系。同样，由于SOAP目前主要用来调用远程的过程和函数，WSDL支持SOAP传输的文档规范。 </p>
            <p>WSDL文档可以分为两部分。顶部分由抽象定义组成，而底部分则由具体描述组成。抽象部分以独立于平台和语言的方式定义SOAP消息，它们并不包含任何随机器或语言而变的元素。这就定义了一系列服务，截然不同的网站都可以实现。 </p>
            <p><a name="N10144"><span class="smalltitle">1. JAVA客户端</span></a></p>
            <p><br />
            使用AXIS的工具将使Web服务的访问和我们之前介绍的创建一个Web服务一样的简单。我们前面安装的AXIS环境中已经包含着这样的工具，它是一个JAVA类，类名为：org.apache.axis.wsdl.WSDL2Java。打开命令行窗口，转到AXIS目录下的WEB-INF子目录。确保Tomcat服务已经处于启动状态，键入命令 ： </p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">Java -Djava.ext.dirs=lib org.apache.axis.wsdl.WSDL2Java http://localhost:8080/axis/Hello.jws?wsdl
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>该命令执行的结果是在当前所在目录下产生一个子目录 localhost/axis/Hello_jws，该目录下有四个JAVA源文件，它们分别是： </p>
            <p>Hello.java 定义了Web服务接口，此例中只有一个hello方法。 </p>
            <p>HelloService.java 定义了用于获取Web服务接口的方法。 </p>
            <p>HelloServiceLocator.java 接口HelloService的具体实现。 </p>
            <p>HelloSoapBindingStub.java Web服务客户端桩，通过该类与服务器交互。 </p>
            <p>这四个JAVA类帮我们处理了大部分的逻辑，我们需要的仅仅是把这些类加到我们的项目然后创建一个我们自己的类来调用它们即可。为此我们新加一个类Main.java，为了方便，让这个类与刚产生的四个类都在同一个包下。内容如下： </p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">//Main.java
                        package localhost.axis.Hello_jws;
                        public class Main{
                        public static void main(String[] args) throws Exception{
                        HelloService service = new HelloServiceLocator();
                        Hello hello = service.getHello();
                        System.out.println("Response:"+hello.hello("罐头"));
                        }
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>使用以下命令进行编译： </p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">javac -classpath lib\axis.jar;lib\jaxrpc.jar localhost\axis\Hello_jws\*.java
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>如果编译没有问题的话执行该测试程序：</p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">java -Djava.ext.dirs=lib -cp . localhost.axis.Hello_jws.Main//运行结果：Response:你好罐头，欢迎来到Web服务的世界！
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>在WSDL2Java工具自动产生的几个类中，类HelloServiceLocator中保存这一些跟服务器相关的信息，例如URL地址等，当服务器的地址更改后但是服务并没有改动的时候直接修改该文件中的字符串定义，而无需重新生成这几个类。具体需要修改的内容，打开该文件便可一目了然。 </p>
            <p><a name="N1017A"><span class="smalltitle">2. VB客户端</span></a></p>
            <p><br />
            有了微软SOAP toolkit，用VB调用Web服务也是一件令人愉快的事情。 </p>
            <p>打开VB开发环境新建一个标准EXE项目，打开工程(Project)菜单并选择引用打开组件引用对话框如下图所示：找到并选中Microsoft Soap Type Library。 </p>
            <br />
            <img alt="" src="http://www.ibm.com/developerworks/cn/webservices/ws-startaxis/image008.jpg" /> <br />
            <p><strong>图 4</strong> </p>
            <p>新建并编辑窗体如下图所示：</p>
            <br />
            <img alt="" src="http://www.ibm.com/developerworks/cn/webservices/ws-startaxis/4_vbclient.jpg" /> <br />
            <p><strong>图 5</strong> </p>
            <p>编辑按钮Call的点击事件处理程序如下：（注意窗体的控件名称要与程序中的名称对应）</p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">Private Sub callBtn_Click()
                        '这种做法需要在工程中引用Soap Type Library
                        'Dim soap As MSSOAPLib.SoapClient
                        'Set soap = New MSSOAPLib.SoapClient
                        Dim soap
                        Set soap = CreateObject("MSSOAP.SoapClient")
                        On Error Resume Next
                        'soap.mssoapinit urlText.Text
                        Call soap.mssoapinit(urlText.Text)
                        If Err &lt;&gt; 0 Then
                        MsgBox "初始化SOAP失败： " + Err.Description
                        urlText.SetFocus
                        Else
                        If Len(Trim(nameText.Text)) = 0 Then
                        MsgBox "请输入您的姓名！"
                        nameText.SetFocus
                        Else
                        responseText.Text = soap.hello(nameText.Text)
                        End If
                        End If
                        End Sub
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>保存项目并运行，输入姓名并点击按钮Call。 </p>
            <p><a name="N101BF"><span class="smalltitle">3. VC客户端</span></a></p>
            <p><br />
            打开VC开发环境，新建项目HelloClient，项目类型为 Win32 Console Application的空项目。新建C++ Source File文件名为：HelloSoap.cpp，编辑文件内容如下： </p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">//#include "stdafx.h"
                        #include &lt;stdio.h&gt;
                        #import "msxml3.dll"
                        using namespace MSXML2;
                        //根据自己机器的情况修改下面语句中指定的路径
                        #import "C:\Program Files\Common Files\MSSoap\Binaries\mssoap1.dll" \
                        exclude("IStream", "ISequentialStream", "_LARGE_INTEGER", \
                        "_ULARGE_INTEGER", "tagSTATSTG", "_FILETIME")
                        using namespace MSSOAPLib;
                        void Hello(){
                        ISoapSerializerPtr Serializer;
                        ISoapReaderPtr Reader;
                        ISoapConnectorPtr Connector;
                        // Connect to the service
                        Connector.CreateInstance(__uuidof(HttpConnector));
                        Connector-&gt;Property["EndPointURL"] = "http://localhost:8080/axis/Hello.jws?wsdl";
                        Connector-&gt;Connect();
                        // Begin message
                        Connector-&gt;BeginMessage();
                        // Create the SoapSerializer
                        Serializer.CreateInstance(__uuidof(SoapSerializer));
                        // Connect the serializer to the input stream of the connector
                        Serializer-&gt;Init(_variant_t((IUnknown*)Connector-&gt;InputStream));
                        // Build the SOAP Message
                        Serializer-&gt;startEnvelope("","","");
                        Serializer-&gt;startBody("");
                        Serializer-&gt;startElement("hello","","","");
                        Serializer-&gt;startElement("name","","","");
                        Serializer-&gt;writeString("罐头");
                        Serializer-&gt;endElement();
                        Serializer-&gt;endElement();
                        Serializer-&gt;endBody();
                        Serializer-&gt;endEnvelope();
                        // Send the message to the web service
                        Connector-&gt;EndMessage();
                        // Let us read the response
                        Reader.CreateInstance(__uuidof(SoapReader));
                        // Connect the reader to the output stream of the connector
                        Reader-&gt;Load(_variant_t((IUnknown*)Connector-&gt;OutputStream), "");
                        // Display the result
                        printf("Response: %s\n", (const char*)Reader-&gt;RPCResult-&gt;text);
                        }
                        int main()
                        {
                        CoInitialize(NULL);
                        Hello();
                        CoUninitialize();
                        return 0;
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>编译并运行该项目。</p>
            <p>本节只是为了演示如果通过VC来访问使用AXIS创建的Web服务，至于Soap toolkit的具体使用请参照soap toolkit的帮助手册，其他语言的访问请查阅相关的文档。 </p>
            <br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
                        <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
                        <table cellspacing="0" cellpadding="0" border="0">
                            <tbody>
                                <tr>
                                    <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                                    </td>
                                    <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/webservices/ws-startaxis/index.html#main"><strong>回页首</strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="5"><span class="atitle">五. AXIS集成</span></a></p>
            <p>
            <p>为了让我们的WEB应用程序支持Web服务功能，我们需要将AXIS集成到我们的应用程序中。集成AXIS很简单，首先需要拷贝AXIS用到的几个JAR包文件，这些文件都在[AXIS]\WEB-INF\lib目录下，将这些文件拷贝到我们自己的应用目录下的WEB-INF\lib。另外如果你用的不是TOMCAT服务器那就需要拷贝activation.jar，这个JAR文件可以在[TOMCAT]\common\lib目录下找到！ </p>
            <p>拷贝完JAR文件后就是web.xml的配置了，只需要把AXIS中的web.xml中的配置信息添加到我们自己应用程序中的web.xml中即可。最重要的是下面的内容： </p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">&lt;servlet&gt;
                        &lt;servlet-name&gt;AxisServlet&lt;/servlet-name&gt;
                        &lt;display-name&gt;Apache-Axis Servlet&lt;/display-name&gt;
                        &lt;servlet-class&gt;
                        org.apache.axis.transport.http.AxisServlet
                        &lt;/servlet-class&gt;
                        &lt;/servlet&gt;
                        &lt;servlet-mapping&gt;
                        &lt;servlet-name&gt;AxisServlet&lt;/servlet-name&gt;
                        &lt;url-pattern&gt;*.jws&lt;/url-pattern&gt;
                        &lt;/servlet-mapping&gt;
                        &lt;mime-mapping&gt;
                        &lt;extension&gt;wsdl&lt;/extension&gt;
                        &lt;mime-type&gt;text/xml&lt;/mime-type&gt;
                        &lt;/mime-mapping&gt;
                        &lt;mime-mapping&gt;
                        &lt;extension&gt;xsd&lt;/extension&gt;
                        &lt;mime-type&gt;text/xml&lt;/mime-type&gt;
                        &lt;/mime-mapping&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
                        <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
                        <table cellspacing="0" cellpadding="0" border="0">
                            <tbody>
                                <tr>
                                    <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                                    </td>
                                    <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/webservices/ws-startaxis/index.html#main"><strong>回页首</strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="6"><span class="atitle">六 总结</span></a></p>
            <p><br />
            到此文章告一段落，通过以上的演练，我相信你已经对Web服务有一个感性的认识，但是这个仅仅是开始，我们也只是很简单的介绍了Web服务的一些基本概念并演示了一个无法再简单的例子。Web服务还有很多其他高级的内容例如复杂类型、数据安全等没有涉及到，不过没有关系，万事开头难，希望本文能够促进大家理解和应用下一代的应用模式并给还没有动手试验的开发人员开一个好头。 </p>
            <br />
            <br />
            <p><a name="resources"><span class="atitle">参考资料 </span></a></p>
            <ul>
                <li>IBM开发者站点Web服务专区 <a href="http://www.ibm.com/developerworks/cn/xml/" target="_blank">http://www.ibm.com/developerworks/cn/xml</a> <br />
                <br />
                <li>Apache网站AXIS项目 <a href="http://ws.apache.org/axis/" target="_blank">http://ws.apache.org/axis/</a> <br />
                <br />
                <li>Apache Tomcat <a href="http://jakarta.apache.org/tomcat" target="_blank">http://jakarta.apache.org/tomcat</a> <br />
                <br />
                <li>微软公司MSDN站点 <a href="http://www.microsoft.com/china/msdn" target="_blank">http://www.microsoft.com/china/msdn</a> <br />
                <br />
                <li>微软公司Soap Toolkit 2.0下载地址 <a href="http://download.microsoft.com/download/xml/soap/2.0/W98NT42KMe/EN-US/SoapToolkit20.exe" target="_blank">http://download.microsoft.com/download/xml/soap/2.0/W98NT42KMe/EN-US/SoapToolkit20.exe</a> <br />
                <br />
                <li>AXIS打包下载地址： <a href="http://ws.apache.org/axis/dist/1_1/" target="_blank">http://ws.apache.org/axis/dist/1_1/</a> <br />
                <br />
                <li>W3C之Web服务 <a href="http://www.w3.org/2002/ws/" target="_blank">http://www.w3.org/2002/ws/</a> <br />
                </li>
            </ul>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/libin2722/aggbug/161343.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-11-18 10:10 <a href="http://www.blogjava.net/libin2722/archive/2007/11/18/161343.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Axis开发WebService程序-（转载）</title><link>http://www.blogjava.net/libin2722/archive/2007/11/18/161341.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sun, 18 Nov 2007 02:08:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/archive/2007/11/18/161341.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/161341.html</wfw:comment><comments>http://www.blogjava.net/libin2722/archive/2007/11/18/161341.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/161341.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/161341.html</trackback:ping><description><![CDATA[今天是感恩节，差点又要在公司加班了。好在Web Service程序并不是特别难搞，下午终于在eclipse下调通过了，正确产生了服务器端和客户端的Java代码，apache的东西的确很不错。
<p>　　说道Web Service的程序开发，<a href="http://www.williamlong.info/archives/441.html" target="_blank">八个月前</a>我加班调试<a href="http://www.williamlong.info/archives/428.html" target="_blank">公司和中国电信的商务领航系统的接口</a>的时候，用的就是Web Service，Web Service有很多优点，使用Web Service可以在不同编程语言间实现数据交换，而我那时对Web Service也不熟，就由同事帮我生成了一大堆Web Service的框架代码，我则只单独开发业务代码。</p>
<p>　　这次的另外一个项目也要用Web Service了，不过人手也少了，没有人帮做Web Service了，只好自己动手。</p>
<p>　　好在开发前，有个同事先给我们不熟悉Web Service的程序员进行了一些培训，我才知道原来以前的Web Service都是可以自动生成代码的，而且也不难，试了一个下午客户端和服务器端的Web Service代码就都调试通过了，真不错。</p>
<p>　　为了更多喜爱开发的程序员也能迅速了解Web Service的开发，我这里整理了一些通过Axis开发Web Service的一些要点，希望能让不熟悉Web Service的开发人员能够迅速掌握Web Service。</p>
<p>　　<strong>一、Axis环境的安装</strong></p>
<p>　　1、安装环境 J2SE SDK 1.4，Tomcat 5.0，eclipse 3.2。</p>
<p>　　2、到 <a href="http://xml.apache.org/" target="_blank">http://xml.apache.org</a>&nbsp;网站下载Axis安装包。</p>
<p>　　3、将Axis相关包文件放在WEB-INF\lib目录下。</p>
<p>　　4、Axis可选的包：activation.jar； mail.jar； xmlsec-1.4.Beta1.jar拷贝到WEB-INF目录下，生成客户端时候需要使用。</p>
<p>　　Axis支持三种web service的部署和开发，分别为：</p>
<p>　　1、Dynamic Invocation Interface （DII）</p>
<p>　　2、Dynamic Proxy方式</p>
<p>　　3、Stubs方式</p>
<p>　　前两种方式我就不介绍了，同事告诉我他们自己都不使用前两种方式，他们建议我们使用Stubs方式，因此我就主要就介绍一下第三种方式。注意，我自己的Java源代码是放在D：\workspace\test\目录下，Axis相关包文件放在D：\workspace\test\WEB-INF目录下。</p>
<p>　　<strong>二、编写wsdd发布web服务，编写stub client访问web服务</strong></p>
<p>　　1、编写服务端程序server，SayHello.java，编译server.SayHello.java</p>
<p>package server;<br />
public class SayHello<br />
{<br />
&nbsp;&nbsp;&nbsp; public String getName(String name)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "hello "+name;<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p>　　2、编写wsdd文件</p>
<p>　　deploy.wsdd文件内容如下：</p>
<p>&lt;deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"&gt;<br />
&nbsp;&lt;service name="SayHello" provider="java:RPC"&gt;<br />
&nbsp; &lt;parameter name="className" value="server.SayHello.getName"/&gt;<br />
&nbsp; &lt;parameter name="allowedMethods" value="*"/&gt;<br />
&nbsp;&lt;/service&gt;<br />
&lt;/deployment&gt;</p>
<p>　　3、发布服务：</p>
<p>　　编辑一个deploy.bat，Axis_Lib为axis.jar路径。内容如下：</p>
<p>set Axis_Lib=D:\workspace\test\WEB-INF\lib<br />
set Java_Cmd=java -Djava.ext.dirs=%Axis_Lib%<br />
set Axis_Servlet=http://localhost:8080/test/servlet/AxisServlet</p>
<img src ="http://www.blogjava.net/libin2722/aggbug/161341.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-11-18 10:08 <a href="http://www.blogjava.net/libin2722/archive/2007/11/18/161341.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>