﻿<?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-都市淘沙者-文章分类-AJAX/XML/ANT/SOAP/WEBService</title><link>http://www.blogjava.net/jelver/category/7671.html</link><description>每天进步一点点</description><language>zh-cn</language><lastBuildDate>Thu, 24 Mar 2011 12:35:12 GMT</lastBuildDate><pubDate>Thu, 24 Mar 2011 12:35:12 GMT</pubDate><ttl>60</ttl><item><title>Ajax 跨域访问 — 方法大全</title><link>http://www.blogjava.net/jelver/articles/346337.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Tue, 15 Mar 2011 09:58:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/346337.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/346337.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/346337.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/346337.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/346337.html</trackback:ping><description><![CDATA[<a href="http://www.cftea.com/c/2008/06/9QA4QM0238B2C0SF.asp">http://www.cftea.com/c/2008/06/9QA4QM0238B2C0SF.asp</a><br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><span style="color: #000000;">Case&nbsp;I.&nbsp;Web代理的方式&nbsp;(on&nbsp;Server&nbsp;A)<br />
<br />
即用户访问&nbsp;A&nbsp;网站时所产生的对&nbsp;B&nbsp;网站的跨域访问请求均提交到&nbsp;A&nbsp;网站的指定页面，由该页面代替用户页面完成交互，从而返回合适的结果。此方案可以解决现阶段所能够想到的多数跨域访问问题，但要求&nbsp;A&nbsp;网站提供&nbsp;Web&nbsp;代理的支持，因此A网站与&nbsp;B&nbsp;网站之间必须是紧密协作的，且每次交互过程，A&nbsp;网站的服务器负担增加，且无法代用户保存&nbsp;Session&nbsp;状态。<br />
<br />
Case&nbsp;II.&nbsp;on-Demand方式&nbsp;(on&nbsp;Server&nbsp;A)<br />
<br />
MYMSN&nbsp;的门户就用的这种方式，不过&nbsp;MYMSN&nbsp;中不涉及跨域访问问题。在页面内动态生成新的&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span><span style="background-color: #f5f5f5; color: #000000;">，将其&nbsp;src&nbsp;属性指向别的网站的网址，这个网址返回的内容必须是合法的&nbsp;Javascript&nbsp;脚本，常用的是&nbsp;JSON&nbsp;消息。此方案存在的缺陷是，script&nbsp;的&nbsp;src&nbsp;属性完成该调用时采取的方式时&nbsp;get&nbsp;方式，如果请求时传递的字符串过大时，可能会无法正常运行。不过此方案非常适合聚合类门户使用。<br />
<br />
</span><span style="background-color: #f5f5f5; color: #000000;">&lt;</span><span style="background-color: #f5f5f5; color: #000000;">html</span><span style="background-color: #f5f5f5; color: #000000;">&gt;</span><span style="background-color: #f5f5f5; color: #000000;"><br />
</span><span style="background-color: #f5f5f5; color: #000000;">&lt;</span><span style="background-color: #f5f5f5; color: #000000;">head</span><span style="background-color: #f5f5f5; color: #000000;">&gt;</span><span style="background-color: #f5f5f5; color: #000000;"><br />
</span><span style="background-color: #f5f5f5; color: #000000;">&lt;</span><span style="background-color: #f5f5f5; color: #000000;">script&nbsp;language</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">javascript</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;type</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">text/javascript</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">&gt;</span><span style="background-color: #f5f5f5; color: #000000;"><br />
</span><span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;loadContent()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;s</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">document.createElement('script');<br />
&nbsp;&nbsp;&nbsp;&nbsp;s.src</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">'http:</span><span style="background-color: #f5f5f5; color: #008000;">//</span><span style="background-color: #f5f5f5; color: #008000;">www.anotherdomain.com/TestCrossJS.aspx?f=setDivContent';</span><span style="background-color: #f5f5f5; color: #008000;"><br />
</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;document.body.appendChild(s);<br />
}<br />
<br />
<br />
&nbsp;<br />
</span><span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;setDivContent(v)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;dv&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;document.getElementById(</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">dv</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;dv.innerHTML&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;v;&nbsp;<br />
}<br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;<br />
<br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">div&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">=dv</span><span style="color: #0000ff;">&gt;&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;<br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">input&nbsp;</span><span style="color: #ff0000;">onclick</span><span style="color: #0000ff;">=loadContent()&nbsp;</span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">=button&nbsp;</span><span style="color: #ff0000;">value</span><span style="color: #0000ff;">="Click&nbsp;Me"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<br />
其中的&nbsp;www.anotherdomain.com/TestCrossJS.aspx&nbsp;是这样的：<br />
<br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">script&nbsp;</span><span style="color: #ff0000;">language</span><span style="color: #0000ff;">="C#"</span><span style="color: #ff0000;">&nbsp;runat</span><span style="color: #0000ff;">="server"</span><span style="color: #0000ff;">&gt;</span><span style="background-color: #f5f5f5; color: #000000;"><br />
</span><span style="background-color: #f5f5f5; color: #0000ff;">void</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;Page_Load(object&nbsp;sender,&nbsp;EventArgs&nbsp;e)<br />
{<br />
&nbsp;&nbsp;string&nbsp;f&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;Request.QueryString[</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">f</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">];<br />
&nbsp;&nbsp;Response.Clear();<br />
&nbsp;&nbsp;Response.ContentType&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">application/x-javascript</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">;<br />
&nbsp;&nbsp;Response.Write(String.Format(@</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{0}('{1}');</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">,&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateTime.Now));<br />
&nbsp;&nbsp;Response.End();<br />
}<br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">&nbsp;<br />
<br />
点击&#8220;Click&nbsp;Me&#8221;按钮，生成一个新的&nbsp;script&nbsp;tag，下载对应的&nbsp;Javascript&nbsp;脚本，结束时回调其中的&nbsp;setDivContent()，从而更新网页上一个&nbsp;div&nbsp;的内容。<br />
<br />
编者注：如果&nbsp;Ajax&nbsp;的&nbsp;js&nbsp;内容由&nbsp;B&nbsp;提供，则&nbsp;A&nbsp;可以利用&nbsp;B&nbsp;提供的&nbsp;js&nbsp;方便地访问&nbsp;B&nbsp;的资源。比如&nbsp;A&nbsp;中的&nbsp;js&nbsp;代码：<br />
<br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">script&nbsp;</span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="text/javascript"</span><span style="color: #ff0000;">&nbsp;src</span><span style="color: #0000ff;">="B/core.js"</span><span style="color: #0000ff;">&gt;&lt;/</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<br />
Case&nbsp;III.&nbsp;iframe&nbsp;方式&nbsp;(on&nbsp;Server&nbsp;A)<br />
<br />
查看过醒来在&nbsp;javaeye&nbsp;上的一篇关于跨域访问的帖子，他提到自己已经用&nbsp;iframe&nbsp;的方式解决了跨域访问问题。数据提交跟获取，采用iframe这种方式的确可以了，但由于父窗口与子窗口之间不能交互（跨域访问的情况下，这种交互被拒绝），因此无法完成对父窗口效果的影响。<br />
<br />
在页面内嵌或动态生成指向别的网站的&nbsp;IFRAME，然后这&nbsp;2&nbsp;个网页间可以通过改变对方的&nbsp;anchor&nbsp;hash&nbsp;fragment&nbsp;来传输消息。改变一个网页的&nbsp;anchor&nbsp;hash&nbsp;fragment&nbsp;并不会使浏览器重新装载网页，所以一个网页的状态得以保持，而网页本身则可以通过一个计时器(timer)来察觉自己&nbsp;anchor&nbsp;hash&nbsp;的变化，从而相应改变自己的状态。<br />
<br />
1.&nbsp;http://domain1/TestCross.html:<br />
<br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">html</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">head</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">script&nbsp;</span><span style="color: #ff0000;">language</span><span style="color: #0000ff;">="javascript"</span><span style="color: #ff0000;">&nbsp;type</span><span style="color: #0000ff;">="text/javascript"</span><span style="color: #0000ff;">&gt;</span><span style="background-color: #f5f5f5; color: #000000;"><br />
</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;url&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">http://domain2/TestCross.html</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;"><br />
</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;oldHash&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">null</span><span style="background-color: #f5f5f5; color: #000000;">;<br />
</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;timer&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">null</span><span style="background-color: #f5f5f5; color: #000000;">;&nbsp;<br />
<br />
&nbsp;<br />
</span><span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;getHash()&nbsp;<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;hash&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;window.location.hash;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">if</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;((hash.length&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">&gt;=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">1</span><span style="background-color: #f5f5f5; color: #000000;">)&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">&amp;&amp;</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;(hash.charAt(</span><span style="background-color: #f5f5f5; color: #000000;">0</span><span style="background-color: #f5f5f5; color: #000000;">)&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">==</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;'#'))&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hash&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;hash.substring(</span><span style="background-color: #f5f5f5; color: #000000;">1</span><span style="background-color: #f5f5f5; color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">return</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;hash;<br />
}<br />
&nbsp;<br />
</span><span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;sendRequest()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;d&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;document;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;t&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;d.getElementById('request');<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;f&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;d.getElementById('alienFrame');<br />
&nbsp;&nbsp;&nbsp;&nbsp;f.src&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;url&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">+</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">#</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">+</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;t.value&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">+</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">&lt;br/&gt;</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">+</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">new</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;Date();<br />
}<br />
&nbsp;<br />
</span><span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;setDivHtml(v)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;d&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;document;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;dv&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;d.getElementById('response');<br />
&nbsp;&nbsp;&nbsp;&nbsp;dv.innerHTML&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;v;<br />
}<br />
&nbsp;<br />
</span><span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;idle()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;newHash&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;getHash();&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">if</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;(newHash&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">!=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;oldHash)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setDivHtml(newHash);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oldHash&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;newHash;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;timer&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;window.setTimeout(idle,&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">100</span><span style="background-color: #f5f5f5; color: #000000;">);<br />
}<br />
&nbsp;<br />
</span><span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;window.onload()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;timer&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;window.setTimeout(idle,&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">100</span><span style="background-color: #f5f5f5; color: #000000;">);<br />
}<br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">head</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;<br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">body</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
请求：</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">input&nbsp;</span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="text"</span><span style="color: #ff0000;">&nbsp;id</span><span style="color: #0000ff;">="request"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">input&nbsp;</span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="button"</span><span style="color: #ff0000;">&nbsp;value</span><span style="color: #0000ff;">="发送"</span><span style="color: #ff0000;">&nbsp;onclick</span><span style="color: #0000ff;">="sendRequest()"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;&lt;</span><span style="color: #800000;">br</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
回复：</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">div&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="response"</span><span style="color: #0000ff;">&gt;&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">iframe&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="alienFrame"</span><span style="color: #ff0000;">&nbsp;src</span><span style="color: #0000ff;">="http://domain2/TestCross.html"</span><span style="color: #0000ff;">&gt;&lt;/</span><span style="color: #800000;">iframe</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">body</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">html</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">&nbsp;&nbsp;<br />
<br />
2.&nbsp;http://domain2/TestCross.html:<br />
<br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">html</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">head</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">script&nbsp;</span><span style="color: #ff0000;">language</span><span style="color: #0000ff;">="javascript"</span><span style="color: #ff0000;">&nbsp;type</span><span style="color: #0000ff;">="text/javascript"</span><span style="color: #0000ff;">&gt;</span><span style="background-color: #f5f5f5; color: #000000;"><br />
</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;url&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">http://domain1/TestCross.html</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;"><br />
</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;oldHash&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">null</span><span style="background-color: #f5f5f5; color: #000000;">;<br />
</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;timer&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">null</span><span style="background-color: #f5f5f5; color: #000000;">;<br />
&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;getHash()&nbsp;<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;hash&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;window.location.hash;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">if</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;((hash.length&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">&gt;=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">1</span><span style="background-color: #f5f5f5; color: #000000;">)&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">&amp;&amp;</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;(hash.charAt(</span><span style="background-color: #f5f5f5; color: #000000;">0</span><span style="background-color: #f5f5f5; color: #000000;">)&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">==</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;'#'))&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hash&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;hash.substring(</span><span style="background-color: #f5f5f5; color: #000000;">1</span><span style="background-color: #f5f5f5; color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">return</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;hash;<br />
}<br />
&nbsp;<br />
</span><span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;sendRequest()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;d&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;document;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;t&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;d.getElementById('request');<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;f&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;parent;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000;">//</span><span style="background-color: #f5f5f5; color: #008000;">alert(f.document);&nbsp;//试着去掉这个注释，你会得到&#8220;Access&nbsp;is&nbsp;denied&#8221;</span><span style="background-color: #f5f5f5; color: #008000;"><br />
</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;f.location.href&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;url&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">+</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">#</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">+</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;t.value&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">+</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">&lt;br/&gt;</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">+</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">new</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;Date();<br />
}<br />
&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;setDivHtml(v)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;d&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;document;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;dv&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;d.getElementById('response');<br />
&nbsp;&nbsp;&nbsp;&nbsp;dv.innerHTML&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;v;<br />
}<br />
&nbsp;<br />
</span><span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;idle()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;newHash&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;getHash();&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff;">if</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;(newHash&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">!=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;oldHash)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setDivHtml(newHash);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oldHash&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;newHash;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;timer&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;window.setTimeout(idle,&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">100</span><span style="background-color: #f5f5f5; color: #000000;">);<br />
}<br />
&nbsp;<br />
</span><span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;window.onload()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;timer&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;">&nbsp;window.setTimeout(idle,&nbsp;</span><span style="background-color: #f5f5f5; color: #000000;">100</span><span style="background-color: #f5f5f5; color: #000000;">);<br />
}<br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">head</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;<br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">body</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">&nbsp;<br />
请求：</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">input&nbsp;</span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="text"</span><span style="color: #ff0000;">&nbsp;id</span><span style="color: #0000ff;">="request"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">input&nbsp;</span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="button"</span><span style="color: #ff0000;">&nbsp;value</span><span style="color: #0000ff;">="发送"</span><span style="color: #ff0000;">&nbsp;onclick</span><span style="color: #0000ff;">="sendRequest()"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;&lt;</span><span style="color: #800000;">br</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
回复：</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">div&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="response"</span><span style="color: #0000ff;">&gt;&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">&nbsp;<br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">body</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">html</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">&nbsp;<br />
<br />
两个网页基本相同，第一个网页内嵌一个&nbsp;IFRAME，在点击&#8220;发送&#8221;按钮后，会将文本框里的内容通过&nbsp;hash&nbsp;fragment&nbsp;传给&nbsp;IFRAME。点击&nbsp;IFRAME&nbsp;里的&#8220;发送&#8221;按钮后，它会将文本框里的内容通过&nbsp;hash&nbsp;fragment&nbsp;传给父窗口。因为是只改动了&nbsp;hash&nbsp;fragment，浏览器不会重新&nbsp;load&nbsp;网页内容，这里使用了一个计时器来检测&nbsp;URL&nbsp;变化，如果变化了，就更新其中一个&nbsp;div&nbsp;的内容&nbsp;。<br />
<br />
Case&nbsp;IV.&nbsp;用户本地转储方式&nbsp;(local)<br />
<br />
IE&nbsp;本身依附于&nbsp;Windows&nbsp;平台的特性为我们提供了一种基于&nbsp;iframe，利用内存来&#8220;绕行&#8221;的方案，即两个&nbsp;Window&nbsp;之间可以在客户端通过&nbsp;Windows&nbsp;剪贴板的方式进行数据传输，只需要在接受数据的一方设置&nbsp;Interval&nbsp;进行轮询，获得结果后清除&nbsp;Interval&nbsp;即可。FF&nbsp;的平台独立性决定了它不支持剪贴板这种方式，而以往版本的&nbsp;FF&nbsp;中存在的插件漏洞又被&nbsp;fixed&nbsp;了，所以&nbsp;FF&nbsp;无法通过内存来完成暗渡陈仓。而由于文件操作&nbsp;FF&nbsp;也没有提供支持（无法通过&nbsp;Cookie&nbsp;跨域完成数据传递），致使这种技巧性的方式只能在&nbsp;IE&nbsp;中使用。<br />
<br />
Case&nbsp;V:&nbsp;（其实还是在服务端&nbsp;A&nbsp;用&nbsp;iframe&nbsp;解决了与服务器&nbsp;B&nbsp;通信的问题）<br />
<br />
要解决的问题：发生在用户提交网页&nbsp;URL（还包括&nbsp;Tag,&nbsp;Notes&nbsp;等）给&nbsp;Bookmark&nbsp;服务器时。<br />
<br />
关于&nbsp;URL&nbsp;的提交至少可以有三种方式：&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;1.&nbsp;登陆&nbsp;Bookmark&nbsp;服务器的提交页面，将要收藏的&nbsp;URL&nbsp;通过该页面提交给服务器。<br />
&nbsp;&nbsp;&nbsp;2.&nbsp;安装浏览器插件，通过插件将&nbsp;URL&nbsp;提交给服务器。<br />
&nbsp;&nbsp;&nbsp;3.&nbsp;从&nbsp;Bookmark&nbsp;服务器动态加载&nbsp;javascript&nbsp;小工具到当前页面，通过它来完成提交工作。<br />
<br />
第一种方式开发起来最简单，但对用户来讲比较麻烦，每次都需要先登陆&nbsp;Bookmark&nbsp;服务器才能完成提交；第二种方式我并不熟悉插件开发，而且用户也不喜欢太多的插件堆满自己的浏览器；第三种方式开发难度小，又避免了每次登陆服务器的麻烦，所以最终采用它。第三种方式中动态加载的&nbsp;javascript&nbsp;小工具除了需要生成&nbsp;UI&nbsp;供用户填写信息（URL，tag，notes&nbsp;等），当用户点击提交的时候，还要完成与服务器通信的功能。<br />
<br />
跨域访问，简单来说就是&nbsp;A&nbsp;网站的&nbsp;javascript&nbsp;代码试图访问&nbsp;B&nbsp;网站，包括提交内容和获取内容。由于安全原因，跨域访问是被各大浏览器所默认禁止的。写过跨域访问&nbsp;ajax&nbsp;的朋友相信都遇到过被告知&#8220;没有权限&#8221;的情况。通过&nbsp;XMLHttp&nbsp;来发送数据给&nbsp;Bookmark&nbsp;服务器的尝试失败了。于是，看到网上的一些资料，我又开始尝试用&nbsp;javascript&nbsp;小工具在用户网页动态创建一个隐藏的&nbsp;iframe,&nbsp;iframe&nbsp;的&nbsp;src&nbsp;指向服务器的一个&nbsp;servlet&nbsp;，试图通过调用&nbsp;iframe&nbsp;中提供的&nbsp;javascript&nbsp;来完成与服务器的通信。但不幸的是，用户网页中的&nbsp;javascript&nbsp;代码访问&nbsp;iframe&nbsp;也被浏览器归为跨域访问（特指&nbsp;iframe&nbsp;的&nbsp;src&nbsp;指向其它网站的情形），尝试再次失败。<br />
<br />
最终，在一篇文章中看到，与&nbsp;iframe&nbsp;不同，如果&nbsp;A&nbsp;网站从&nbsp;B&nbsp;网站加载&nbsp;javascript&nbsp;，&nbsp;A&nbsp;网站可以自由的访问该&nbsp;javascript&nbsp;的内容，并不会被浏览器认为是跨域访问。模仿刚才&nbsp;iframe&nbsp;的思路，当用户点击提交时，可以动态创建一个&nbsp;javascript&nbsp;对象，该对象的&nbsp;src&nbsp;指向&nbsp;Bookmark&nbsp;服务器的一个&nbsp;servlet，注意：URL、Tag、Notes、User、Password&nbsp;等信息被作为&nbsp;src&nbsp;URL&nbsp;参数传给服务器。请看下面的代码：<br />
<br />
var&nbsp;url&nbsp;=&nbsp;"http://localhost:8080/Deeryard/BookmarkServlet?"&nbsp;+<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"url="&nbsp;+&nbsp;url_source&nbsp;+&nbsp;"&amp;"&nbsp;+&nbsp;"title="&nbsp;+&nbsp;title&nbsp;+&nbsp;"&amp;"&nbsp;+<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"tag="&nbsp;+&nbsp;tag&nbsp;+&nbsp;"&amp;"&nbsp;+&nbsp;"notes="&nbsp;+&nbsp;notes&nbsp;+&nbsp;"&amp;"&nbsp;+<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"user="&nbsp;+&nbsp;user&nbsp;+&nbsp;"&amp;"&nbsp;+&nbsp;"password="&nbsp;+&nbsp;password;&nbsp;<br />
&nbsp;<br />
url&nbsp;=&nbsp;encodeURI(url);&nbsp;<br />
&nbsp;<br />
//Submit&nbsp;to&nbsp;server&nbsp;with&nbsp;a&nbsp;trick&nbsp;<br />
var&nbsp;js_obj&nbsp;=&nbsp;document.createElement(&nbsp;"script"&nbsp;);&nbsp;<br />
js_obj.type&nbsp;=&nbsp;"text/javascript"&nbsp;;&nbsp;<br />
js_obj.setAttribute(&nbsp;"src"&nbsp;,&nbsp;url);&nbsp;<br />
&nbsp;<br />
//Get&nbsp;response&nbsp;from&nbsp;server&nbsp;by&nbsp;appending&nbsp;it&nbsp;to&nbsp;document&nbsp;<br />
document.body.appendChild(js_obj);<br />
<br />
上面例子中，&nbsp;js_obj.setArrribute()&nbsp;将信息作为&nbsp;src&nbsp;的&nbsp;URL&nbsp;参数提交给了&nbsp;Bookmark&nbsp;servlet&nbsp;。那么用户又如何取得服务器的响应信息呢？答案就是最末一行代码，&nbsp;servlet&nbsp;的输出必须是&nbsp;javascript&nbsp;代码，它可以调用用户网页上的其他&nbsp;javascript&nbsp;函数，以及操作&nbsp;dom&nbsp;对象。下面的&nbsp;servlet&nbsp;代码生成了一个&nbsp;javascript&nbsp;函数调用：<br />
<br />
out.write("onServerResponse(INADEQUATE_INFORMATION);");&nbsp;<br />
<br />
document.body.appendChild(js_obj)&nbsp;执行后&nbsp;onServerResponse(&nbsp;INADEQUATE_INFORMATION)&nbsp;就会得到执行，使客户网页响应服务器结果。这样一个完整的通信过程就完成了。<br />
<br />
CaseVI:Tomcat&nbsp;+&nbsp;PHP&nbsp;+&nbsp;HTML(含JS)(on&nbsp;Server&nbsp;A)<br />
<br />
服务器&nbsp;A&nbsp;上已经装好了&nbsp;Tomcat,&nbsp;我们写一个&nbsp;test.html(含JS)，再写一个&nbsp;PHP&nbsp;文件（由其来完成跨域通信要求）。<br />
<br />
更多，请参考：<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;https://www6.software.ibm.com/developerworks/cn/education/xml/x-ajaxtrans/index.html<br />
&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;http://www.xyhhxx.com/news/net/20061013121041.htm<br />
<br />
相关阅读<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;http://www-128.ibm.com/developerworks/library/x-securemashups/</span></div>
<br />
<br />
<img src ="http://www.blogjava.net/jelver/aggbug/346337.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2011-03-15 17:58 <a href="http://www.blogjava.net/jelver/articles/346337.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>javascript转换字符串为json对象的方法 </title><link>http://www.blogjava.net/jelver/articles/346182.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Mon, 14 Mar 2011 01:46:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/346182.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/346182.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/346182.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/346182.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/346182.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->JSON是一种便于操作使用的轻量级数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。具体介绍请查看：http://www.json.org。很多时候我们需要组装字符串为json...&nbsp;&nbsp;<a href='http://www.blogjava.net/jelver/articles/346182.html'>阅读全文</a><img src ="http://www.blogjava.net/jelver/aggbug/346182.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2011-03-14 09:46 <a href="http://www.blogjava.net/jelver/articles/346182.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Web 服务编程，REST 与 SOAP</title><link>http://www.blogjava.net/jelver/articles/331273.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Tue, 07 Sep 2010 01:12:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/331273.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/331273.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/331273.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/331273.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/331273.html</trackback:ping><description><![CDATA[原文：<a href="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/">http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/
</a><br />
<p><a name="2.REST 简介|outline">REST 简介</a></p>
<p>
在开始我们的正式讨论之前，让我们简单看一下 REST 的定义。</p>
<p>
REST（Representational State Transfer）是 Roy Fielding
提出的一个描述互联系统架构风格的名词。为什么称为 REST？Web 本质上由各种各样的资源组成，资源由 URI
唯一标识。浏览器（或者任何其它类似于浏览器的应用程序）将展示出该资源的一种表现方式，或者一种表现状态。如果用户在该页面中定向到指向其它资源的链
接，则将访问该资源，并表现出它的状态。这意味着客户端应用程序随着每个资源表现状态的不同而发生状态转移，也即所谓 REST。</p>
<p>关于 REST 本身，本文就不再这里过多地讨论，读者可以参考 developerWorks 上其它介绍 REST 的文章。本文的重点在于通过 REST 与 SOAP Web 服务的对比，帮助读者更深刻理解 REST 架构风格的特点，优势。
</p>
<br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" width="100%" height="1" /><br />
            <img alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" height="6" /></td>
        </tr>
    </tbody>
</table>
<table align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img src="http://www.ibm.com/i/c.gif" alt="" width="100%" height="4" /><br />
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" width="16" border="0" height="16" /><br />
                        </td>
                        <td valign="top" align="right"><a href="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="3.应用场景介绍（在线用户管理）|outline">应用场景介绍（在线用户管理）</a></p>
<p>
本文将借助于一个应用场景，通过基于 REST 和 SOAP Web 服务的不同实现，来对两者进行对比。该应用场景的业务逻辑会尽量保持简单且易于理解，以有助于把我们的重心放在 REST 和 SOAP Web 服务技术特质对比上。
</p>
<p><a name="3.1.需求描述|outline">需求描述</a></p>
<p>
这是一个在线的用户管理模块，负责用户信息的创建，修改，删除，查询。用户的信息主要包括：
</p>
<ul>
    <li>
    用户名（唯一标志在系统中的用户）</li>
    <li>
    头衔</li>
    <li>
    公司</li>
    <li>
    EMAIL</li>
    <li>
    描述</li>
</ul>
<p>
需求用例图如下：
</p>
<br />
<a name="3.1.1.图 1. 需求用例图 .|outline"><strong>图 1. 需求用例图</strong></a><br />
<img alt="REST" src="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/images/1.jpg" width="393" height="345" />
<br />
<p>如图 1 所示，客户端 1（Client1）与客户端 2（Client2）对于信息的存取具有不同的权限，客户端 1
可以执行所有的操作，而客户端 2 只被允许执行用户查询（Query User）与用户列表查询（Query User
List）。关于这一点，我们在对 REST Web 服务与 SOAP Web 服务安全控制对比时会具体谈到。下面我们将分别向您介绍如何使用
REST 和 SOAP 架构实现 Web 服务。</p>
<br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" width="100%" height="1" /><br />
            <img alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" height="6" /></td>
        </tr>
    </tbody>
</table>
<table align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img src="http://www.ibm.com/i/c.gif" alt="" width="100%" height="4" /><br />
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" width="16" border="0" height="16" /><br />
                        </td>
                        <td valign="top" align="right"><a href="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="4.使用 REST 实现 Web 服务|outline">使用 REST 实现 Web 服务</a></p>
<p>本部分将基于 Restlet 框架来实现该应用。Restlet 为那些要采用 REST 结构体系来构建应用程序的 Java 开发者提供了一个具体的解决方案。关于更多的 Restlet 相关内容，本文不做深入讨论，请见参考资源列表。</p>
<p><a name="4.1.设计|outline">设计</a></p>
<p>我们将采用遵循 REST 设计原则的 ROA（Resource-Oriented
Architecture，面向资源的体系架构）进行设计。ROA 是什么？简单点说，ROA 是一种把实际问题转换成 REST 式 Web
服务的方法，它使得 URI、HTTP 和 XML 具有跟其他 Web 应用一样的工作方式。</p>
<p>在使用 ROA 进行设计时，我们需要把真实的应用需求转化成 ROA 中的资源，基本上遵循以下的步骤：</p>
<ul>
    <li>
    分析应用需求中的数据集。</li>
    <li>
    映射数据集到 ROA 中的资源。</li>
    <li>
    对于每一资源，命名它的 URI。</li>
    <li>
    为每一资源设计其 Representations。</li>
    <li>
    用 hypermedia links 表述资源间的联系。</li>
</ul>
<p>接下来我们按照以上的步骤来设计本文的应用案例。</p>
<p>在线用户管理所涉及的数据集就是用户信息，如果映射到 ROA 资源，主要包括两类资源：用户及用户列表。用户资源的 URI 用 <code>http://localhost:8182/v1/users/{username}</code> 表示，用户列表资源的 URI 用 <code>http://localhost:8182/v1/users</code> 表示。它们的 Representation 如下，它们都采用了如清单 1 和清单 2 所示的 XML 表述方式。</p>
<br />
<a name="4.1.1.清单 1. 用户列表资源 Representation|outline"><strong>清单 1. 用户列表资源 Representation</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>				<br />
            &lt;?xml version="1.0" encoding="UTF-8" standalone="no"?&gt;<br />
            &lt;users&gt;<br />
            &lt;user&gt;<br />
            &lt;name&gt;tester&lt;/name&gt;<br />
            &lt;link&gt;http://localhost:8182/v1/users/tester&lt;/link&gt;<br />
            &lt;/user&gt;<br />
            &lt;user&gt;<br />
            &lt;name&gt;tester1&lt;/name&gt;<br />
            &lt;link&gt;http://localhost:8182/v1/users/tester1&lt;/link&gt;<br />
            &lt;/user&gt;<br />
            &lt;/users&gt;<br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<a name="4.1.2.清单 2. 用户资源 Representation|outline"><strong>清单 2. 用户资源 Representation</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>				<br />
            &lt;?xml version="1.0" encoding="UTF-8" standalone="no"?&gt;<br />
            &lt;user&gt;<br />
            &lt;name&gt;tester&lt;/name&gt;<br />
            &lt;title&gt;software engineer&lt;/title&gt;<br />
            &lt;company&gt;IBM&lt;/company&gt;<br />
            &lt;email&gt;tester@cn.ibm.com&lt;/email&gt;<br />
            &lt;description&gt;testing!&lt;/description&gt;<br />
            &lt;/user&gt;<br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>客户端通过 User List Resource 提供的 LINK 信息 ( 如 :<code>
&lt;link&gt;http://localhost:8182/v1/users/tester&lt;/link&gt;
</code>) 获得具体的某个 USER Resource。</p>
<p><a name="4.2.Restful Web 服务架构|outline">Restful Web 服务架构</a></p>
<p>首先给出 Web 服务使用 REST 风格实现的整体架构图，如下图所示：</p>
<br />
<a name="4.2.1.图 2. REST 实现架构|outline"><strong>图 2. REST 实现架构</strong></a><br />
<img alt="REST" src="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/images/2.jpg" width="540" height="553" />
<br />
<p>接下来，我们将基于该架构，使用 Restlet 给出应用的 RESTful Web 服务实现。</p>
<p>下面的章节中，我们将给出 REST Web 服务实现的核心代码片段。关于完整的代码清单，读者可以通过资源列表下载。</p>
<p><a name="4.3.客户端实现|outline">客户端实现</a></p>
<p>清单 3 给出的是客户端的核心实现部分，其主要由四部分组成：使用 HTTP PUT 增加、修改用户资源，使用 HTTP GET
得到某一具体用户资源，使用 HTTP DELETE 删除用户资源，使用 HTTP GET 得到用户列表资源。而这四部分也正对应了图 2
关于架构描述的四对 HTTP 消息来回。关于 UserRestHelper 类的完整实现，请读者参见本文所附的代码示例。</p>
<br />
<a name="4.3.1.清单 3. 客户端实现|outline"><strong>清单 3. 客户端实现</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>				<br />
            public class UserRestHelper {<br />
            //The root URI of our ROA implementation.<br />
            public static final tring <em>APPLICATION_URI</em> = "http://localhost:8182/v1";<br />
            <br />
            //Get the URI of user resource by user name. <br />
            private static String getUserUri(String name) {<br />
            return <em>APPLICATION_URI</em> + "/users/" + name;<br />
            }<br />
            <br />
            //Get the URI of user list resource.<br />
            private static String getUsersUri() {<br />
            return <em>APPLICATION_URI</em> + "/users";<br />
            }<br />
            //Delete user resource from server by user name.<br />
            //使用 HTTP DELETE 方法经由 URI 删除用户资源<br />
            public static void deleteFromServer(String name) {<br />
            Response response = new Client(Protocol.<em>HTTP</em>).delete(<em>getUserUri</em>(name));<br />
            &#8230;&#8230; <br />
            }<br />
            //Put user resource to server.<br />
            //使用 HTTP PUT 方法经由 URI 增加或者修改用户资源<br />
            public static void putToServer(User user) {<br />
            //Fill FORM using user data.<br />
            Form form = new Form();<br />
            form.add("user[title]", user.getTitle());<br />
            form.add("user[company]", user.getCompany());<br />
            form.add("user[email]", user.getEmail());<br />
            form.add("user[description]", user.getDescription());<br />
            Response putResponse = new Client(Protocol.<em>HTTP</em>).put(<br />
            <em>getUserUri</em>(user.getName()), form.getWebRepresentation());<br />
            &#8230;&#8230;<br />
            }<br />
            //Output user resource to console.<br />
            public static void printUser(String name) {<br />
            <em>printUserByURI</em>(<em>getUserUri</em>(name));<br />
            }<br />
            <br />
            //Output user list resource to console.<br />
            //使用 HTTP GET 方法经由 URI 显示用户列表资源<br />
            public static void printUserList() {<br />
            Response getResponse = new Client(Protocol.<em>HTTP</em>).get(<em>getUsersUri</em>());<br />
            if (getResponse.getStatus().isSuccess()) { <br />
            DomRepresentation result = getResponse.getEntityAsDom();<br />
            //The following code line will explore this XML document and output<br />
            //each user resource to console.<br />
            &#8230;&#8230;<br />
            } else { <br />
            System.<em>out</em>.println("Unexpected status:"+ getResponse.getStatus()); <br />
            }<br />
            }<br />
            <br />
            //Output user resource to console.<br />
            //使用 HTTP GET 方法经由 URI 显示用户资源<br />
            private static void printUserByURI(String uri) { <br />
            Response getResponse = new Client(Protocol.<em>HTTP</em>).get(uri);<br />
            if (getResponse.getStatus().isSuccess()) { <br />
            DomRepresentation result = getResponse.getEntityAsDom();<br />
            //The following code line will explore this XML document and output<br />
            //current user resource to console.<br />
            &#8230;&#8230;<br />
            } else { <br />
            System.<em>out</em>.println("unexpected status:"+ getResponse.getStatus()); <br />
            }<br />
            }<br />
            } <br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p><a name="4.4.服务器端实现|outline">服务器端实现</a></p>
<p>清单 4 给出的是服务器端对于用户资源类（UserResourc）的实现，其核心的功能是响应有关用户资源的 HTTP GET/PUT/DELETE 请求，而这些请求响应逻辑正对应了 UserRestHelper 类中关于用户资源类的 HTTP 请求。</p>
<br />
<a name="4.4.1.清单 4. 服务器端实现 |outline"><strong>清单 4. 服务器端实现</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>				<br />
            public class UserResource extends Resource {<br />
            private User _user;<br />
            private String _userName;<br />
            public UserResource(Context context, Request request, Response response) {<br />
            //Constructor is here.<br />
            &#8230;&#8230;<br />
            }<br />
            //响应 HTTP DELETE 请求逻辑<br />
            public void delete() {<br />
            // Remove the user from container.<br />
            getContainer().remove(_userName);<br />
            getResponse().setStatus(Status.SUCCESS_OK);<br />
            }<br />
            <br />
            //This method will be called by handleGet.<br />
            public Representation getRepresentation(Variant variant) {<br />
            Representation result = null;<br />
            if (variant.getMediaType().equals(MediaType.TEXT_XML)) {	<br />
            Document doc = createDocument(this._user);<br />
            result = new DomRepresentation(MediaType.TEXT_XML, doc);<br />
            }<br />
            return result;<br />
            }<br />
            //响应 HTTP PUT 请求逻辑。<br />
            public void put(Representation entity) {<br />
            if (getUser() == null) {<br />
            //The user doesn't exist, create it<br />
            setUser(new User());<br />
            getUser().setName(this._userName);<br />
            getResponse().setStatus(Status.SUCCESS_CREATED);<br />
            } else {<br />
            getResponse().setStatus(Status.SUCCESS_NO_CONTENT);<br />
            }<br />
            //Parse the entity as a Web form.<br />
            Form form = new Form(entity);<br />
            getUser().setTitle(form.getFirstValue("user[title]"));<br />
            getUser().setCompany(form.getFirstValue("user[company]"));<br />
            getUser().setEmail(form.getFirstValue("user[email]"));<br />
            getUser().setDescription(form.getFirstValue("user[description]")); <br />
            //Put the user to the container.<br />
            getApplication().getContainer().put(_userName, getUser()); <br />
            }<br />
            //响应 HTTP GET 请求逻辑。<br />
            public void handleGet() {<br />
            super.handleGet();<br />
            if(this._user != null ) {<br />
            getResponse().setEntity(getRepresentation(<br />
            new Variant(MediaType.TEXT_XML)));<br />
            getResponse().setStatus(Status.SUCCESS_OK);	<br />
            } else {<br />
            getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND);		<br />
            }<br />
            }<br />
            //build XML document for user resource.<br />
            private Document createDocument(User user) {<br />
            //The following code line will create XML document according to user info. <br />
            &#8230;&#8230;<br />
            }<br />
            //The remaining methods here<br />
            &#8230;&#8230;<br />
            }<br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>UserResource 类是对用户资源类的抽象，包括了对该资源的创建修改（put 方法），读取（handleGet 方法
）和删除（delete 方法），被创建出来的 UserResource 类实例被 Restlet 框架所托管，所有操纵资源的方法会在相应的
HTTP 请求到达后被自动回调。</p>
<p>另外，在服务端，还需要实现代表用户列表资源的资源类 UserListResource，它的实现与 UserResource
类似，响应 HTTP GET 请求，读取当前系统内的所有用户信息，形成如清单 1 所示的用户列表资源
Representation，然后返回该结果给客户端。具体的实现请读者参见本文所附的代码示例。 </p>
<br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" width="100%" height="1" /><br />
            <img alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" height="6" /></td>
        </tr>
    </tbody>
</table>
<table align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img src="http://www.ibm.com/i/c.gif" alt="" width="100%" height="4" /><br />
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" width="16" border="0" height="16" /><br />
                        </td>
                        <td valign="top" align="right"><a href="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="5.使用 SOAP 实现 Web 服务|outline">使用 SOAP 实现 Web 服务</a></p>
<p>本文对于 SOAP 实现，就不再像 REST 那样，具体到代码级别的实现。本节将主要通过 URI,HTTP 和 XML 来宏观上表述 SOAP Web 服务实现的技术本质，为下一节 REST Web 服务与 SOAP Web 服务的对比做铺垫。</p>
<p><a name="5.1.SOAP Web 服务架构|outline">SOAP Web 服务架构</a></p>
<p>同样，首先给出 SOAP 实现的整体架构图，如下图所示：</p>
<br />
<a name="5.1.1.图 3. SOAP 实现架构|outline"><strong>图 3. SOAP 实现架构</strong></a><br />
<img alt="REST" src="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/images/3.jpg" width="567" height="367" />
<br />
<p>可以看到，与 REST 架构相比，SOAP 架构图明显不同的是：所有的 SOAP 消息发送都使用 HTTP POST 方法，并且所有 SOAP 消息的 URI 都是一样的，这是基于 SOAP 的 Web 服务的基本实践特征。</p>
<p><a name="5.2.获得用户信息列表|outline">获得用户信息列表</a></p>
<p>基于 SOAP 的客户端创建如清单 5 所示的 SOAP XML 文档，它通过类 RPC 方式来获得用户列表信息。</p>
<br />
<a name="5.2.1.清单 5. getUserList SOAP 消息|outline"><strong>清单 5. getUserList SOAP 消息</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>				<br />
            &lt;?xml version="1.0" encoding="UTF-8" standalone="no"?&gt;<br />
            &lt;soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"&gt;<br />
            &lt;soap:Body&gt;<br />
            &lt;p:getUserList xmlns:p="http://www.exmaple.com"/&gt;<br />
            &lt;/soap:Body&gt;<br />
            &lt;/soap:Envelope&gt;<br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>客户端将使用 HTTP 的 POST 方法，将上述的 SOAP 消息发送至 <code>http://localhost:8182/v1/soap/servlet/messagerouter</code> URI，SOAP SERVER 收到该 HTTP POST 请求，通过解码 SOAP 消息确定需要调用 getUserList 方法完成该 WEB 服务调用，返回如下的响应：</p>
<br />
<a name="5.2.2.清单 6. getUserListResponse 消息|outline"><strong>清单 6. getUserListResponse 消息</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>				<br />
            &lt;?xml version="1.0" encoding="UTF-8" standalone="no"?&gt;<br />
            &lt;soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"&gt;<br />
            &lt;soap:Body&gt;<br />
            &lt;p:get<br />
            UserListResponse xmlns:p="http://www.exmaple.com"&gt;<br />
            &lt;Users&gt;<br />
            &lt;username&gt;tester&lt;username&gt;<br />
            &lt;username&gt;tester1&lt;username&gt;<br />
            ......<br />
            &lt;/Users&gt;<br />
            &lt;p: getUserListResponse &gt;<br />
            &lt;/soap:Body&gt;<br />
            &lt;/soap:Envelope&gt;<br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p><a name="5.3.获得某一具体用户信息|outline">获得某一具体用户信息</a></p>
<br />
<a name="5.3.1.清单 7. getUserByName SOAP 消息|outline"><strong>清单 7. getUserByName SOAP 消息</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>				<br />
            &lt;?xml version="1.0" encoding="UTF-8" standalone="no"?&gt;<br />
            &lt;soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"&gt;<br />
            &lt;soap:Body&gt;<br />
            &lt;p:getUserByName xmlns:p="http://www.exmaple.com"&gt;<br />
            &lt;username&gt;tester&lt;/username&gt;<br />
            &lt;/p:getUserByName &gt;<br />
            &lt;/soap:Body&gt;<br />
            &lt;/soap:Envelope&gt;<br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>同样地，客户端将使用 HTTP 的 POST 方法，将上述的 SOAP 消息发送至 <code>http://localhost:8182/v1/soap/servlet/messagerouter</code> URI，SOAP SERVER 处理后返回的 Response 如下：</p>
<br />
<a name="5.3.2.清单 8. getUserByNameResponse SOAP 消息|outline"><strong>清单 8. getUserByNameResponse SOAP 消息</strong></a><br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>
            <pre>				<br />
            &lt;?xml version="1.0" encoding="UTF-8" standalone="no"?&gt;<br />
            &lt;soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"&gt;<br />
            &lt;soap:Body&gt;<br />
            &lt;p:getUserByNameResponse xmlns:p="http://www.exmaple.com"&gt;<br />
            &lt;name&gt;tester&lt;/name&gt;<br />
            &lt;title&gt;software engineer&lt;/title&gt;<br />
            &lt;company&gt;IBM&lt;/company&gt;<br />
            &lt;email&gt;tester@cn.ibm.com&lt;/email&gt;<br />
            &lt;description&gt;testing!&lt;/description&gt;<br />
            &lt;/p:getUserByNameResponse&gt;<br />
            &lt;/soap:Body&gt;<br />
            &lt;/soap:Envelope&gt;<br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>实际上，创建新的用户，过程也比较类似，在这里，就不一一列出，因为这两个例子对于本文在选定的点上对比 REST 与 SOAP 已经足够了。</p>
<br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" width="100%" height="1" /><br />
            <img alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" height="6" /></td>
        </tr>
    </tbody>
</table>
<table align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img src="http://www.ibm.com/i/c.gif" alt="" width="100%" height="4" /><br />
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" width="16" border="0" height="16" /><br />
                        </td>
                        <td valign="top" align="right"><a href="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="6.REST 与 SOAP 比较|outline">REST 与 SOAP 比较</a></p>
<p>本节从以下几个方面来对比上面两节给出 REST 实现与 SOAP 实现。</p>
<p><a name="6.1.接口抽象|outline">接口抽象</a></p>
<p>RESTful Web 服务使用标准的 HTTP 方法 (GET/PUT/POST/DELETE) 来抽象所有 Web
系统的服务能力，而不同的是，SOAP 应用都通过定义自己个性化的接口方法来抽象 Web 服务，这更像我们经常谈到的 RPC。例如本例中的
getUserList 与 getUserByName 方法。</p>
<p>RESTful Web 服务使用标准的 HTTP 方法优势，从大的方面来讲：标准化的 HTTP 操作方法，结合其他的标准化技术，如
URI，HTML，XML 等，将会极大提高系统与系统之间整合的互操作能力。尤其在 Web 应用领域，RESTful Web
服务所表达的这种抽象能力更加贴近 Web 本身的工作方式，也更加自然。</p>
<p>同时，使用标准 HTTP 方法实现的 RRESTful Web 服务也带来了 HTTP 方法本身的一些优势：</p>
<ul>
    <li>
    <strong>
    <em>无状态性（Stateless）</em>
    </strong>
    </li>
</ul>
<p>HTTP 协议从本质上说是一种无状态的协议，客户端发出的 HTTP 请求之间可以相互隔离，不存在相互的状态依赖。基于 HTTP 的
ROA，以非常自然的方式来实现无状态服务请求处理逻辑。对于分布式的应用而言，任意给定的两个服务请求 Request 1 与 Request 2,
由于它们之间并没有相互之间的状态依赖，就不需要对它们进行相互协作处理，其结果是：Request 1 与 Request 2
可以在任何的服务器上执行，这样的应用很容易在服务器端支持负载平衡 (load-balance)。</p>
<ul>
    <li>
    <strong>
    <em>安全操作与幂指相等特性（Safety /Idempotence）</em>
    </strong>
    </li>
</ul>
<p>HTTP 的 GET、HEAD 请求本质上应该是安全的调用，即：GET、HEAD
调用不会有任何的副作用，不会造成服务器端状态的改变。对于服务器来说，客户端对某一 URI 做 n 次的 GET、HAED
调用，其状态与没有做调用是一样的，不会发生任何的改变。</p>
<p>HTTP 的 PUT、DELTE 调用，具有幂指相等特性 , 即：客户端对某一 URI 做 n 次的 PUT、DELTE 调用，其效果与做一次的调用是一样的。HTTP 的 GET、HEAD 方法也具有幂指相等特性。</p>
<p>HTTP 这些标准方法在原则上保证你的分布式系统具有这些特性，以帮助构建更加健壮的分布式系统。</p>
<p><a name="6.2.安全控制|outline">安全控制</a></p>
<p>为了说明问题，基于上面的在线用户管理系统，我们给定以下场景：</p>
<p>参考一开始我们给出的用例图，对于客户端 Client2，我们只希望它能以只读的方式访问 User 和 User List 资源，而 Client1 具有访问所有资源的所有权限。</p>
<p>如何做这样的安全控制？</p>
<p>通行的做法是：所有从客户端 Client2 发出的 HTTP 请求都经过代理服务器 (Proxy
Server)。代理服务器制定安全策略：所有经过该代理的访问 User 和 User List 资源的请求只具有读取权限，即：允许
GET/HEAD 操作，而像具有写权限的 PUT/DELTE 是不被允许的。</p>
<p>如果对于 REST，我们看看这样的安全策略是如何部署的。如下图所示：</p>
<br />
<a name="6.2.1.图 4. REST 与代理服务器 (Proxy Servers)|outline"><strong>图 4. REST 与代理服务器 (Proxy Servers)</strong></a><br />
<img alt="REST" src="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/images/4.jpg" width="547" height="187" />
<br />
<p>一般代理服务器的实现根据 (URI, HTTP Method) 两元组来决定 HTTP 请求的安全合法性。</p>
<p>当发现类似于（http://localhost:8182/v1/users/{username}，DELETE）这样的请求时，予以拒绝。</p>
<p>对于 SOAP，如果我们想借助于既有的代理服务器进行安全控制，会比较尴尬，如下图：</p>
<br />
<a name="6.2.2.图 5. SOAP 与代理服务器 (Proxy Servers)|outline"><strong>图 5. SOAP 与代理服务器 (Proxy Servers)</strong></a><br />
<img alt="REST" src="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/images/5.jpg" width="567" height="205" />
<br />
<p>所有的 SOAP 消息经过代理服务器，只能看到（<code>http://localhost:8182/v1/soap/servlet/messagerouter</code>,
HTTP POST）这样的信息，如果代理服务器想知道当前的 HTTP 请求具体做的是什么，必须对 SOAP
的消息体解码，这样的话，意味着要求第三方的代理服务器需要理解当前的 SOAP 消息语义，而这种 SOAP
应用与代理服务器之间的紧耦合关系是不合理的。</p>
<p><a name="6.3.关于缓存|outline">关于缓存</a></p>
<p>众所周知，对于基于网络的分布式应用，网络传输是一个影响应用性能的重要因素。如何使用缓存来节省网络传输带来的开销，这是每一个构建分布式网络应用的开发人员必须考虑的问题。</p>
<p>HTTP 协议带条件的 HTTP GET 请求 (Conditional GET)
被设计用来节省客户端与服务器之间网络传输带来的开销，这也给客户端实现 Cache 机制 ( 包括在客户端与服务器之间的任何代理 )
提供了可能。HTTP 协议通过 HTTP HEADER 域：If-Modified-Since/Last-
Modified，If-None-Match/ETag 实现带条件的 GET 请求。</p>
<p>REST 的应用可以充分地挖掘 HTTP 协议对缓存支持的能力。当客户端第一次发送 HTTP GET
请求给服务器获得内容后，该内容可能被缓存服务器 (Cache Server)
缓存。当下一次客户端请求同样的资源时，缓存可以直接给出响应，而不需要请求远程的服务器获得。而这一切对客户端来说都是透明的。</p>
<br />
<a name="6.3.1.图 6. REST 与缓存服务器 (Cache Server)|outline"><strong>图 6. REST 与缓存服务器 (Cache Server)</strong></a><br />
<img alt="REST" src="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/images/6.jpg" width="530" height="204" />
<br />
<p>而对于 SOAP，情况又是怎样的呢？</p>
<p>使用 HTTP 协议的 SOAP，由于其设计原则上并不像 REST 那样强调与 Web 的工作方式相一致，所以，基于 SOAP 应用很难充分发挥 HTTP 本身的缓存能力。</p>
<br />
<a name="6.3.2.图 7. SOAP 与缓存服务器 (Cache Server)|outline"><strong>图 7. SOAP 与缓存服务器 (Cache Server)</strong></a><br />
<img alt="REST" src="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/images/7.jpg" width="569" height="115" />
<br />
<p>两个因素决定了基于 SOAP 应用的缓存机制要远比 REST 复杂：</p>
<p>其一、所有经过缓存服务器的 SOAP 消息总是 HTTP POST，缓存服务器如果不解码 SOAP 消息体，没法知道该 HTTP 请求是否是想从服务器获得数据。</p>
<p>其二、SOAP 消息所使用的 URI 总是指向 SOAP 的服务器，如本文例子中的 <code>http://localhost:8182/v1/soap/servlet/messagerouter</code>，这并没有表达真实的资源 URI，其结果是缓存服务器根本不知道那个资源正在被请求，更不用谈进行缓存处理。</p>
<p><a name="6.4.关于连接性|outline">关于连接性</a></p>
<p>在一个纯的 SOAP 应用中，URI 本质上除了用来指示 SOAP 服务器外，本身没有任何意义。与 REST 的不同的是，无法通过 URI 驱动 SOAP 方法调用。例如在我们的例子中，当我们通过</p>
<p>getUserList SOAP 消息获得所有的用户列表后，仍然无法通过既有的信息得到某个具体的用户信息。唯一的方法只有通过
WSDL 的指示，通过调用 getUserByName 获得，getUserList 与 getUserByName 是彼此孤立的。</p>
<p>而对于 REST，情况是完全不同的：通过 <code>http://localhost:8182/v1/users</code> URI 获得用户列表，然后再通过用户列表中所提供的 LINK 属性，例如 <code>&lt;link&gt;http://localhost:8182/v1/users/tester&lt;/link&gt;</code>获得 tester 用户的用户信息。这样的工作方式，非常类似于你在浏览器的某个页面上点击某个 hyperlink, 浏览器帮你自动定向到你想访问的页面，并不依赖任何第三方的信息。</p>
<br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" width="100%" height="1" /><br />
            <img alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" height="6" /></td>
        </tr>
    </tbody>
</table>
<table align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img src="http://www.ibm.com/i/c.gif" alt="" width="100%" height="4" /><br />
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" width="16" border="0" height="16" /><br />
                        </td>
                        <td valign="top" align="right"><a href="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="7.总结|outline">总结</a></p>
<p>典型的基于 SOAP 的 Web 服务以操作为中心，每个操作接受 XML 文档作为输入，提供 XML
文档作为输出。在本质上讲，它们是 RPC 风格的。而在遵循 REST 原则的 ROA 应用中，服务是以资源为中心的，对每个资源的操作都是标准化的
HTTP 方法。</p>
<p>本文主要集中在以上的几个方面，对 SOAP 与 REST 进行了对比，可以看到，基于 REST 构建的系统其系统的扩展能力要强于
SOAP，这可以体现在它的统一接口抽象、代理服务器支持、缓存服务器支持等诸多方面。并且，伴随着 Web Site as Web Services
演进的趋势，基于 REST 设计和实现的简单性和强扩展性，有理由相信，REST 将会成为 Web 服务的一个重要架构实践领域。</p>
<br />
<br />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" width="100%" height="1" /><br />
            <img alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" height="6" /></td>
        </tr>
    </tbody>
</table>
<table align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img src="http://www.ibm.com/i/c.gif" alt="" width="100%" height="4" /><br />
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" width="16" border="0" height="16" /><br />
                        </td>
                        <td valign="top" align="right"><a href="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="download">下载</a></p>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <th scope="col">描述</th><th scope="col">名字</th><th scope="col">大小</th><th scope="col">下载方法</th>
        </tr>
        <tr>
            <th scope="row">本文代码示例</th>
            <td nowrap="nowrap">code_rest.zip</td>
            <td nowrap="nowrap">10 KB</td>
            <td nowrap="nowrap"><a onclick="sa_onclick(this.href)" onkeypress="sa_onclick(this.href)" href="http://download.boulder.ibm.com/ibmdl/pub/software/dw/cn/webservices/0907_Rest_WebservicesImpl/code_rest.zip"><strong>HTTP</strong></a></td>
        </tr>
    </tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr valign="top">
            <td colspan="5"><img alt="" src="http://www.ibm.com/i/c.gif" width="12" border="0" height="12" /></td>
        </tr>
        <tr>
            <td><img alt="" src="http://www.ibm.com/i/v14/icons/fw.gif" width="16" height="16" /></td>
            <td><a href="http://www.ibm.com/developerworks/cn/whichmethod.html">关于下载方法的信息</a></td>
            <td><img alt="" src="http://www.ibm.com/i/c.gif" width="50" height="1" /></td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="resources">参考资料 </a></p>
<ul>
    <li>
    <a href="http://www.ibm.com/developerworks/cn/webservices/">developerWorks SOA and Web services 专区</a>：为您提供了更多关于 SOA 和 Web 服务相关的最新技术文章、教程等资源。
    <br />
    <br />
    </li>
    <li>
    <a href="http://www.ibm.com/developerworks/cn/webservices/ws-restful/index.html">基于 REST 的 Web 服务：基础</a>：本文将向您介绍 REST 的基本原理。
    <br />
    <br />
    </li>
    <li>
    <a href="http://www.ibm.com/developerworks/cn/edu/j-dw-java-rest-i.html">构建 RESTful Web 服务</a>：本教程从 REST 的基本概念开始，逐步指导您使用 Restlet 框架构建应用程序。
    <br />
    <br />
    </li>
    <li>
    <a href="http://www.ibm.com/developerworks/cn/edu/x-dw-x-restatompp.html">编写 REST 服务</a>：本教程讨论了 REST 和 Atom 发布协议（Atom Publishing Protocol，APP）的概念，展示了其在服务中的应用，以及如何使用 Java 技术实现基于 REST/APP 的服务。
    <br />
    <br />
    </li>
    <li>
    阅读 Roy Fielding 的论文&#8220;<a href="http://www.ics.uci.edu/%7Efielding/pubs/dissertation/rest_arch_style.htm">Architectural Styles and the Design of Network-based Software Architectures</a>&#8221;的第 5 章。
    <br />
    <br />
    </li>
    <li>
    阅读图书<a href="http://www.oreilly.com/catalog/9780596529260/">基于 REST 的 Web 服务</a>。
    <br />
    <br />
    </li>
    <li>
    获得有关 <a href="ftp://ftp.isi.edu/in-notes/rfc2616.txt">RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1</a> 的更多信息。
    <br />
    <br />
    </li>
    <li>
    阅读<a href="http://www.restlet.org/documentation/">Restlet 开发文档</a>。
    <br />
    <br />
    </li>
    <li>
    <a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/0708_colonnese/0708_colonnese.html">基于 REST 的 Web 服务及其基于 Ajax 的客户端</a>：
    本文描述使用 WebSphere DataPower SOA Appliances 来实现 REST
    风格的软件系统的服务模式。这些模式将帮助加速 DataPower Appliances 的采用，并帮助架构师构建更灵活的软件系统，以及改进
    REST 风格软件服务的安全性和可伸缩性。
    <br />
    <br />
    </li>
    <li>
    <a href="http://www.ibm.com/developerworks/cn/xml/x-restfulsoa/index.html">使用 XML 实现 REST 式的 SOA</a>：本文描述使用 REST 这样的轻量型技术实现 SOA 的方法。
    <br />
    <br />
    </li>
    <li>
    <a href="http://www.ibm.com/developerworks/cn/webservices/ws-restwsdl/index.html">使用 WSDL 2.0 描述 REST Web 服务</a>：本文向您介绍 REST 和 WSDL 2.0，并指导您创建 REST Web 服务的 WSDL 2.0 描述。
    <br />
    <br />
    </li>
    <li>
    <a href="http://www.ibm.com/developerworks/cn/webservices/ws-soapojms/index.html">在 SOAP over JMS Web 服务中使用 WebSphere MQ，第 1 部分: 部署和配置 Web 服务</a>：本文介绍如何使用 WebSphere MQ 作为消息提供者，从而开发、部署和测试一个带 SOAP over JMS 绑定的示例 Web 服务。
    <br />
    <br />
    </li>
    <li>
    <a href="http://www.ibm.com/developerworks/cn/webservices/ws-complex/index.html">基于 SOAP 的 Web 服务中的复杂数据类型</a>：本文向 Java 开发人员展示如何通过 Axis 来使用复杂数据类型，包括 JavaBean 组件。
    <br />
    <br />
    </li>
    <li>
    <a href="http://www.ibm.com/developerworks/cn/webservices/ws-soapenc/index.html">发现 SOAP 编码对 Web 服务性能的影响</a>：本文描述了SOAP不同的编码选择并说明了每种编码选择所具有的性能和可靠性得失，以及用来在自己的环境中进行阶段测试的工具。
    <br />
    <br />
    </li>
    <li>
    <a href="http://www.ibm.com/developerworks/cn/webservices/ws-tip-extend/index.html">使用 SOAP 头扩展 JAX-RPC Web 服务</a>：本文介绍如何使用 JAX-RPC 1.0 SOAP 处理程序来处理 SOAP 1.1 头。
    </li>
</ul>
<br />
<a href="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/"><br />
</a><soap:envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:body>
<p:get userlistresponse="" xmlns:p="http://www.exmaple.com"><users><username><username></username></username></users></p:get>
</soap:body></soap:envelope></soap:envelope>
<img src ="http://www.blogjava.net/jelver/aggbug/331273.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2010-09-07 09:12 <a href="http://www.blogjava.net/jelver/articles/331273.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>身份证号码校验js脚本
</title><link>http://www.blogjava.net/jelver/articles/246441.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Mon, 15 Dec 2008 08:14:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/246441.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/246441.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/246441.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/246441.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/246441.html</trackback:ping><description><![CDATA[<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;"><br />
将这些代码保存在check.js的文件中<br />
<br />
function&nbsp;checkIdcard(idcard){<br />
var&nbsp;Errors=new&nbsp;Array(<br />
"身份证验证通过!",<br />
"身份证号码位数不对!",<br />
"身份证号码出生日期超出范围或含有非法字符!",<br />
"身份证号码校验错误!",<br />
"身份证地区非法!"<br />
);<br />
var&nbsp;area={11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江",31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外"}<br />
<br />
<br />
var&nbsp;idcard,Y,JYM;<br />
var&nbsp;S,M;<br />
var&nbsp;idcard_array&nbsp;=&nbsp;new&nbsp;Array();<br />
idcard_array&nbsp;=&nbsp;idcard.split("");<br />
//地区检验<br />
if(area[parseInt(idcard.substr(0,2))]==null)&nbsp;return&nbsp;Errors[4];<br />
//身份号码位数及格式检验<br />
switch(idcard.length){<br />
case&nbsp;15:<br />
if&nbsp;(&nbsp;(parseInt(idcard.substr(6,2))+1900)&nbsp;%&nbsp;4&nbsp;==&nbsp;0&nbsp;||&nbsp;((parseInt(idcard.substr(6,2))+1900)&nbsp;%&nbsp;100&nbsp;==&nbsp;0&nbsp;&amp;&amp;&nbsp;(parseInt(idcard.substr(6,2))+1900)&nbsp;%&nbsp;4&nbsp;==&nbsp;0&nbsp;)){<br />
ereg=/^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}$/;//测试出生日期的合法性<br />
}&nbsp;else&nbsp;{<br />
ereg=/^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}$/;//测试出生日期的合法性<br />
}<br />
if(ereg.test(idcard))&nbsp;return&nbsp;Errors[0];<br />
else&nbsp;return&nbsp;Errors[2];<br />
break;<br />
case&nbsp;18:<br />
//18位身份号码检测<br />
//出生日期的合法性检查<br />
//闰年月日:((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))<br />
//平年月日:((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))<br />
if&nbsp;(&nbsp;parseInt(idcard.substr(6,4))&nbsp;%&nbsp;4&nbsp;==&nbsp;0&nbsp;||&nbsp;(parseInt(idcard.substr(6,4))&nbsp;%&nbsp;100&nbsp;==&nbsp;0&nbsp;&amp;&amp;&nbsp;parseInt(idcard.substr(6,4))%4&nbsp;==&nbsp;0&nbsp;)){<br />
ereg=/^[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9Xx]$/;//闰年出生日期的合法性正则表达式<br />
}&nbsp;else&nbsp;{<br />
ereg=/^[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}[0-9Xx]$/;//平年出生日期的合法性正则表达式<br />
}<br />
if(ereg.test(idcard)){//测试出生日期的合法性<br />
//计算校验位<br />
S&nbsp;=&nbsp;(parseInt(idcard_array[0])&nbsp;+&nbsp;parseInt(idcard_array[10]))&nbsp;*&nbsp;7<br />
+&nbsp;(parseInt(idcard_array[1])&nbsp;+&nbsp;parseInt(idcard_array[11]))&nbsp;*&nbsp;9<br />
+&nbsp;(parseInt(idcard_array[2])&nbsp;+&nbsp;parseInt(idcard_array[12]))&nbsp;*&nbsp;10<br />
+&nbsp;(parseInt(idcard_array[3])&nbsp;+&nbsp;parseInt(idcard_array[13]))&nbsp;*&nbsp;5<br />
+&nbsp;(parseInt(idcard_array[4])&nbsp;+&nbsp;parseInt(idcard_array[14]))&nbsp;*&nbsp;8<br />
+&nbsp;(parseInt(idcard_array[5])&nbsp;+&nbsp;parseInt(idcard_array[15]))&nbsp;*&nbsp;4<br />
+&nbsp;(parseInt(idcard_array[6])&nbsp;+&nbsp;parseInt(idcard_array[16]))&nbsp;*&nbsp;2<br />
+&nbsp;parseInt(idcard_array[7])&nbsp;*&nbsp;1<br />
+&nbsp;parseInt(idcard_array[8])&nbsp;*&nbsp;6<br />
+&nbsp;parseInt(idcard_array[9])&nbsp;*&nbsp;3&nbsp;;<br />
Y&nbsp;=&nbsp;S&nbsp;%&nbsp;11;<br />
M&nbsp;=&nbsp;"F";<br />
JYM&nbsp;=&nbsp;"10X98765432";<br />
M&nbsp;=&nbsp;JYM.substr(Y,1);//判断校验位<br />
if(M&nbsp;==&nbsp;idcard_array[17])&nbsp;return&nbsp;Errors[0];&nbsp;//检测ID的校验位<br />
else&nbsp;return&nbsp;Errors[3];<br />
}<br />
else&nbsp;return&nbsp;Errors[2];<br />
break;<br />
default:<br />
return&nbsp;Errors[1];<br />
break;<br />
}<br />
<br />
}<br />
function&nbsp;check(obj){<br />
<br />
alert(checkIdcard(obj.value));<br />
<br />
}<br />
<br />
<br />
function&nbsp;dosubmit(){<br />
&nbsp;var&nbsp;i&nbsp;=&nbsp;checkIdcard(document.getElementById('character_id').value);<br />
&nbsp;&nbsp;&nbsp;if(i&nbsp;!=&nbsp;"身份证验证通过!"){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false;<br />
&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById('submit').submit;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;}<br />
<br />
<br />
下面是表单处的写法<br />
<br />
<br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">form&nbsp;</span><span style="color: #ff0000;">action</span><span style="color: #0000ff;">=""</span><span style="color: #ff0000;">&nbsp;method</span><span style="color: #0000ff;">="post"</span><span style="color: #ff0000;">&nbsp;name</span><span style="color: #0000ff;">="setICP"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">tr</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">td</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">中文名</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">td</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">td</span><span style="color: #0000ff;">&gt;&lt;</span><span style="color: #800000;">input&nbsp;</span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">='text'&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">='username_cn'&nbsp;</span><span style="color: #ff0000;">value</span><span style="color: #0000ff;">='&lt;%{$res2[list].user_name_cn&nbsp;</span><span style="color: #ff0000;">}%</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">'&nbsp;/&gt;&nbsp;您身份证上的名字</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">td</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">tr</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">tr</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">td</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">身份证号</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">td</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">td</span><span style="color: #0000ff;">&gt;&lt;</span><span style="color: #800000;">input&nbsp;</span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">='text'&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">='character_id'&nbsp;</span><span style="color: #ff0000;">value</span><span style="color: #0000ff;">='&lt;%{$res2[list].character_id&nbsp;</span><span style="color: #ff0000;">}%</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">'&nbsp;/&gt;&nbsp;您的身份证号码</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">td</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">tr</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">tr</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">td&nbsp;</span><span style="color: #ff0000;">colspan</span><span style="color: #0000ff;">="2"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">input&nbsp;</span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="submit"</span><span style="color: #ff0000;">&nbsp;name</span><span style="color: #0000ff;">="submit"</span><span style="color: #ff0000;">&nbsp;value</span><span style="color: #0000ff;">="提交"</span><span style="color: #ff0000;">&nbsp;onclick</span><span style="color: #0000ff;">="dosubmit()"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">td</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">tr</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">form</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<br />
<br />
<br />
还要记得在html文件头部引用那个js文件<br />
<br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">script&nbsp;</span><span style="color: #ff0000;">language</span><span style="color: #0000ff;">="JavaScript"</span><span style="color: #ff0000;">&nbsp;type</span><span style="color: #0000ff;">="text/javascript"</span><span style="color: #ff0000;">&nbsp;src</span><span style="color: #0000ff;">="/tpl/js/union_user_beian.js"</span><span style="color: #0000ff;">&gt;&lt;/</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span></div>
<img src ="http://www.blogjava.net/jelver/aggbug/246441.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2008-12-15 16:14 <a href="http://www.blogjava.net/jelver/articles/246441.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>应用HttpClient来对付各种顽固的WEB服务器(ZHUAN)</title><link>http://www.blogjava.net/jelver/articles/221076.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Sat, 09 Aug 2008 14:51:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/221076.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/221076.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/221076.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/221076.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/221076.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 应用HttpClient来对付各种顽固的WEB服务器2004年10月15日(星期五)&nbsp;13点50分&nbsp;作者:&nbsp;本站原创&nbsp;天气:&nbsp;&nbsp;心情:&nbsp;一般&nbsp;此文也是较早之前写的文章！------------------------------------------------------------------...&nbsp;&nbsp;<a href='http://www.blogjava.net/jelver/articles/221076.html'>阅读全文</a><img src ="http://www.blogjava.net/jelver/aggbug/221076.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2008-08-09 22:51 <a href="http://www.blogjava.net/jelver/articles/221076.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDK tomcat Axis的安装使用（转）</title><link>http://www.blogjava.net/jelver/articles/167230.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Wed, 12 Dec 2007 06:42:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/167230.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/167230.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/167230.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/167230.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/167230.html</trackback:ping><description><![CDATA[<p><br />
一.简介<br />
什么是SOAP?SOAP是一个应用程序间的基于XML的通信工具和规范.SOAP最初由MicroSoft和Userland公司开发,已经演化了好几个版本,当前的版本SOAP1.1正飞速发展.W3C的XML协议工作组正努力把它发展为一个真正的开发的标准.SOAP1.2草案已经发布,它能澄清 1.1版规范的容易混淆的地方.</p>
<p>什么是Axis?Axis总体上是一个SOAP引擎,但又不仅仅是个引擎,它还:1)是一个简单的独立的服务器2)是一个可插入到servlet引擎(如Tomcat)中的服务3)可扩展的支持WSDL4)能根据WSDL产生JAVA文件/类5)包括一些例子程序6)包括一个可以监控TCP/IP包的工具</p>
<p>Axis起源于IBM的SOAP4J,是Apache SOAP的第三代产品,相对于以前的版本,它有如下特性:1)快速,它使用了基于事件的SAX解析机制.2)灵活,用户可以灵活定制扩展.3)稳定,接口将会变动很小.4)基于组件开发.5)支持WSDL1.1</p>
<p>二.准备<br />
应用Axis开发Web Services，你需要安装如下软件：<br />
1.jdk1.5<br />
2.安装Tomcat5.0.28,这是当前稳定版本.Tomcat运行在80端口.访问<a href="http://localhost/8080">http://localhost/8080</a>检查Tomcat是否安装成功.<br />
3.下载AXIS:<br />
官方站点:http://xml.apache.org/axis/index.html<br />
下载软件:axis-bin-1_2_1.tar.gz<br />
4.下载相关包:<br />
a.mail.jar 下载地址:http://java.sun.com/products/javamail<br />
b.activation.jar 下载地址:http://java.sun.com/products/javabeans/glasgow/jaf.html<br />
c.xerces.jar 下载地址:http://xml.apache.org/xerces-j/index.html<br />
d.xmlsec-1.2.1.jar 下载地址:http://xml.apache.org/security/</p>
<p>三.安装<br />
1.将jdk1.5.0_04安装在D:\jdk1.5.0_04下(当然安装路径可任意选)好后，环境变量配置如下：<br />
JAVA_HOME=D:\jdk1.5.0_04<br />
CLASSPATH=.;D:\jdk1.5.0_04\jre\lib\rt.jar;D:\jdk1.5.0_04\jre\lib\tools.jar<br />
Path=D:\jdk1.5.0_04\bin<br />
2.tomcat-5.0.28安装在D:\tomcat-5.0.28下(安装路径可任选)好后，环境变量配置如下：<br />
CATALINA_BASE=D:\tomcat-5.0.28<br />
CATALINA_HOME=D:\tomcat-5.0.28<br />
3.axis的安装<br />
a.将下载的Axis软件包解压缩，将其中的&#8220;webapps&#8221;目录下的&#8220;axis&#8221;目录整个拷贝到Tomcat安装目录下的&#8220;webapps&#8221;目录下。<br />
b.将mail.jar、activation.jar、xerces.jar、xmlsec-1.2.1.jar四个包,全部拷到D:\tomcat-5.0.28\webapps\axis\WEB-INF\lib下<br />
c.环境变量配置<br />
AXIS_HOME=D:\tomcat-5.0.28</p>
<p>AXIS_LIB=%AXIS_HOME%\WEB-INF\lib<br />
AXISCLASSPATH=%AXIS_LIB%\activation.jar;%AXIS_LIB%\axis.jar;%AXIS_LIB%\axis-ant.jar;%AXIS_LIB%\commons-discovery-0.2.jar;%AXIS_LIB%\commons-logging-1.0.4.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\saaj.jar;%AXIS_LIB%\log4j-1.2.8.jar;AXIS_LIB%\xml-apis.jar;%AXIS_LIB%\xercesImpl.jar;%AXIS_LIB%\mail.jar;AXIS_LIB%\wsdl4j-1.5.1.jar;%AXIS_LIB%\xerces.jar;%AXIS_LIB%\xmlsec-1.2.1.jar</p>
<p>CLASSPATH=%AXIS_HOME%\WEB-INF\lib<br />
AXISCLASSPATH=%AXIS_LIB%\activation.jar;%AXIS_LIB%\axis.jar;%AXIS_LIB%\axis-ant.jar;%AXIS_LIB%\commons-discovery-0.2.jar;%AXIS_LIB%\commons-logging-1.0.4.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\saaj.jar;%AXIS_LIB%\log4j-1.2.8.jar;AXIS_LIB%\xml-apis.jar;%AXIS_LIB%\xercesImpl.jar;%AXIS_LIB%\mail.jar;AXIS_LIB%\wsdl4j-1.5.1.jar;%AXIS_LIB%\xerces.jar;%AXIS_LIB%\xmlsec-1.2.1.jar<br />
这里有几点需要注意：中间不要有空格，包的名字可能有不同的版本，这时需要修改一下包名。</p>
<p>四.测试<br />
安装配置完毕后，应测试一下是否tomcat、Axis可以正确运行了。<br />
启动Tomcat服务器，在浏览器中访问<a href="http://localhost:8080/axis/happyaxis.jsp">http://localhost:8080/axis/happyaxis.jsp</a>，如果页面显示有错误，则需要回头检查一下相关配置是否正确，如果浏览页面能正确显示出系统组件、属性等参数配置信息，则表示安装成功。现在可以开始开发你的Web Services应用了。　</p>
<p>五、服务的发布<br />
Axis提供了两种服务发布方式，一种是即时发布（Instant Deployment），一种是定制发布（Custom Deployment）。</p>
<p>1. 使用即时发布 Java Web Service(JWS)</p>
<p>　　对即时发布的支持是Axis的特色之一，使用即时发布使用户只需有提供服务的Java类的源代码，即可将其迅速发布成Web服务。每当用户调用这类服务的时候，Axis会自动进行编译，即使服务器重启了也不必对其做任何处理，使用非常简单快捷。</p>
<p>　　使用即时发布首先需要一个实现服务功能的Java源文件，将其扩展名改为.jws（Java Web Service的缩写），然后将该文件放到&#8220;&#8230;&#8230;\webapps\axis&#8221;目录下即可。<br />
&nbsp;在此给出一个HelloWorld程序，其源码如下：</p>
<p>HelloWorld.java</p>
<p>public class HelloWorld {<br />
&nbsp; public String sayHello()<br />
&nbsp; {<br />
&nbsp;&nbsp;&nbsp; return "HELLO WORLD!"; <br />
&nbsp; } <br />
}</p>
<p><br />
将其放到&#8220;&#8230;&#8230;\webapps\axis&#8221;目录，通过访问<a href="http://localhost:8080/axis/HelloWorld.jws?wsdl">http://localhost:8080/axis/HelloWorld.jws?wsdl</a>可以看到这个服务的WSDL描述文件，这说明HelloWorld服务被成功发布了。<br />
现在写个客户端程序访问一下：</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #008080">&nbsp;1</span><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">TestClient.java<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;org.apache.axis.client.Call;<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;org.apache.axis.client.Service;<br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;javax.xml.rpc.ParameterMode;<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;TestClient<br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img id="Codehighlighter1_154_747_Open_Image" onclick="this.style.display='none'; Codehighlighter1_154_747_Open_Text.style.display='none'; Codehighlighter1_154_747_Closed_Image.style.display='inline'; Codehighlighter1_154_747_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_154_747_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_154_747_Closed_Text.style.display='none'; Codehighlighter1_154_747_Open_Image.style.display='inline'; Codehighlighter1_154_747_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_154_747_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_154_747_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img id="Codehighlighter1_216_745_Open_Image" onclick="this.style.display='none'; Codehighlighter1_216_745_Open_Text.style.display='none'; Codehighlighter1_216_745_Closed_Image.style.display='inline'; Codehighlighter1_216_745_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_216_745_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_216_745_Closed_Text.style.display='none'; Codehighlighter1_216_745_Open_Image.style.display='inline'; Codehighlighter1_216_745_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;main(String&nbsp;[]&nbsp;args)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;Exception&nbsp;</span><span id="Codehighlighter1_216_745_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_216_745_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;endpoint&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">http://localhost:</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">"</span><span style="color: #000000">8080</span><span style="color: #000000">"</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">/axis/HelloWorld.jws</span><span style="color: #000000">"</span><span style="color: #000000">;</span><span style="color: #008000">//</span><span style="color: #008000">指明服务所在位置</span><span style="color: #008000"><br />
</span><span style="color: #008080">13</span><span style="color: #008000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000"><br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Service&nbsp;&nbsp;service&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Service();&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">创建一个Service实例，注意是必须的！</span><span style="color: #008000"><br />
</span><span style="color: #008080">15</span><span style="color: #008000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(Call)&nbsp;service.createCall();</span><span style="color: #008000">//</span><span style="color: #008000">创建Call实例，也是必须的！</span><span style="color: #008000"><br />
</span><span style="color: #008080">16</span><span style="color: #008000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000"><br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call.setTargetEndpointAddress(&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;java.net.URL(endpoint)&nbsp;);</span><span style="color: #008000">//</span><span style="color: #008000">为Call设置服务的位置</span><span style="color: #008000"><br />
</span><span style="color: #008080">18</span><span style="color: #008000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000"><br />
</span><span style="color: #008080">19</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call.setOperationName(&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">sayHello</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;);</span><span style="color: #008000">//</span><span style="color: #008000">注意方法名与HelloWorld.java中一样！！</span><span style="color: #008000"><br />
</span><span style="color: #008080">20</span><span style="color: #008000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000"><br />
</span><span style="color: #008080">21</span><span style="color: #000000"><img id="Codehighlighter1_666_667_Open_Image" onclick="this.style.display='none'; Codehighlighter1_666_667_Open_Text.style.display='none'; Codehighlighter1_666_667_Closed_Image.style.display='inline'; Codehighlighter1_666_667_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_666_667_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_666_667_Closed_Text.style.display='none'; Codehighlighter1_666_667_Open_Image.style.display='inline'; Codehighlighter1_666_667_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;res&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(String)&nbsp;call.invoke(&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Object[]&nbsp;</span><span id="Codehighlighter1_666_667_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_666_667_Open_Text"><span style="color: #000000">{}</span></span><span style="color: #000000">&nbsp;);</span><span style="color: #008000">//</span><span style="color: #008000">返回String，没有传入参数</span><span style="color: #008000"><br />
</span><span style="color: #008080">22</span><span style="color: #008000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000"><br />
</span><span style="color: #008080">23</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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;System.out.println(&nbsp;res&nbsp;);<br />
</span><span style="color: #008080">24</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">25</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">26</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<p>&nbsp;</p>
<p><br />
下面我们介绍第二种发布方式，这是常用的。</p>
<p>我们的第二种发布方式：<br />
1、将HelloWorld.java编译成HelloWorld.class,放到%TOMCAT_HOME%\webapps\axis\WEB-INF\classes</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下</p>
<p>2、在%TOMCAT_HOME%\webapps\axis\WEB-INF下新建deploy.wsdd文件，即SOAP服务发布描述文件</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; deploy.wsdd</p>
<p>&lt;deployment xmlns="<a href="http://xml.apache.org/axis/wsdd/">http://xml.apache.org/axis/wsdd/</a>" xmlns:java="<a href="http://xml.apache.org/axis/wsdd/providers/java">http://xml.apache.org/axis/wsdd/providers/java</a>"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;service name="HelloWorld" provider="java:RPC"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter name="className" value="HelloWorld"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter name="allowedMethods" value="sayHello"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/service&gt;<br />
&lt;/deployment&gt;</p>
<p>在DOS下转换目录到%TOMCAT_HOME%\webapps\axis\WEB-INF，命令：<br />
java org.apache.axis.client.AdminClient deploy.wsdd 后会出现</p>
<p>Processing file deploy.wsdd<br />
&lt;Admin&gt;Done processing&lt;/Admin&gt;</p>
<p>这时你会发现目录下多了一个server-config.wsdd文件，这就是AXIS的配置文件，以后所有的服务发布描述都会在里面找到。（当然，你可以直接修改它，不用再写deploy.wsdd）然后打开浏览器<a href="http://localhost:8080/axis/services/HelloWorld?wsdl">http://localhost:8080/axis/services/HelloWorld?wsdl</a>，你就会看到你的服务已发布</p>
<p>同样用客户端程序访问一下：（注意和上边的差别！！）</p>
<p>&nbsp;</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #008080">&nbsp;1</span><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">HelloClient.java<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;org.apache.axis.client.Call;<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;org.apache.axis.client.Service;<br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;HelloClient<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img id="Codehighlighter1_119_613_Open_Image" onclick="this.style.display='none'; Codehighlighter1_119_613_Open_Text.style.display='none'; Codehighlighter1_119_613_Closed_Image.style.display='inline'; Codehighlighter1_119_613_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_119_613_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_119_613_Closed_Text.style.display='none'; Codehighlighter1_119_613_Open_Image.style.display='inline'; Codehighlighter1_119_613_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_119_613_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_119_613_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img id="Codehighlighter1_181_611_Open_Image" onclick="this.style.display='none'; Codehighlighter1_181_611_Open_Text.style.display='none'; Codehighlighter1_181_611_Closed_Image.style.display='inline'; Codehighlighter1_181_611_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_181_611_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_181_611_Closed_Text.style.display='none'; Codehighlighter1_181_611_Open_Image.style.display='inline'; Codehighlighter1_181_611_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;main(String&nbsp;[]&nbsp;args)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;Exception&nbsp;</span><span id="Codehighlighter1_181_611_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_181_611_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;endpoint&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">http://localhost:</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">"</span><span style="color: #000000">8080</span><span style="color: #000000">"</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">/axis/services/HelloWorld</span><span style="color: #000000">"</span><span style="color: #000000">;</span><span style="color: #008000">//</span><span style="color: #008000">注意！差别仅仅在这里！！</span><span style="color: #008000"><br />
</span><span style="color: #008080">11</span><span style="color: #008000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000"><br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Service&nbsp;&nbsp;service&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Service();<br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(Call)&nbsp;service.createCall();<br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call.setTargetEndpointAddress(&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;java.net.URL(endpoint)&nbsp;);<br />
</span><span style="color: #008080">15</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call.setOperationName(</span><span style="color: #000000">"</span><span style="color: #000000">sayHello</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;&nbsp;);<br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img id="Codehighlighter1_549_550_Open_Image" onclick="this.style.display='none'; Codehighlighter1_549_550_Open_Text.style.display='none'; Codehighlighter1_549_550_Closed_Image.style.display='inline'; Codehighlighter1_549_550_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_549_550_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_549_550_Closed_Text.style.display='none'; Codehighlighter1_549_550_Open_Image.style.display='inline'; Codehighlighter1_549_550_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;res&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(String)&nbsp;call.invoke(&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Object[]&nbsp;</span><span id="Codehighlighter1_549_550_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_549_550_Open_Text"><span style="color: #000000">{}</span></span><span style="color: #000000">&nbsp;);<br />
</span><span style="color: #008080">18</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
</span><span style="color: #008080">19</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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;System.out.println(&nbsp;res&nbsp;);<br />
</span><span style="color: #008080">20</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">21</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">22</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<p>&nbsp;</p>
<p>五.总结</p>
<p>　　Web Services是未来网络应用的发展方向，SOAP和WSDL是Web Services的核心协议，Axis给出了一个很好的SOAP实现，它使得开发Web Services应用变得轻松而有趣。</p>
<img src ="http://www.blogjava.net/jelver/aggbug/167230.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2007-12-12 14:42 <a href="http://www.blogjava.net/jelver/articles/167230.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SOAP中复杂类型(JavaBean)调用实例实践（转）</title><link>http://www.blogjava.net/jelver/articles/167189.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Wed, 12 Dec 2007 04:14:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/167189.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/167189.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/167189.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/167189.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/167189.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;1SOAP中复杂类型(JavaBean)调用实例实践&nbsp;&nbsp;2&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;5使用工具：axis-1_1&nbsp;&nbsp;6&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&...&nbsp;&nbsp;<a href='http://www.blogjava.net/jelver/articles/167189.html'>阅读全文</a><img src ="http://www.blogjava.net/jelver/aggbug/167189.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2007-12-12 12:14 <a href="http://www.blogjava.net/jelver/articles/167189.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用ant与jmeter实现负载测试自动化（转贴）</title><link>http://www.blogjava.net/jelver/articles/146111.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Tue, 18 Sep 2007 03:49:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/146111.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/146111.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/146111.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/146111.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/146111.html</trackback:ping><description><![CDATA[&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;&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;&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://blog.csdn.net/lemonfamily/archive/2007/05/17/1612826.aspx"><span><span>原贴地址：http://blog.csdn.net/lemonfamily/archive/2007/05/17/1612826.aspx</span></span></a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 性能测试一直以来都是测试领域一个令人争议的话题。测试的参考标准、评判依据及测试的方法选择都很难有一个统一的说法。但无论如何，对于需要能够承受一定压力而运行的程序来说，进行其进行功能和性能测试是一个必不可少的过程。<br />
工欲善其事，必先利其器。性能测试，很必要的准备是要利用工具简化测试的繁杂程度。减轻人工操作的负担。在下面的例子中，我们将会用到下面几个软件：<br />
Eclipse 3.2<span>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;java IDE</span>，对ant的强力支持，非常方便我们利用ant的task与target功能实现测试的自动化。<br />
Ant1.7<span>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>一个强大的构建脚本工具，在需要进行批处理操作或多任务时，非常有用。<a href="http://ant.apache.org/"><span><span>下载地址</span></span></a><br />
Jakarta-jmeter 2.1 &nbsp;100%用java实现的性能测试工具，原来目的是用于web的压力测试，目前已经可以用于测试静态或者动态资源的性能 包括java桌面应用程序、文件、数据库等。目前已经有更新的版本可用。<a href="http://jakarta.apache.org/site/downloads/downloads_jmeter.cgi"><span><span>下载地址</span></span></a><br />
Badboy 2.0<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>一个非常不错的脚本录制工具，支持导出jemter的jmx格式。虽然功能不如loadrunner和winrunner强大，但如果只用于录制动作脚本，那么已经足够了。<a href="http://www.badboy.com.au/"><span><span>官方网站</span></span></a><span><br />
</span><br />
下面以个简单的web程序的负载测试的实现流程介绍如何使用ant 与jmeter实现负载测试自动化的。<br />
&nbsp;&nbsp;一、<span>&nbsp;&nbsp; </span>利用badboy录制一段脚本，该脚本包含了所需进行负载测试的url段以及请求数据。</div>
<div style="text-indent: 21.75pt"><img height="457" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/lemonfamily/878d380d0d4c4c47868e71e2926be2bf.png" width="750" />&nbsp;<br />
<br />
然后利用 &#8221;File&#8221;-&gt;&#8221;Export to Jmeter&#8230;&#8221;导出jmx。<br />
二、<span>&nbsp;&nbsp;&nbsp; </span>运行jmeter。打开刚才的jmx。对其进行一定的编辑。<img height="549" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/lemonfamily/c85247d9e0dd437eabc12025ed5dbffc.png" width="750" /><br />
<br />
我们计划要对登陆进行测试，则可以在该请求的节点上加上循环控制器：<img height="549" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/lemonfamily/505e9db6d80348e3b6c5e6b975ab632c.png" width="750" /><br />
<br />
运行无误后，取消掉监视器。保存该脚本<br />
三、打开eclipse，先建一个java工程用于运行ant脚本。<br />
在jmeter的安装目录的extras文件夹下有个示例的ant运行脚本以及一个演示教程的html文档。我们直接copy这个build.xml到eclipse的新建工程目录下。利用&#8221;Windows&#8221;<span>--&gt;</span>&#8221;Show View&#8221;<span>--&gt;</span>&#8221;Other&#8221;<span>--&gt;</span>&#8221;Ant&#8221;打开ant控制面板。通过&#8221;Add Buildfiles&#8221;按钮将该build.xml添加进去。<br />
因为示例的脚本使用相对目录.，我们需要修改一下这个build.xml使得ant可以找到所指定的资源。在我的jmeter版本中，有个小的错误需要修改，原文件多打了个x：&nbsp;</div>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="568"><span style="font-size: 10pt; color: navy">&lt;property </span><span style="font-size: 10pt; color: navy">name=</span><span style="font-size: 10pt; color: green">"jmeter.save.saveservice.bytes" </span><span style="font-size: 10pt; color: navy">value=</span><span style="font-size: 10pt; color: green">"true"</span><span style="font-size: 10pt; color: navy">/&gt;</span></td>
        </tr>
    </tbody>
</table>
<div style="text-indent: 21.75pt"><img height="459" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/lemonfamily/1d08f6d391484717983d342bd773e646.png" width="750" />&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 运行脚本成功后，会在指定的目录下生成一个html文档：&nbsp; <img height="459" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/lemonfamily/69d392cc28c849b5a163c28ca9e7d2a5.png" width="750" /><br />
<br />
&nbsp;小提示：如果每次运行脚本不删除先前的jtl文件，则报告内容会把以前的测试结果保留下来。<br /><img src ="http://www.blogjava.net/jelver/aggbug/146111.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2007-09-18 11:49 <a href="http://www.blogjava.net/jelver/articles/146111.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ajax资料收集-Ajax文章(教程和实例)</title><link>http://www.blogjava.net/jelver/articles/87049.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Mon, 11 Dec 2006 12:42:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/87049.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/87049.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/87049.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/87049.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/87049.html</trackback:ping><description><![CDATA[作者tag:<a href="http://tag.csdn.net/tag/ajax/1.html" target="_blank">ajax</a> <a href="http://tag.csdn.net/tag/web开发(脚本和动态语言)/1.html" target="_blank">web开发(脚本和动态语言)</a> <a href="http://tag.csdn.net/tag/ajax资料收集-ajax文章(教程和实例)---ajax资源下载(源码和教程)---ajax规范标准/1.html" target="_blank">ajax资料收集-ajax文章(教程和实例)---ajax资源下载(源码和教程)---ajax规范标准</a> CSDN 推荐tag:<a href="http://tag.csdn.net/tag/.net/1.html" target="_blank">.net</a> <a href="http://tag.csdn.net/tag/asp.net/1.html" target="_blank">asp.net</a> <a href="http://tag.csdn.net/tag/w3c/1.html" target="_blank">w3c</a> <a href="http://tag.csdn.net/tag/web2.0/1.html" target="_blank">web2.0</a> <a href="http://tag.csdn.net/tag/教程/1.html" target="_blank">教程</a> <a href="http://tag.csdn.net/tag/资源/1.html" target="_blank">资源</a>  
<div style="CLEAR: both"></div><script><![CDATA[unction StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}]]&gt;</script><div class="post"><div class="postTitle"><a href="http://blog.csdn.net/dshpsky/archive/2006/11/27/1416612.aspx"><img height="13" src="http://blog.csdn.net/images/authorship.gif" width="15" border="0" /> ajax资料收集-Ajax文章(教程和实例)---Ajax资源下载(源码和教程)---Ajax规范标准</a></div><div class="postText"><div class="tit"><br /></div><div class="date"><br /></div><table style="TABLE-LAYOUT: fixed"><tbody><tr><td><div class="cnt"><p>CSDN Blog Ajax文章搜索：<br /><a href="http://search.csdn.net/search/ajax/1/blog/">http://search.csdn.net/search/ajax/1/blog/</a><br /><br />专题：Ajax技术应用开发<br /><a href="http://www.51cto.com/html/2005/1121/11736.htm">http://www.51cto.com/html/2005/1121/11736.htm</a><br /><br /><a href="http://www.edufans.com/html/Ajax/">http://www.edufans.com/html/Ajax/</a><br /><a class="menubar" title="Ajax教程文章数：0" href="http://www.edufans.com/html/Ajax/Ajax_tech/"><font color="#810081">Ajax教程</font></a>  <br /><a class="menubar" title="Ajax技巧文章数：43" href="http://www.edufans.com/html/Ajax/Ajax_skills/"><font color="#810081">Ajax技巧</font></a><br /><a class="menubar" title="Ajax实例文章数：0" href="http://www.edufans.com/html/Ajax/Ajax_example/"><font color="#810081">Ajax实例</font></a><br /><a class="menubar" title="Ajax下载文章数：4" href="http://www.edufans.com/html/Ajax/Ajax_down/"><font color="#810081">Ajax下载</font></a><br /><br /><font color="#000000">++++++++++++++++++++++++++++++++++++++++++++++++++++++++</font><br />ajax联盟：资源下载<br /><a href="http://www.ajaxw3c.com/resource.html">http://www.ajaxw3c.com/resource.html</a></p><li><a href="http://www.ajaxw3c.com/resource_down/AjaxWeb20.rar" target="_blank">征服Ajax - Web20开发技术详解试读版【PDF电子版下载】</a></li><li><a href="http://www.ajaxw3c.com/resource_down/AjaxFastLane.pdf" target="new"><font color="#810081">AJAX 新手快车道【PDF电子版下载】</font></a></li><li><a href="http://wh.wlha.com.cn/bbs/pic/ajaxbasic.rar" target="_blank"><font color="#810081">Ajax 基础教程【html版下载】</font></a></li><li><a href="http://media.pragprog.com/titles/ajax/code/ajax-code.zip" target="_blank">Ajax 修炼之道—Web2.0入门【全部源代码下载】</a></li><li><a href="http://www.ajaxw3c.com/resource.html#">Ajax 开发精要</a></li><li><a href="http://www.ajaxw3c.com/resource_down/ajax_in_action.rar"><font color="#810081">Ajax实战(ajax_in_action)【PDF电子版下载】</font></a></li><li><a href="http://www.king-js.com/nimg/wzcg.pdf">网站重构【PDF电子版下载】</a></li><li><a href="http://www.ajaxw3c.com/resource_down/codeall101.rar">代码大全1.01中文版【PDF电子版下载】</a></li><li><a href="http://www.ajaxw3c.com/resource_down/CSS2.rar">CSS 2.0手册中文版(苏沈小雨版)【chm电子版下载】</a></li><li><a href="http://www.ajaxw3c.com/resource_down/CSS%202.0cn.rar">CSS 2.0样式表中文手册(苏昱版)【chm电子版下载】</a></li><li><a href="http://www.ajaxw3c.com/resource_down/JavaScript%205.rar">JScript 语言参考【chm电子版下载】</a></li><li><a href="http://www.ajaxw3c.com/resource_down/JavaScriptcode1.0.rar">JavaScript源码大全 v1.0【chm电子版下载】</a></li><li><a href="http://www.ajaxw3c.com/resource_down/javascript.rar">JavaScript 权威指南【chm电子版下载】</a></li><li><a href="http://www.ajaxw3c.com/resource_down/VBScript%205.5.rar">VBScript 语言参考【chm电子版下载】</a></li><li><a href="http://www.ajaxw3c.com/resource_down/XMLHTTP.rar"><font color="#810081">XmlHttp对象参考【chm电子版下载】</font></a></li><li><a href="http://www.ajaxw3c.com/resource_down/Flash%202004%20ActionScript.rar">Flash 2004 ActionScript 字典【chm电子版下载】</a></li><li><a href="http://www.ajaxw3c.com/resource_down/XML.rar">XML 指南【chm电子版下载】</a></li><li><a href="http://www.ajaxw3c.com/resource_down/XML2.rar">XML 学习手册英文第二版【chm电子版下载】</a></li><li><a href="http://www.ajaxw3c.com/resource_down/MSWinScript.rar">Microsoft Windows脚本技术【chm电子版下载】</a></li><li><a href="http://www.ajaxw3c.com/resource_down/WebProgram.rar">网站项目管理规范【chm电子版下载】</a></li><li><a href="http://www.ajaxw3c.com/resource_down/DHTML.rar">网页制作完全手册【chm电子版下载】</a></li><li><a href="http://www.ajaxw3c.com/resource_down/SQL.rar">SQL语言参考大全【chm电子版下载】</a></li><li><a href="http://www.ajaxw3c.com/resource_down/Validator%20v1.0.rar">表单验证Validator v1.0【chm电子版下载】</a></li><li><a href="http://www.ajaxw3c.com/resource_down/win32api.rar">新编 Win32API 大传【chm电子版下载】</a></li><li><a href="http://www.ajaxw3c.com/resource_down/webmake.rar">网站设计和制作理论知识【chm电子版下载】</a><br /><br />ajax联盟：规范标准<br /><a href="http://www.ajaxw3c.com/webstandard.html">http://www.ajaxw3c.com/webstandard.html</a><br /><br /><p class="text"><a title="CSS 编码规范" href="http://www.ajaxw3c.com/webstandard/css_standard.html" target="new"><font color="#810081">CSS 编码规范</font></a><br /><a title="ASP 编码规范" href="http://www.ajaxw3c.com/webstandard/asp_standard.html" target="new">ASP 编码规范</a><br /><a title="PHP 编码规范" href="http://www.ajaxw3c.com/webstandard/php_standard.html" target="new">PHP 编码规范</a><br /><a title="Java 编码规范" href="http://www.ajaxw3c.com/webstandard/java_standard.html" target="new">Java 编码规范</a><br /><a title="C＃编码规范" href="http://www.ajaxw3c.com/webstandard/CSharp_standard.html" target="new">C＃编码规范</a><br /><a title="JSP 编码规范" href="http://www.ajaxw3c.com/webstandard/JSP_standard.html" target="new">JSP 编码规范</a><br /><a title="网站技术规范" href="http://www.ajaxw3c.com/webstandard/web_standard.html" target="new">网站技术规范</a><br /><a title="网页制作规范及流程" href="http://www.ajaxw3c.com/webstandard/webpage_standard.html" target="new">网页制作规范及流程</a><br /><a title="专业信息网站制作规范" href="http://www.ajaxw3c.com/webstandard/webpro_standard.html" target="new">专业信息网站制作规范</a><br /><br />ajax联盟：文章教程<br /><a href="http://www.ajaxw3c.com/article.html">http://www.ajaxw3c.com/article.html</a></p><ul><li><a href="http://www.ajaxw3c.com/article/ajax20060701001.html" target="_blank">AJAX 技术简介</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060701002.html" target="_blank">AJAX 技术基础介绍</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060701003.html" target="_blank">AJAX 技术概述与现状应用</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060701004.html" target="_blank">AJAX 程序设计入门</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060701005.html" target="_blank">AJAX 应用说明及开发实例</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060704001.html" target="_blank">循序渐进学习Ajax的途径</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060704002.html" target="_blank">AJAX 开发简略</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060711002.html" target="_blank">AJAX 上手篇</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060711011.html" target="_blank">用AJAX编写一个简单的相册</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060711001.html" target="_blank">用AJAX开发应用程序实战</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060711003.html" target="_blank">AJAX 在 PHP 开发中的应用</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060711004.html" target="_blank">Atlas 微软的Ajax工具包</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060711005.html" target="_blank">用Ajax控制书签和回退按钮</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060711006.html" target="_blank">基于Ajax应用程序架构汇总</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060711007.html" target="_blank">AJAX 版的聊天室</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060711008.html" target="_blank">AJAX 案例研究之详细剖析Gmail应用</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060711012.html" target="_blank">Ajax 开发工具、框架</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060711014.html" target="_blank">详解如何实现最基本的AJAX框架</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060711010.html" target="_blank">用AJAX+J2EE实现网上会议室系统</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060711009.html" target="_blank">深入理解AJAX响应信息的处理</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060711014.html" target="_blank">详解如何实现最基本的AJAX框架</a></li><li><span twffan="done"><a href="http://www.ajaxw3c.com/article/ajax20060711018.html" target="_blank">实现基于Ajax的无限级菜单</a></span></li><li><a href="http://www.ajaxw3c.com/article/ajax20060711013.html" target="_blank">AJAX 实例：根据邮编自动完成地址信息</a></li><li><a href="http://www.ajaxw3c.com/web/ajax.html" target="_blank">Ajax学习--网址链接大全</a></li></ul><p class="text">ajax联盟：WEB2.0<br /><a href="http://www.ajaxw3c.com/web20.html">http://www.ajaxw3c.com/web20.html</a></p></li><li><a href="http://www.ajaxw3c.com/web2.0/web2.0_01.html" target="new">web 2.0 概念结构</a></li><li><a href="http://www.ajaxw3c.com/web2.0/web2.0_03.html" target="new">Web 2.0 学习指南</a></li><li><a href="http://www.ajaxw3c.com/web2.0/web2.0_04.html" target="new">Web 2.0中AJAX技术应用详解</a></li><li><a href="http://www.ajaxw3c.com/web2.0/web2.0_05.html" target="new">Web 2.0 网站成功的关键</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060711015.html" target="_blank">WEB2.0中AJAX应用的详细探讨</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060711016.html" target="_blank">Web 2.0 编程思想:16条法则</a></li><li><a href="http://www.ajaxw3c.com/article/ajax20060711017.html" target="_blank">关于Web 2.0 网站的创业思考</a><br /><br /><br />+++++++++++++++++++++++++++++++++++++++++++++++++<br />Ajax资料<br /><a href="http://blog.csdn.net/bjoker/archive/2006/10/23/1347578.aspx">http://blog.csdn.net/bjoker/archive/2006/10/23/1347578.aspx</a><br />一.资源类网站<br /><br />1,国内网站<br />1)Ajax中国(推荐)<br />一个专业的ajax技术网站,分类清晰,有大量的电子版教程,以及AJAX源码下载!<br /><a href="http://www.okajax.com/"><u><font color="#0000ff">www.okajax.com</font></u></a><br /><br />2)ajaxcn.org<br />李琨老师的blog。李琨:《ajax实战》译者.<br /><a href="http://www.ajaxcn.org/"><u><font color="#0000ff">www.ajaxcn.org</font></u></a><br />-----------------------------------------<br />2,国外网站<br />1)、Ajax 的诞生 <br />Ajax: A New Approach to Web Applications <br /><a href="http://www.adaptivepath.com/publications/essays/archives/000385.php"><u><font color="#0000ff">www.adaptivepath.com/publications/essays/archives/000385.php</font></u></a><br /><br />2)、AJAX Matters <br /><a href="http://www.ajaxmatters.com/"><u><font color="#0000ff">www.ajaxmatters.com</font></u></a><br />关于 Ajax 技术一个信息量非常大的网站，有点像 Ajax 世界中的 TSS。 <br /><br />3)、AJAX Patterns <br />与 AJAX 设计模式相关的资源。 <br /><a href="http://www.ajaxpatterns.org/"><u><font color="#0000ff">www.ajaxpatterns.org</font></u></a><br /><a href="http://www.softwareas.com/ajax-patterns"><u><font color="#0000ff">www.softwareas.com/ajax-patterns</font></u></a><br /><br />4)、http://www.ajaxian.com <br /><br />--------------------------------------------------------------------------------<br /><br />二.热门文章<br /><br />1.什么是AJAX<br /><a href="http://www.okajax.com/info/net/20060510.html"><u><font color="#0000ff">www.okajax.com/info/net/20060510.html</font></u></a><br />2.ajax技术简介<br /><a href="http://www.okajax.com/info/basic/200604654.html"><u><font color="#0000ff">www.okajax.com/info/basic/200604654.html</font></u></a><br />3.ajax.net<br /><a href="http://www.okajax.com/info/basic/200604556.html"><font color="#0000ff"><u>www.okajax.com/info/basic/200604556.html</u></font></a><br /><a href="http://www.okajax.com/info/tech/200605589.html"><font color="#0000ff"><u>www.okajax.com/info/tech/200605589.html</u></font></a><br /><a href="http://weblogs.asp.net/mschwarz/archive/2005/04/11/399893.aspx"><u><font color="#0000ff">weblogs.asp.net/mschwarz/archive/2005/04/11/399893.aspx</font></u></a>(英文)<br /><br />--------------------------------------------------------------------------------<br /><br />三.ajax相关下载（电子书教程/源码）<br />1.Ajax基础教程电子版<br /><a href="http://www.okajax.com/info/bookdown/200604950.htm"><u><font color="#0000ff">www.okajax.com/info/bookdown/200604950.htm</font></u></a><br />2.《AJAX实战》ajax in action电子版<br /><a href="http://www.okajax.com/info/bookdown/200604366.htm"><u><font color="#0000ff">www.okajax.com/info/bookdown/200604366.htm</font></u></a><br />3.AJAX开发简略<br /><a href="http://www.okajax.com/info/bookdown/20060538.htm"><u><font color="#0000ff">www.okajax.com/info/bookdown/20060538.htm</font></u></a><br />----------------------------<br />4.AJAX版CD管理系统 (jsp)<br /><a href="http://www.okajax.com/info/codedown/200604327.htm"><u><font color="#0000ff">www.okajax.com/info/codedown/200604327.htm</font></u></a><br />5.Alexa 查询系统 (Xmlhttp + Ajax)<br /><a href="http://www.okajax.com/info/codedown/200604982.htm"><u><font color="#0000ff">www.okajax.com/info/codedown/200604982.htm</font></u></a><br />6.ASP.NET+AJAX解决网页打开等待问题<br /><a href="http://www.okajax.com/info/codedown/200604166.htm"><u><font color="#0000ff">www.okajax.com/info/codedown/200604166.htm</font></u></a><br />7.Ajax技术简介 (ajax demo)<br /><a href="http://www.okajax.com/info/codedown/200604576.htm"><u><font color="#0000ff">www.okajax.com/info/codedown/200604576.htm</font></u></a><br /><br />--------------------------------------------------------------------------------<br /><br />四.ajax相关图书<br />1.《Ajax实战》(目前Ajax领域最为全面深入的一本著作) <br /><a href="http://www.china-pub.com/computers/common/info.asp?id=28433"><u><font color="#0000ff">www.china-pub.com/computers/common/info.asp?id=28433</font></u></a><br />2.《Ajax基础教程》（亚马逊计算机榜首图书，国内第1本Ajax图书）<br /><a href="http://www.china-pub.com/computers/common/info.asp?id=28432"><u><font color="#0000ff">www.china-pub.com/computers/common/info.asp?id=28432</font></u></a><br />3.《Ajax 修炼之道-Web 2.0 入门》（Ajax从小工到专家的首选图书）<br /><a href="http://www.china-pub.com/computers/common/info.asp?id=29430"><u><font color="#0000ff">www.china-pub.com/computers/common/info.asp?id=29430</font></u></a><br />4.《征服Ajax+Lucene构建搜索引擎》<br /><a href="http://www.china-pub.com/computers/common/info.asp?id=29996"><u><font color="#0000ff">www.china-pub.com/computers/common/info.asp?id=29996</font></u></a><br />5.《征服Ajax--Web 2.0快速入门与项目实践（.net）》<br /><a href="http://www.china-pub.com/computers/common/info.asp?id=29995"><u><font color="#0000ff">www.china-pub.com/computers/common/info.asp?id=29995</font></u></a><br />6.《Ajax开发精要--概念、案例与框架》<br /><a href="http://www.china-pub.com/computers/common/info.asp?id=30006"><u><font color="#0000ff">www.china-pub.com/computers/common/info.asp?id=30006</font></u></a><br />[Page] <br /><br /><br />--------------------------------------------------------------------------------<br /><br />五.部分技术文章<br /><a href="http://www.dragonson.com/doc/ajax.html"><u><font color="#0000ff">www.dragonson.com/doc/ajax.html</font></u></a><br />Ajax内部交流文档 <br /><a href="http://info96.k12studio.com/~nio/comments.php?id=242_0_1_0_C"><u><font color="#0000ff">info96.k12studio.com/~nio/comments.php?id=242_0_1_0_C</font></u></a><br />简单地对 Ajax 进行描述介绍 <br /><a href="http://www.adaptivepath.com/publications/essays/archives/000385.php"><u><font color="#0000ff">www.adaptivepath.com/publications/essays/archives/000385.php</font></u></a><br />Ajax: A New Approach to Web Applications <br /><a href="http://jibbering.com/2002/4/httprequest.html"><u><font color="#0000ff">jibbering.com/2002/4/httprequest.html</font></u></a><br />Using the XML HTTP Request object <br /><a href="http://developer.apple.com/internet/webcontent/xmlhttpreq.html"><u><font color="#0000ff">developer.apple.com/internet/webcontent/xmlhttpreq.html</font></u></a><br />Dynamic HTML and XML: The XMLHttpRequest Object <br /><a href="http://del.icio.us/popular/ajax"><u><font color="#0000ff">del.icio.us/popular/ajax</font></u></a><br />del.icio.us / popular / ajax <br /><a href="http://www.fiftyfoureleven.com/resources/programming/xmlhttprequest/examples"><u><font color="#0000ff">www.fiftyfoureleven.com/resources/programming/xmlhttprequest/examples</font></u></a><br />XMLHttpRequest &amp; Ajax Working Examples <br /><a href="http://www.xml.com/lpt/a/2005/02/09/xml-http-request.html"><u><font color="#0000ff">www.xml.com/lpt/a/2005/02/09/xml-http-request.html</font></u></a><br />Very Dynamic Web Interfaces <br /><a href="http://www.standards-schmandards.com/index.php?2005/03/01/16-ajax-and-accessibility"><u><font color="#0000ff">www.standards-schmandards.com/index.php?2005/03/01/16-ajax-and-accessibility</font></u></a><br />AJAX and Accessibility <br /><a href="http://www.xml.com/lpt/a/2005/05/11/ajax-error.html"><u><font color="#0000ff">www.xml.com/lpt/a/2005/05/11/ajax-error.html</font></u></a><br />Errors and AJAX <br /><a href="http://www.softwareas.com/ajax-patterns"><u><font color="#0000ff">www.softwareas.com/ajax-patterns</font></u></a><br />AJAX Patterns: Design Patterns for AJAX Usability <br /><a href="http://www.backbase.com/download/Whitepaper%20Backbase%20AJAX%20and%20Beyond.pdf"><u><font color="#0000ff">www.backbase.com/download/Whitepaper%20Backbase%20AJAX%20and%20Beyond.pdf</font></u></a><br />Whitepaper Backbase AJAX and Beyond <br /><a href="http://www.ajaxpatterns.org/index.php?title=Main_Page"><u><font color="#0000ff">www.ajaxpatterns.org/index.php?title=Main_Page</font></u></a><br />AJAX patterns <br /><a href="http://www.onlamp.com/pub/a/onlamp/2005/05/19/xmlhttprequest.html"><u><font color="#0000ff">www.onlamp.com/pub/a/onlamp/2005/05/19/xmlhttprequest.html</font></u></a><br />A Simpler Ajax Path <br />++++++++++++++++++++++++++++++++++++++++++++++++++++<br />AJAX技术初探 <br /><a href="http://blog.csdn.net/weihj1999/archive/2006/11/07/1370794.aspx">http://blog.csdn.net/weihj1999/archive/2006/11/07/1370794.aspx</a><br />AJAX学习 <br /><a href="http://blog.csdn.net/starshus/archive/2006/10/15/1335028.aspx">http://blog.csdn.net/starshus/archive/2006/10/15/1335028.aspx</a><br />AJAX技术汇总 <br /><a href="http://blog.csdn.net/aiwtu/archive/2006/10/06/1323397.aspx">http://blog.csdn.net/aiwtu/archive/2006/10/06/1323397.aspx</a><br />掌握 Ajax，第 1 部分: Ajax 简介<br /><a href="http://blog.csdn.net/zhp80/archive/2006/10/12/1331538.aspx">http://blog.csdn.net/zhp80/archive/2006/10/12/1331538.aspx</a><br />Ajax原理详细说明(转自ibm开发者网站) <br /><a href="http://blog.csdn.net/etnovo/archive/2006/11/04/1366493.aspx">http://blog.csdn.net/etnovo/archive/2006/11/04/1366493.aspx</a><br />Ajax的定义与总结 <br /><a href="http://blog.csdn.net/xdy3008/archive/2006/10/30/1356778.aspx">http://blog.csdn.net/xdy3008/archive/2006/10/30/1356778.aspx</a><br />Thinking in AJAX -- 基于AJAX的WEB设计 <br /><a href="http://blog.csdn.net/ljhj210423/archive/2006/11/01/1360136.aspx">http://blog.csdn.net/ljhj210423/archive/2006/11/01/1360136.aspx</a><br />Ajax应用演示和源码下载 <br /><a href="http://blog.csdn.net/honglei225/archive/2006/11/07/1370409.aspx">http://blog.csdn.net/honglei225/archive/2006/11/07/1370409.aspx</a><br />70个流行的AJAX应用的演示和源码下载 <br /><a href="http://blog.csdn.net/xwycs/archive/2006/10/01/1315222.aspx">http://blog.csdn.net/xwycs/archive/2006/10/01/1315222.aspx</a><br />AJAX、AJAX实例及AJAX源代码（asp） <br /><a href="http://blog.csdn.net/itfly8/archive/2006/10/30/1356293.aspx">http://blog.csdn.net/itfly8/archive/2006/10/30/1356293.aspx</a><br />基于Ajax的应用程序架构汇总<br /><a href="http://blog.csdn.net/kastolo/archive/2006/11/07/1371545.aspx">http://blog.csdn.net/kastolo/archive/2006/11/07/1371545.aspx</a><br />ASP.NETWeb应用程序的简单AJAX实现 (转婕舞飞扬) <br /><a href="http://blog.csdn.net/lover_rong/archive/2006/11/09/1375031.aspx">http://blog.csdn.net/lover_rong/archive/2006/11/09/1375031.aspx</a><br />使用 Ajax 构建 RSS 阅读器<br /><a href="http://www-128.ibm.com/developerworks/cn/xml/x-ajaxrss/index.html">http://www-128.ibm.com/developerworks/cn/xml/x-ajaxrss/index.html</a><br /><br /><br /><br /></li></div></td></tr></tbody></table> </div></div><img src ="http://www.blogjava.net/jelver/aggbug/87049.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-12-11 20:42 <a href="http://www.blogjava.net/jelver/articles/87049.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Eclipse快速上手指南之使用ANT</title><link>http://www.blogjava.net/jelver/articles/81736.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Fri, 17 Nov 2006 04:34:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/81736.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/81736.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/81736.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/81736.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/81736.html</trackback:ping><description><![CDATA[Ant是Java平台下非常棒的批处理命令执行程序，能非常方便地自动完成编译，测试，打包，部署等等一系列任务，大大提高开发效率。如果你现在还没有开始使用Ant，那就要赶快开始学习使用，使自己的开发水平上一个新台阶。<br /><br />　　Eclipse中已经集成了Ant，我们可以直接在Eclipse中运行Ant。<br /><br />　　以前面建立的Hello工程为例，创建以下目录结构：<br /><br /><table width="90%" align="center" border="0"><tbody><tr><td><div align="center"><img onerror="this.src='http://www.yesky.com/image20010518/208897.jpg';" hspace="3" src="http://www.yesky.com/image20010518/208897.jpg" align="center" vspace="1" border="1" /></div></td></tr></tbody></table><br />　　新建一个build.xml，放在工程根目录下。build.xml定义了Ant要执行的批处理命令。虽然Ant也可以使用其它文件名，但是遵循标准能更使开发更规范，同时易于与别人交流。<br /><br />　　通常，src存放Java源文件，classes存放编译后的class文件，lib存放编译和运行用到的所有jar文件，web存放JSP等web文件，dist存放打包后的jar文件，doc存放API文档。<br /><br />　　然后在根目录下创建build.xml文件，输入以下内容： <br /><font face="Courier New" color="#006400"><br /></font><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#d9ecee" border="1"><tbody><tr><td><font face="Courier New" color="#006400">＜?xml version="1.0"?＞<br />＜project name="Hello world" default="doc"＞</font><br /><br /><font face="Courier New" color="#006400">＜!-- properies --＞<br />＜property name="src.dir" value="src" /＞<br />＜property name="report.dir" value="report" /＞<br />＜property name="classes.dir" value="classes" /＞<br />＜property name="lib.dir" value="lib" /＞<br />＜property name="dist.dir" value="dist" /＞<br />＜property name="doc.dir" value="doc"/＞</font><br /><br /><font face="Courier New" color="#006400">＜!-- 定义classpath --＞<br />＜path id="master-classpath"＞<br />＜fileset file="${lib.dir}/*.jar" /＞<br />＜pathelement path="${classes.dir}"/＞<br />＜/path＞</font><br /><br /><font face="Courier New" color="#006400">＜!-- 初始化任务 --＞<br />＜target name="init"＞<br />＜/target＞</font><br /><br /><font face="Courier New" color="#006400">＜!-- 编译 --＞<br />＜target name="compile" depends="init" description="compile the source files"＞<br />＜mkdir dir="${classes.dir}"/＞<br />＜javac srcdir="${src.dir}" destdir="${classes.dir}" target="1.4"＞<br />＜classpath refid="master-classpath"/＞<br />＜/javac＞<br />＜/target＞</font><br /><br /><font face="Courier New" color="#006400">＜!-- 测试 --＞<br />＜target name="test" depends="compile" description="run junit test"＞<br />＜mkdir dir="${report.dir}"/＞<br />＜junit printsummary="on"<br />haltonfailure="false"<br />failureproperty="tests.failed"<br />showoutput="true"＞<br />＜classpath refid="master-classpath" /＞<br />＜formatter type="plain"/＞<br />＜batchtest todir="${report.dir}"＞<br />＜fileset dir="${classes.dir}"＞<br />＜include name="**/*Test.*"/＞<br />＜/fileset＞<br />＜/batchtest＞<br />＜/junit＞<br />＜fail if="tests.failed"＞<br />***********************************************************<br />**** One or more tests failed! Check the output ... ****<br />***********************************************************<br />＜/fail＞<br />＜/target＞</font><br /><br /><font face="Courier New" color="#006400">＜!-- 打包成jar --＞<br />＜target name="pack" depends="test" description="make .jar file"＞<br />＜mkdir dir="${dist.dir}" /＞<br />＜jar destfile="${dist.dir}/hello.jar" basedir="${classes.dir}"＞<br />＜exclude name="**/*Test.*" /＞<br />＜exclude name="**/Test*.*" /＞<br />＜/jar＞<br />＜/target＞</font><br /><br /><font face="Courier New" color="#006400">＜!-- 输出api文档 --＞<br />＜target name="doc" depends="pack" description="create api doc"＞<br />＜mkdir dir="${doc.dir}" /＞<br />＜javadoc destdir="${doc.dir}"<br />author="true"<br />version="true"<br />use="true"<br />windowtitle="Test API"＞<br />＜packageset dir="${src.dir}" defaultexcludes="yes"＞<br />＜include name="example/**" /＞<br />＜/packageset＞<br />＜doctitle＞＜![CDATA[＜h1＞Hello, test＜/h1＞]]＞＜/doctitle＞<br />＜bottom＞＜![CDATA[＜i＞All Rights Reserved.＜/i＞]]＞＜/bottom＞<br />＜tag name="todo" scope="all" description="To do:" /＞<br />＜/javadoc＞<br />＜/target＞<br />＜/project＞</font></td></tr></tbody></table><font face="Courier New" color="#006400"></font><br />　　以上xml依次定义了init（初始化），compile（编译），test（测试），doc（生成文档），pack（打包）任务，可以作为模板。<br /><br />　　选中Hello工程，然后选择“Project”，“Properties”，“Builders”，“New…”，选择“Ant Build”：<br /><br /><table width="90%" align="center" border="0"><tbody><tr><td><div align="center"><img onerror="this.src='http://www.yesky.com/image20010518/208898.jpg';" hspace="3" src="http://www.yesky.com/image20010518/208898.jpg" align="center" vspace="1" border="1" /></div></td></tr></tbody></table><br />　　填入Name：Ant_Builder；Buildfile：build.xml；Base Directory：${workspace_loc:/Hello}（按“Browse Workspace”选择工程根目录），由于用到了junit.jar包，搜索Eclipse目录，找到junit.jar，把它复制到Hello/lib目录下，并添加到Ant的Classpath中：<br /><br /><table width="90%" align="center" border="0"><tbody><tr><td><div align="center"><img onerror="this.src='http://www.yesky.com/image20010518/208899.jpg';" hspace="3" src="http://www.yesky.com/image20010518/208899.jpg" align="center" vspace="1" border="1" /></div></td></tr></tbody></table><br />　　然后在Builder面板中钩上Ant_Build，去掉Java Builder：<br /><br /><table width="90%" align="center" border="0"><tbody><tr><td><div align="center"><img onerror="this.src='http://www.yesky.com/image20010518/208900.jpg';" hspace="3" src="http://www.yesky.com/image20010518/208900.jpg" align="center" vspace="1" border="1" /></div></td></tr></tbody></table><br />　　再次编译，即可在控制台看到Ant的输出：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#d9ecee" border="1"><tbody><tr><td><font face="Courier New" color="#006400">Buildfile: F:\eclipse-projects\Hello\build.xml</font><br /><br /><font face="Courier New" color="#006400">init:</font><br /><br /><font face="Courier New" color="#006400">compile:<br />[mkdir] Created dir: F:\eclipse-projects\Hello\classes<br />[javac] Compiling 2 source files to F:\eclipse-projects\Hello\classes</font><br /><br /><font face="Courier New" color="#006400">test:<br />[mkdir] Created dir: F:\eclipse-projects\Hello\report<br />[junit] Running example.HelloTest<br />[junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.02 sec</font><br /><br /><font face="Courier New" color="#006400">pack:<br />[mkdir] Created dir: F:\eclipse-projects\Hello\dist<br />[jar] Building jar: F:\eclipse-projects\Hello\dist\hello.jar</font><br /><br /><font face="Courier New" color="#006400">doc:<br />[mkdir] Created dir: F:\eclipse-projects\Hello\doc<br />[javadoc] Generating Javadoc<br />[javadoc] Javadoc execution<br />[javadoc] Loading source files for package example...<br />[javadoc] Constructing Javadoc information...<br />[javadoc] Standard Doclet version 1.4.2_04<br />[javadoc] Building tree for all the packages and classes...<br />[javadoc] Building index for all the packages and classes...<br />[javadoc] Building index for all classes...<br />[javadoc] Generating F:\eclipse-projects\Hello\doc\stylesheet.css...<br />[javadoc] Note: Custom tags that could override future standard tags: @todo. To avoid potential overrides, use at least one period character (.) in custom tag names.<br />[javadoc] Note: Custom tags that were not seen: @todo<br />BUILD SUCCESSFUL<br />Total time: 11 seconds</font></td></tr></tbody></table><br />　　Ant依次执行初始化，编译，测试，打包，生成API文档一系列任务，极大地提高了开发效率。将来开发J2EE项目时，还可加入部署等任务。并且，即使脱离了Eclipse环境，只要正确安装了Ant，配置好环境变量ANT_HOME=＜Ant解压目录＞，Path=…;%ANT_HOME%\bin，在命令行提示符下切换到Hello目录，简单地键入ant即可。<br /><br />相关文章：<a href="http://www-128.ibm.com/developerworks/cn/java/j-lo-ant-eclipse/index.html">http://www-128.ibm.com/developerworks/cn/java/j-lo-ant-eclipse/index.html</a><img src ="http://www.blogjava.net/jelver/aggbug/81736.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-11-17 12:34 <a href="http://www.blogjava.net/jelver/articles/81736.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ant使用指南（一） </title><link>http://www.blogjava.net/jelver/articles/81568.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Thu, 16 Nov 2006 09:19:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/81568.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/81568.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/81568.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/81568.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/81568.html</trackback:ping><description><![CDATA[
		<h2>
				<a id="viewpost1_TitleUrl" href="http://www.cnblogs.com/SGSoft/articles/81480.html">Ant使用指南（一）</a>
		</h2>原文：<a href="http://sgsoft.cnblogs.com/articles/81480.html?Pending=true#Post">http://sgsoft.cnblogs.com/articles/81480.html?Pending=true#Post</a><br />管理你的代码，doc文件,编译,配置等开发工作你是怎末做的：自己管理源目录，编译文件，copy,实施... 在window写bat,在unix写shell？ <br />     可惜我不怎末会写。所以我制作一个ejb的过程是这样的： <br />写代码-&gt;写个bat编译代码-&gt;组织文件(ejb-jar.xml,jboss.xml...)-&gt;压缩文件生成jar文档-&gt; <br />实施......(还有同样的测试过程)(为甚末不用jbuild?) 
<p><font size="2">    这中间每次修改都要经过重复的无数次手工copy,paste...过程，好累，好花时间。可我确实不想去 <br />学脚本编写，unix,linux下我还得重学，太累。</font></p><p><font size="2">    如果你和我一样希望自动执行预定义的动作却又不想太累，那末，我觉得ANT工具不错： <br />它可以以相同的用法用在不同平台(跨平台)。它是JAVA做的，免费的，开源的，据说网上已经成了事实的JAVA <br />构建标准，还听说高手都用它...... ^_^</font></p><p><font size="2">    我花了2天时间才掌握了它的基本用法，我希望你能通过我的文章和试验花半天时间就掌握它。</font></p><p><b><font color="#ff0000" size="2">内容：</font></b></p><ul><li><b><font color="#ff0000" size="2">下载，安装</font></b></li><li><b><font color="#ff0000" size="2">hello ant</font></b></li><li><b><font color="#ff0000" size="2">hello ant 进级</font></b></li><li><b><font color="#ff0000" size="2">参考及下载</font></b></li></ul><p><font size="2"><font color="#ff0000"><b>下载，安装 <br />   </b></font>又下载?又是一大堆参数变量?  :( <br />    <a href="http://jakarta.apache.org/ant/index.html">http://jakarta.apache.org/ant/index.html</a> 它是apache的java子项目"jakarta"的子项目.你可以选择 <br />当前的版本，目前我是1.5版,window版，以下就用它讲。</font></p><p><font size="2">    解压后ant_home用来方便访问。并确保你也设置了java_home 。 <br />    set ant_home=D:\java\kit\ant\jakarta-ant-1.5.1    这是我的目录     <br /><br />    就这些，简单吧。 <br /><br /><font color="#ff0000"><b>hello ant</b></font></font></p><p><font size="2">我们要开发一个java类：其内容只有一句，输出"hello ant"字符串。并使用ant完成编译和运行工作，这个例子只是为了跑通ant，不附加多余的东西。</font></p><p><font size="2">下图为文件组织，请建立相应的目录，并编写HelloAnt.java <br /><img height="198" src="http://www.huihoo.com/java/hello-ant/images/hello-ant-dir.gif" width="425" border="1" /></font></p><p><font size="2">按照人家老外的文件组织规则咱也照搬。</font></p><table style="BORDER-COLLAPSE: collapse" bordercolor="#000000" height="69" cellspacing="0" cellpadding="0" width="86%" border="1"><tbody><tr><td width="100%" bgcolor="#c0c0c0" height="13"><font size="2"> hello.ant.HelloAnt.java</font></td></tr><tr><td width="100%" height="52"><font size="2"><textarea style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体" name="S1" rows="7" cols="75">package hello.ant;

public class HelloAnt{
    public static void main(String[] args){
        System.out.println("hello ant,ant 的第一次接触，好棒！");
    } 
}</textarea></font></td></tr></tbody></table><p><font size="2">在项目根目录(hello-ant\)写1个文件：ant执行配置文件build.xml</font></p><table style="BORDER-COLLAPSE: collapse" bordercolor="#000000" height="69" cellspacing="0" cellpadding="0" width="86%" border="1"><tbody><tr><td width="100%" bgcolor="#c0c0c0" height="13"><font size="2"> build.xml</font></td></tr><tr><td width="100%" height="52"><font size="2"><textarea style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体" name="S1" rows="13" cols="75">&lt;?xml version="1.0"  encoding="GB2312" ?&gt;

&lt;!-- 一个项目,可包含很多任务组(target) --&gt;
&lt;project default="main" basedir="."&gt;

    &lt;!-- 项目中的一个任务组,可包含很多任务(task:javac,java...) --&gt;
    &lt;target name="main"&gt;

        &lt;!--编译--&gt;
        &lt;javac srcdir="src\main\hello\ant" destdir="build\classes"/&gt;

        &lt;!--运行--&gt;
        &lt;java classname="hello.ant.HelloAnt"&gt;
            &lt;classpath&gt;
                &lt;pathelement path="build\classes"/&gt;
            &lt;/classpath&gt;
        &lt;/java&gt;

    &lt;/target&gt;
&lt;/project&gt;</textarea></font></td></tr></tbody></table><p><font size="2">ok,一切大功告成，哦，不，还没有运行它。</font></p><p><font size="2">dos下进入hello-ant的目录，即build.xml所在的目录，我们要用ant工具执行它 ， </font></p><p><font size="2">执行: %ant_home%/bin/ant -file build.xml     用ant工具执行当前目录下的配置文件build.xml </font></p><p><font size="2">或  ：ant -file build.xml                    你如果设置%ant_home%/bin到path中</font></p><p><font size="2">这次ok了，这是答案：</font></p><table style="BORDER-COLLAPSE: collapse" bordercolor="#000000" height="69" cellspacing="0" cellpadding="0" width="86%" border="1"><tbody><tr><td width="100%" bgcolor="#c0c0c0" height="13"><font size="2">命令提示符窗口</font></td></tr><tr><td width="100%" bgcolor="#000000" height="52"><font color="#ffffff" size="2">D:\temp\hello-ant&gt;ant -file build.xml <br />Buildfile: build.xml <br /><br />main: <br />[javac] Compiling 1 source file to D:\temp\hello-ant\build\classes <br />[java] hello ant,ant 的第一次接触，好棒！ <br /><br />BUILD SUCCESSFUL <br />Total time: 2 seconds <br />D:\temp\hello-ant&gt;</font></td></tr></tbody></table><p><font size="2">检查一下build/classes目录，哦，看到编译过的文件就在这里: <br />build/classes/hello/ant/HelloAnt.class.</font></p><p><b><font color="#ff0000" size="2">hello ant 进级</font></b></p><p><font size="2">(此段比较废话，可以略过) <br /><font face="仿宋_GB2312">你也许会说：这末简单的工作写个批处理不就得了，又xml又ant的，把我的时间都浪费完了，我用jbuild或 <br />webShpere不就得了，怎末说你才明白呢？反正网上开源项目大多数都用ant,你总不能给人家个*.jpx吧， <br />而且这样的工具太贵，受不了(当然用D的兄弟不怕^_^ )，而且ant可以让你明确的管理和自动化所有的东西: <br />编译-实施-测试...,哎，稍微麻烦一点点，但节约你以前花在零碎的copy,paste上的时间.而且我发现管理 <br />代码的质量有所提高.</font></font></p><p><font size="2">我们要改进build.xml，让它做更多的事情：</font></p><ul><li><font size="2">定义全局变量</font></li><li><font size="2">初始化,主要是建立目录</font></li><li><font size="2">编译  (已有)</font></li><li><font size="2">打包为jar</font></li><li><font size="2">建立API documentation</font></li><li><font size="2">生成distribution产品</font></li></ul><p class="MsoNormal"><font face="仿宋_GB2312" size="2">凡事都讲究平衡，你要ant给你做更多事，当然要累一点点，不过只用累一次，以后的代码修改后的构建都是"一键式"完成,我们制作一个hello的简单例子，你可以自己做j2ee的练习。</font></p><p class="MsoNormal"><font face="宋体" size="2">我们要扩充目录结构，使它更像回事：</font></p><p class="MsoNormal"><font face="宋体" size="2">ant处理编译之前的目录：</font></p><p class="MsoNormal"><font face="宋体" size="2"><img height="170" src="http://www.huihoo.com/java/hello-ant/images/hello-ant-dir-advance-2.gif" width="425" border="1" /></font></p><p class="MsoNormal"><font face="宋体" size="2">ant处理之后的目录：</font></p><p class="MsoNormal"><font size="2"><img height="283" src="http://www.huihoo.com/java/hello-ant/images/hello-ant-dir-advance-1.gif" width="454" border="1" /></font></p><p class="MsoNormal"><font size="2">图中：\src,\docs,\lib是自己组织的文件结构，\build,\dist是ant动态生成的成品。</font></p><p class="MsoNormal"><font size="2">\src                     源文件：java源，script源，jsp源，xml配置..... <br />\src\main         java源 <br />\src\script     window,unix,liunx的执行script，我们的简单只有一个： <br />                  run.bat:  java hello.ant.HelloAnt</font></p><p class="MsoNormal"><font size="2">\docs                手写说明文档 <br />\lib                   程序所需类库的jar,比如j2ee.jar,mail,jar...</font></p><p class="MsoNormal"><font size="2">\build               用ant动态生成的构建目录 <br />\build\classes  编译的类文件 <br />\build\docs         copy "\docs"的手写说明文档，和ant生成的api文档 <br />\build\lib           放置我们自己的HelloAnt.class打包成品hello-ant.jar</font></p><p class="MsoNormal"><font size="2">\dist\bin        copy "\src\script" 得执行文件 <br />\dist\docs      copy "\build\docs" 的文档 <br />\dist\lib         除了copy "\build\lib"下的hello-ant.jar外， <br />                              还应copy "\lib"的程序所需jar，这里我们没有。</font></p><p class="MsoNormal"><font size="2">以上是我学老外的文件组织，大家可以按照自己的爱好组织</font></p><p class="MsoNormal"><font size="2">我们编写必要的文件： </font></p><table style="BORDER-COLLAPSE: collapse" bordercolor="#000000" height="29" cellspacing="0" cellpadding="0" width="86%" border="1"><tbody><tr><td width="100%" bgcolor="#c0c0c0" height="13"><font size="2">hello.ant. HelloAnt.java</font></td></tr><tr><td width="100%" height="12"><font size="2">已有</font></td></tr></tbody></table><table style="BORDER-COLLAPSE: collapse" bordercolor="#000000" height="69" cellspacing="0" cellpadding="0" width="86%" border="1"><tbody><tr><td width="100%" bgcolor="#c0c0c0" height="13"><font size="2">\src\script.bat</font></td></tr><tr><td width="100%" height="52"><font size="2"><textarea style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体" name="S1" rows="7" cols="75">@echo off
echo ========================================================
echo   请先设置 Environment
echo .
echo   JAVA_HOME: %JAVA_HOME%
echo ======================================================

%java_home%\bin\java -classpath ..\lib\hello-ant.jar  hello.ant.HelloAnt

pause </textarea></font></td></tr></tbody></table><table style="BORDER-COLLAPSE: collapse" bordercolor="#000000" height="69" cellspacing="0" cellpadding="0" width="86%" border="1"><tbody><tr><td width="100%" bgcolor="#c0c0c0" height="13"><font size="2">\docs\index.html 随便写一个手写的文档</font></td></tr><tr><td width="100%" height="52"><p align="center"><b><font color="#ff0000" size="2">hello ant 软件项目手册docs</font></b></p><hr color="#008000" size="1" /><p align="center"><b><a href="http://www.huihoo.com/java/hello-ant/api/index.html"><font color="#ff0000" size="2">访问api文档</font></a></b></p>　 </td></tr></tbody></table><table style="BORDER-COLLAPSE: collapse" bordercolor="#000000" height="69" cellspacing="0" cellpadding="0" width="86%" border="1"><tbody><tr><td width="100%" bgcolor="#c0c0c0" height="13"><font size="2">\build.xml 配置文件 </font></td></tr><tr><td width="100%" height="52"><font size="2"><textarea style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体" name="S1" rows="24" cols="83">&lt;?xml version="1.0"  encoding="GB2312" ?&gt;
&lt;!--
    =======================================================================
      hello-ant 项目 ,学习ant工具的第2个build file.

      参照ant的jakarta-ant-1.6alpha的build.xml

      Copyright (c) 2002 The Neusoft Software Foundation.  All rights
      reserved.

    =======================================================================
--&gt;

&lt;!--
    文档结构为:
    &lt;project&gt;
        &lt;property/&gt;               全局变量的定义
        &lt;property/&gt;...

        &lt;target name="1"&gt;         任务组(tasks)
            &lt;javac&gt;&lt;/javac&gt;       一项javac任务
            ...
            &lt;oneTask&gt;&lt;/ontTask&gt;   一项其它任务
        &lt;/target&gt;

        &lt;target name="2"&gt;
            &lt;javac&gt;&lt;/javac&gt;
            ...
            &lt;oneTask&gt;&lt;/ontTask&gt;
        &lt;/target&gt;
    &lt;/project&gt;

    project代表一个项目，
    default:运行到名称为"dist"的target(任务组)
    basedir:基准路径。
--&gt;
&lt;project default="dist" basedir="."&gt;

&lt;!--
    ===================================================================
      定义属性（property tasks）
      最好把用到的路径呀，名称呀都在这里定义成全局变量
      例：定义
          &lt;property name="a" value="hello"/&gt;
      以后就可以这样用它：
          &lt;property name="b" value="${a}/b"/&gt;
      现在:b=="hello/b"
    ===================================================================
--&gt;

    &lt;!--主要的系统环境属性--&gt;
    &lt;property environment="env"/&gt;&lt;!--取window,unix...的环境变量--&gt;
    &lt;property name="java.home" value="${env.JAVA_HOME}"/&gt;
    &lt;property name="ant.home"  value="${env.ANT_HOME}"/&gt;

    &lt;!--主要的app环境属性--&gt;
    &lt;property name="app.name"      value="hello-ant"/&gt;
    &lt;property name="app.jar"       value="${app.name}.jar"/&gt;
    &lt;property name="app.copyright" value=" Copyright (c) 2002 The Neusoft Software Foundation.  All rights reserved."/&gt;


    &lt;!--app中src的属性--&gt;
    &lt;property name="src.dir"    value="src" /&gt;
    &lt;property name="src.main"   value="${src.dir}/main"/&gt;
    &lt;property name="src.script" value="${src.dir}/script"/&gt;

    &lt;!--app用到的lib--&gt;
    &lt;property name="lib.dir" value="lib"/&gt;

    &lt;!--app的build目录中--&gt;
    &lt;property name="build.dir"      value="build" /&gt;
    &lt;property name="build.classes"  value="${build.dir}/classes"/&gt;
    &lt;property name="build.docs"     value="${build.dir}/docs"/&gt;
    &lt;property name="build.docs.api" value="${build.docs}/api"/&gt;
    &lt;property name="build.lib"      value="${build.dir}/lib"/&gt;

    &lt;!--app的dist (distribution) 目录中--&gt;
    &lt;property name="dist.dir"      value="dist"/&gt;
    &lt;property name="dist.bin"      value="${dist.dir}/bin"/&gt;
    &lt;property name="dist.docs"     value="${dist.dir}/docs"/&gt;
    &lt;property name="dist.lib"      value="${dist.dir}/lib"/&gt;

    &lt;!--app的docs目录中--&gt;
    &lt;property name="docs.dir"      value="docs"/&gt;

    &lt;!--
    定义一组路径以后可以通过id重用这组路径 ，例：
    &lt;javac srcdir="src/main" destdir="build/classes"&gt;
            &lt;classpath refid="classpath"/&gt;
    &lt;/javac&gt;
    --&gt;
    &lt;path id="classpath"&gt;
        &lt;!--本项目只有一个java，用不上classpath，这里只是做个例子--&gt;
        &lt;pathelement location="${build.classes}"/&gt;
        &lt;pathelement path="${java.home}/lib/tools.jar"/&gt;
    &lt;/path&gt;

&lt;!--
    ===================================================================
      init 准备目录(File Tasks)
      主要的目录结构通常是不会变的，一起生成他们
    ===================================================================
--&gt;
    &lt;target name="init"&gt;
        &lt;!--清除以前目录--&gt;
        &lt;delete dir="${build.dir}" failonerror="false" /&gt;
        &lt;delete dir="${dist.dir}"  failonerror="false"/&gt;

        &lt;!--准备目录--&gt;
        &lt;mkdir dir="${build.dir}"/&gt;
        &lt;mkdir dir="${build.classes}"/&gt;
        &lt;mkdir dir="${build.docs}"/&gt;
        &lt;mkdir dir="${build.docs.api}"/&gt;
        &lt;mkdir dir="${build.lib}"/&gt;

        &lt;mkdir dir="${dist.dir}"/&gt;
        &lt;mkdir dir="${dist.bin}"/&gt;
        &lt;mkdir dir="${dist.lib}"/&gt;

    &lt;/target&gt;

&lt;!--
    ===================================================================
      Build the code (Compile Tasks,File Tasks)
    ===================================================================
--&gt;
    &lt;target name="build" depends="init"&gt;
        &lt;!--编译--&gt;
        &lt;javac srcdir="${src.main}" destdir="${build.classes}"&gt;
            &lt;classpath refid="classpath"/&gt;
        &lt;/javac&gt;
    &lt;/target&gt;

&lt;!--
    ===================================================================
      打包文档(Archive Tasks)
      Create the project jars: xxx1.jar and xxx2.jar
    ===================================================================
--&gt;
   &lt;target name="jars" depends="build"&gt;
        &lt;jar basedir="${build.classes}" jarfile="${build.lib}/${app.jar}"/&gt;
    &lt;/target&gt;

&lt;!--
     ===================================================================
       Creates the API documentation
     ===================================================================
--&gt;
    &lt;target name="javadocs"
            depends="jars"
            description="--&gt; creates the API documentation"&gt;
        &lt;!--copy docs 手册... --&gt;
        &lt;copy todir="${build.docs}"&gt;
            &lt;fileset dir="${docs.dir}"/&gt;
        &lt;/copy&gt;

        &lt;javadoc packagenames="hello.ant.*"
                 sourcepath="${src.main}"
                 defaultexcludes="yes"
                 destdir="${build.docs.api}"
                 author="true"
                 version="true"
                 use="true"
                 windowtitle="Docs API"&gt;
             &lt;doctitle&gt;&lt;![CDATA[&lt;h1&gt;hello ant Docs API&lt;/h1&gt;]]&gt;&lt;/doctitle&gt;
             &lt;bottom&gt;&lt;![CDATA[&lt;i&gt;${app.copyright}&lt;/i&gt;]]&gt;&lt;/bottom&gt;
             &lt;tag name="todo" scope="all" description="To do:" /&gt;
         &lt;/javadoc&gt;
    &lt;/target&gt;

&lt;!--
     ===================================================================
       Create the distribution that can run (Archive Tasks)
       主要是从各目录中把该copy的copy上
     ===================================================================
--&gt;
   &lt;target name="dist" depends="javadocs"&gt;
        &lt;!--copy bin 执行文件 --&gt;
        &lt;copy todir="${dist.bin}"&gt;
            &lt;fileset dir="${src.script}/"/&gt;
        &lt;/copy&gt;
        &lt;copy todir="${dist.docs}"&gt;
            &lt;fileset dir="${build.docs}/"/&gt;
        &lt;/copy&gt;
        &lt;!-- copy lib 文件 --&gt;
        &lt;copy todir="${dist.lib}"&gt;
            &lt;fileset dir="${build.lib}/"/&gt;
        &lt;/copy&gt;

    &lt;/target&gt;
&lt;!--
     ===================================================================
      Cleans everything(File Tasks)
      例如可以删除build中的文件，留给你发挥吧
     ===================================================================
--&gt;

&lt;/project&gt;</textarea></font></td></tr></tbody></table><p class="MsoNormal"><font size="2"><br />build.xml多了些，但其实很简单：(注释比较详细可以参照，这里再简单说一下)</font></p><p class="MsoNormal"><font size="2">一个build.xml包含一个工程的自动化处理的完整xml说明，并且基本由3种东东组成：</font></p><p class="MsoNormal"><font size="2">&lt;project &gt; <br /><br />    1.全局变量的定义 <br />    &lt;property/&gt;</font></p><p class="MsoNormal"><font size="2">    2.任务组 <br />    &lt;target&gt; <br />        3.许多单项任务... 像copy,delete,javac,jar... <br />        &lt;task1/&gt; <br />        &lt;task2/&gt; <br />        &lt;task3/&gt; <br />    &lt;/target&gt;</font></p><p class="MsoNormal"><font size="2">&lt;/project&gt;</font></p><img src ="http://www.blogjava.net/jelver/aggbug/81568.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-11-16 17:19 <a href="http://www.blogjava.net/jelver/articles/81568.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用xmlhttp和Java session监听改善站内消息系统</title><link>http://www.blogjava.net/jelver/articles/43316.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Wed, 26 Apr 2006 07:35:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/43316.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/43316.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/43316.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/43316.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/43316.html</trackback:ping><description><![CDATA[  这个题目含有许多需要解释的概念，最容易说明的是“站内消息”，这是很多论坛都有的功能，可以通过web向其他的在线用户发送消息，很多用户都使用过。站内消息的第一个好处是大家都不需要安装客户端，你不用知道对方的MSN或者QQ，就能与他联系，称赞他的观点或者是给他一顿臭骂。第二个好处是客户管理方便，利用session来维护在线名单，各种脚本都已经把session操作封装得很易用了，不用像其他无状态的即时通信工具（比如使用UDP通信的工具）一样，要费一些脑细胞来解决在线名单的问题。缺点嘛，就是实时性不好，一般是在用户跳转或者刷新页面才能探测消息、更新在线名单。<br /><br />　　 Session监听嘛，没什么好解释的，java提供了很灵活的事件机制来监听session，可以监听session的创建和销毁，监控session所携带数据的创建、变化和销毁，可以监听session的锐化和钝化（了解对象序列化的兄弟应该知道这个），其他的平台是个什么情况我不太清楚，估计也差不多吧。如果能够对所有客户的session进行监控，就不用再去操作麻烦而危险的Application了。
<p>　　 　　 Xmlhttp是MS推的一项技术，功能很复杂，可以做很多事情，比如客户端可以在简单的HTML中打开HTTP连接，主动向server请求数据并获得返回数据，是DOM技术一个非常重要的应用，利用它来写无刷新的动态页面简直是so easy，做过web开发的兄弟应该明白它的意义有多么重大。<br /><br />一、 session监听<br /><br />　　 servlet中对session的监听有很多接口，功能很灵活，最常用的是监听Session和Attribute。这里要澄清一下概念，servlet中的session监听和Attribute监听含义有差别，session监听指的不是我们一般所理解的放置一个session或者销毁一个session，这是Attribute监听的功能，因为servlet中放置session的语法是session.setAttribute(“session名”,要放入的对象)。而session监听，监听的是HTTP连接，只要有用户与server连接，就算连接的是一个空白的jsp页面，也会触发session事件，所以此处的session实际上指的是connection，用来统计当前在线用户数最合适了。不知道我说清楚了没有。下面分别讲解这两种监听方式。<br /><br />1、 session监听<br /><br />　　 首先编写一个session监听类，实作HttpSessionListener接口，它的作用是计算当前有多少个在线用户：<br /><br /></p><div class="codeStyle"><ol><li><i><font color="#339900">/**</font></i></li><li><i><font color="#339900">*@Author bromon</font></i></li><li><i><font color="#339900">*2004-6-12</font></i></li><li><i><font color="#339900">*/</font></i></li><li><b><font color="#0000ff">package</font></b> org.bromon.test; 
</li><li></li><li><b><font color="#0000ff">import</font></b> javax.servlet.*; 
</li><li><b><font color="#0000ff">import</font></b> javax.servlet.http.*; 
</li><li></li><li><b><font color="#0000ff">public</font></b> <b><font color="#0000ff">class</font></b> SessionCount <b><font color="#0000ff">implements</font></b> <a href="http://www.javaresearch.org/source/j2ee1.3.1/javax/servlet/http/HttpSessionListener.java.html" target="_blank"><font class="classLink"><u>HttpSessionListener</u></font></a></li><li>{ 
</li><li>    <b><font color="#0000ff">private</font></b> <b><font color="#0000ff">static</font></b> <b><font color="#0000ff">int</font></b> count=0; 
</li><li></li><li>    <b><font color="#0000ff">public</font></b> <b><font color="#0000ff">void</font></b> sessionCreated(<a href="http://www.javaresearch.org/source/j2ee1.3.1/javax/servlet/http/HttpSessionEvent.java.html" target="_blank"><font class="classLink"><u>HttpSessionEvent</u></font></a> se) 
</li><li>    { 
</li><li>        count++; 
</li><li>        <b><a href="http://www.javaresearch.org/source/jdk142/java/lang/System.java.html" target="_blank"><font class="classLink"><u>System</u></font></a></b>.out.println(“session创建：”+<b><font color="#0000ff">new</font></b> java.util.<b><a href="http://www.javaresearch.org/source/jdk142/java/util/Date.java.html" target="_blank"><font class="classLink"><u>Date</u></font></a></b>()); 
</li><li>    } 
</li><li></li><li>    <b><font color="#0000ff">public</font></b> <b><font color="#0000ff">void</font></b> sessionDestroyed(<a href="http://www.javaresearch.org/source/j2ee1.3.1/javax/servlet/http/HttpSessionEvent.java.html" target="_blank"><font class="classLink"><u>HttpSessionEvent</u></font></a> se) 
</li><li>    { 
</li><li>       count--; 
</li><li>       <b><a href="http://www.javaresearch.org/source/jdk142/java/lang/System.java.html" target="_blank"><font class="classLink"><u>System</u></font></a></b>.out.println(“session销毁:”+<b><font color="#0000ff">new</font></b> java.util.<b><a href="http://www.javaresearch.org/source/jdk142/java/util/Date.java.html" target="_blank"><font class="classLink"><u>Date</u></font></a></b>()); 
</li><li>    } 
</li><li></li><li>    <b><font color="#0000ff">public</font></b> <b><font color="#0000ff">static</font></b> <b><font color="#0000ff">int</font></b> getCount() 
</li><li>    { 
</li><li>       <b><font color="#0000ff">return</font></b>(count); 
</li><li>     } 
</li><li>} </li></ol></div><br /><br /><br />　　 怎么样，是不是一目了然？count被定义为static，是因为要保证整个系统只有这一个count。如果你实在不放心，可以把它写成一个单例类。<br /><br />　　 然后在web.xml中声明这个监听器：<br />&lt;listener&gt;<br />&lt;listener-class&gt;<br />org.bromon.test.SessionCount<br />&lt;/listener-class&gt;<br />&lt;/listener&gt;<br /><br />　　 编写一个测试页面test.jsp，内容是获得count：<br />&lt;%<br />int count=org.bromon.test.SessionCount.getCount();<br />out.println(count);<br />%&gt;<br /><br />　　 需要注意的是，这里根本不涉及任何session的操作。重启动App server，试着连接test.jsp，可以看到监听器已经开始工作。<br /><br />2、 Attribute监听<br />　　 作为一个站内消息系统，肯定要获得所有登陆者的ID，才有可能互发消息。这就涉及Attribute监听。假设我们写了个用户登陆的模块，用户通过身份验证之后会产生一个session，保存它的相关信息，比如：<br /><div class="codeStyle"><ol><li><i><font color="#339900">//check.jsp</font></i></li><li>&lt;% 
</li><li>    <b><a href="http://www.javaresearch.org/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink"><u>String</u></font></a></b> name=request.getParameter(“name”); 
</li><li>    <font color="#ff0000">Name</font>=<b><font color="#0000ff">new</font></b> <b><a href="http://www.javaresearch.org/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink"><u>String</u></font></a></b>(name.getBytes(“ISO8859-1”)); 
</li><li>    session.setAttribute(“user”,name); 
</li><li>%&gt; </li></ol></div><br /><br />　　 做过jsp的兄弟应该对这段代码再熟悉不过了，下面写个监听器来监听用户登陆，把所有用户的ID保存到一个List当中，这个监听器实作HttpSessionAttributeListener接口：<br /><br /><div class="codeStyle"><ol><li><i><font color="#339900">/**</font></i></li><li><i><font color="#339900">*@Author bromon</font></i></li><li><i><font color="#339900">*2004-6-12</font></i></li><li><i><font color="#339900">*/</font></i></li><li><b><font color="#0000ff">package</font></b> org.bromon.test; 
</li><li></li><li><b><font color="#0000ff">import</font></b> javax.servlet.*; 
</li><li><b><font color="#0000ff">import</font></b> javax.servlet.http.*; 
</li><li><b><font color="#0000ff">import</font></b> java.util.*; 
</li><li></li><li><b><font color="#0000ff">public</font></b> <b><font color="#0000ff">class</font></b> OnlineList <b><font color="#0000ff">implements</font></b> <a href="http://www.javaresearch.org/source/j2ee1.3.1/javax/servlet/http/HttpSessionAttributeListener.java.html" target="_blank"><font class="classLink"><u>HttpSessionAttributeListener</u></font></a></li><li>{ 
</li><li>    <b><font color="#0000ff">private</font></b> <b><font color="#0000ff">static</font></b> <b><a href="http://www.javaresearch.org/source/jdk142/java/util/List.java.html" target="_blank"><font class="classLink"><u>List</u></font></a></b> list=<b><font color="#0000ff">new</font></b> <b><a href="http://www.javaresearch.org/source/jdk142/java/util/ArrayList.java.html" target="_blank"><font class="classLink"><u>ArrayList</u></font></a></b>(); 
</li><li></li><li>    <b><font color="#0000ff">public</font></b> <b><font color="#0000ff">void</font></b> attributeAdded(<a href="http://www.javaresearch.org/source/j2ee1.3.1/javax/servlet/http/HttpSessionBindingEvent.java.html" target="_blank"><font class="classLink"><u>HttpSessionBindingEvent</u></font></a> se) 
</li><li>    { 
</li><li>        <b><font color="#0000ff">if</font></b>(“user”.equals(se.getName())) 
</li><li>        { 
</li><li>            list.add(se.getValue()); 
</li><li>         } 
</li><li>    } 
</li><li></li><li>    <b><font color="#0000ff">public</font></b> <b><font color="#0000ff">void</font></b> attributeRemoved(<a href="http://www.javaresearch.org/source/j2ee1.3.1/javax/servlet/http/HttpSessionBindingEvent.java.html" target="_blank"><font class="classLink"><u>HttpSessionBindingEvent</u></font></a> se) 
</li><li>    { 
</li><li>         <b><font color="#0000ff">if</font></b>(“user”.equals(se.getName())) 
</li><li>         { 
</li><li>            list.remove(se.getValue()); 
</li><li>         } 
</li><li>    } 
</li><li></li><li>    <b><font color="#0000ff">public</font></b> <b><font color="#0000ff">void</font></b> attributeReplaced(<a href="http://www.javaresearch.org/source/j2ee1.3.1/javax/servlet/http/HttpSessionBindingEvent.java.html" target="_blank"><font class="classLink"><u>HttpSessionBindingEvent</u></font></a> se){} 
</li><li></li><li>    <b><font color="#0000ff">public</font></b> <b><font color="#0000ff">static</font></b> <b><a href="http://www.javaresearch.org/source/jdk142/java/util/List.java.html" target="_blank"><font class="classLink"><u>List</u></font></a></b> getList() 
</li><li>    { 
</li><li>         <b><font color="#0000ff">return</font></b>(list); 
</li><li>     } 
</li><li>} </li></ol></div><br /><br />写个简单的jsp来得到用户列表：<br />&lt;%<br />    java.util.List list=org.bromon.test.OnlineList.getList();<br />    out.println(“共有”+list.size()+”名用户已登陆：”);<br />    for(int I=0;I&lt;lise.size();i++)<br />    {<br />        out.println(list.get(i));<br />    }<br />%&gt;<br /><br />也许你说，这有什么神奇呢，监听session而已，不着急，看看xmlhttp。<br /><br />二、 XMLHTTP<br /><br />　　 XMLHTTP的用处很多，这里只说我们需要的，就是无刷新的与server通信，看这段代码：<br /><br /><div class="codeStyle"><ol><li>&lt;script language=<font color="#ff33ff">"javascript"</font>&gt;  
</li><li>xml = <b><font color="#0000ff">new</font></b> ActiveXObject(<font color="#ff33ff">"Microsoft.XMLHTTP"</font>);  
</li><li>var post=<font color="#ff33ff">" "</font>;<i><font color="#339900">//构造要携带的数据 </font></i></li><li>xml.open(<font color="#ff33ff">"POST"</font>,<font color="#ff33ff">"http://localhost:7001/TestWL/index.jsp"</font>,<b><font color="#0000ff">false</font></b>);<i><font color="#339900">//使用POST方法打开一个到服务器的连接 </font></i></li><li>xml.setrequestheader(<font color="#ff33ff">"content-length"</font>,post.<b><font color="#0000ff">length</font></b>);  
</li><li>xml.setrequestheader(<font color="#ff33ff">"content-type"</font>,<font color="#ff33ff">"application/x-www-form-urlencoded"</font>);  
</li><li>xml.send(post);<i><font color="#339900">//发送数据 </font></i></li><li>var res = xml.responseText;<i><font color="#339900">//接收服务器返回的数据 </font></i></li><li>document.write(res);  
</li><li>&lt;/script&gt; </li></ol></div><br /><br /><br />　　 豁然开朗，这段代码就是打开一个HTTP连接，以标准的HTTP格式传递数据，如果你喜欢，可以用XML的格式来传递。更改一下xml对象的构造方式就可以兼容Mozilla和Netscape。下面来写一个轮询，每隔一段时间刷新一次用户列表，当然，是不需要刷新页面的：<br /><br /><div class="codeStyle"><ol><li>&lt;html&gt; 
</li><li>&lt;head&gt;&lt;title&gt;探测器&lt;/title&gt; 
</li><li>&lt;script language=<font color="#ff33ff">"javascript"</font>&gt; 
</li><li>function detect() 
</li><li>{ 
</li><li>xml = <b><font color="#0000ff">new</font></b> ActiveXObject(<font color="#ff33ff">"Microsoft.XMLHTTP"</font>);  
</li><li>var post=<font color="#ff33ff">" "</font>;<i><font color="#339900">//构造要携带的数据 </font></i></li><li>xml.open(<font color="#ff33ff">"POST"</font>,<font color="#ff33ff">"http://localhost:7001/TestWL/index.jsp"</font>,<b><font color="#0000ff">false</font></b>);<i><font color="#339900">//使用POST方法打开一个到服务器的连接，以异步方式通信 </font></i></li><li>xml.setrequestheader(<font color="#ff33ff">"content-length"</font>,post.<b><font color="#0000ff">length</font></b>);  
</li><li>xml.setrequestheader(<font color="#ff33ff">"content-type"</font>,<font color="#ff33ff">"application/x-www-form-urlencoded"</font>);  
</li><li>xml.send(post);<i><font color="#339900">//发送数据 </font></i></li><li>var res = xml.responseText;<i><font color="#339900">//接收服务器返回的数据 </font></i></li><li>list.innerText=res; 
</li><li>setTimeout(“detect()”,5000);<i><font color="#339900">//每隔5秒钟轮询一次</font></i></li><li>}  
</li><li>&lt;/script&gt; 
</li><li>&lt;body onload=”detect()”&gt; 
</li><li>&lt;a id=”list”&gt;&lt;/a&gt; 
</li><li>&lt;/body&gt; 
</li><li>&lt;/html&gt; </li></ol></div><br /><br />　　 这样的通信方式数据量很小，不用重新传递整个页面，5秒钟轮一次，普通PC也能承受较大的在线数。构造一个探测器来监听在线列表和消息，效果是很好的，即使你的客户坐在电脑前袖手旁观，键鼠都不碰一下，也能保证数据即时传递，页面也不会发生跳转和刷新。<br /><br />　　 Session监听加上XMLHTTP通信，开发一个较为完善的站内消息系统实在易如反掌。 <br /><img src ="http://www.blogjava.net/jelver/aggbug/43316.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-04-26 15:35 <a href="http://www.blogjava.net/jelver/articles/43316.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于web.xml配置的详细说明</title><link>http://www.blogjava.net/jelver/articles/40920.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Thu, 13 Apr 2006 07:58:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/40920.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/40920.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/40920.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/40920.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/40920.html</trackback:ping><description><![CDATA[
		<font face="Arial">1 定义头和根元素<br /><br />部署描述符文件就像所有XML文件一样，必须以一个XML头开始。这个头声明可以使用的XML版本并给出文件的字符编码。<br />DOCYTPE声明必须立即出现在此头之后。这个声明告诉服务器适用的servlet规范的版本（如2.2或2.3）并指定管理此文件其余部分内容的语法的DTD(Document Type Definition，文档类型定义)。<br />所有部署描述符文件的顶层（根）元素为web-app。请注意，XML元素不像HTML，他们是大小写敏感的。因此，web-App和WEB-APP都是不合法的，web-app必须用小写。<br /><br />2 部署描述符文件内的元素次序<br /><br />XML 元素不仅是大小写敏感的，而且它们还对出现在其他元素中的次序敏感。例如，XML头必须是文件中的第一项，DOCTYPE声明必须是第二项，而web- app元素必须是第三项。在web-app元素内，元素的次序也很重要。服务器不一定强制要求这种次序，但它们允许（实际上有些服务器就是这样做的）完全拒绝执行含有次序不正确的元素的Web应用。这表示使用非标准元素次序的web.xml文件是不可移植的。<br />下面的列表给出了所有可直接出现在web-app元素内的合法元素所必需的次序。例如，此列表说明servlet元素必须出现在所有servlet-mapping元素之前。请注意，所有这些元素都是可选的。因此，可以省略掉某一元素，但不能把它放于不正确的位置。<br />l icon icon元素指出IDE和GUI工具用来表示Web应用的一个和两个图像文件的位置。<br />l display-name display-name元素提供GUI工具可能会用来标记这个特定的Web应用的一个名称。<br />l description description元素给出与此有关的说明性文本。<br />l context-param context-param元素声明应用范围内的初始化参数。<br />l filter 过滤器元素将一个名字与一个实现javax.servlet.Filter接口的类相关联。<br />l filter-mapping 一旦命名了一个过滤器，就要利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。<br />l listener servlet API的版本2.3增加了对事件监听程序的支持，事件监听程序在建立、修改和删除会话或servlet环境时得到通知。Listener元素指出事件监听程序类。<br />l servlet 在向servlet或JSP页面制定初始化参数或定制URL时，必须首先命名servlet或JSP页面。Servlet元素就是用来完成此项任务的。<br />l servlet-mapping 服务器一般为servlet提供一个缺省的URL：</font>
		<a href="http://host/webAppPrefix/servlet/ServletName">
				<font face="Arial">http://host/webAppPrefix/servlet/ServletName</font>
		</a>
		<font face="Arial">。但是，常常会更改这个URL，以便servlet可以访问初始化参数或更容易地处理相对URL。在更改缺省URL时，使用servlet-mapping元素。<br />l session-config 如果某个会话在一定时间内未被访问，服务器可以抛弃它以节省内存。可通过使用HttpSession的setMaxInactiveInterval方法明确设置单个会话对象的超时值，或者可利用session-config元素制定缺省超时值。<br />l mime-mapping 如果Web应用具有想到特殊的文件，希望能保证给他们分配特定的MIME类型，则mime-mapping元素提供这种保证。<br />l welcom-file-list welcome-file-list元素指示服务器在收到引用一个目录名而不是文件名的URL时，使用哪个文件。<br />l error-page error-page元素使得在返回特定HTTP状态代码时，或者特定类型的异常被抛出时，能够制定将要显示的页面。<br />l taglib taglib元素对标记库描述符文件（Tag Libraryu Descriptor file）指定别名。此功能使你能够更改TLD文件的位置，而不用编辑使用这些文件的JSP页面。<br />l resource-env-ref resource-env-ref元素声明与资源相关的一个管理对象。<br />l resource-ref resource-ref元素声明一个资源工厂使用的外部资源。<br />l security-constraint security-constraint元素制定应该保护的URL。它与login-config元素联合使用<br />l login-config 用login-config元素来指定服务器应该怎样给试图访问受保护页面的用户授权。它与sercurity-constraint元素联合使用。<br />l security-role security-role元素给出安全角色的一个列表，这些角色将出现在servlet元素内的security-role-ref元素的role-name子元素中。分别地声明角色可使高级IDE处理安全信息更为容易。<br />l env-entry env-entry元素声明Web应用的环境项。<br />l ejb-ref ejb-ref元素声明一个EJB的主目录的引用。<br />l ejb-local-ref ejb-local-ref元素声明一个EJB的本地主目录的应用。<br /><br />3 分配名称和定制的UL<br /><br />在web.xml中完成的一个最常见的任务是对servlet或JSP页面给出名称和定制的URL。用servlet元素分配名称，使用servlet-mapping元素将定制的URL与刚分配的名称相关联。<br />3.1 分配名称<br />为了提供初始化参数，对servlet或JSP页面定义一个定制URL或分配一个安全角色，必须首先给servlet或JSP页面一个名称。可通过 servlet元素分配一个名称。最常见的格式包括servlet-name和servlet-class子元素（在web-app元素内），如下所示：<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;moreservlets.TestServlet&lt;/servlet-class&gt;<br />&lt;/servlet&gt; <br />这表示位于WEB-INF/classes/moreservlets/TestServlet的servlet已经得到了注册名Test。给 servlet一个名称具有两个主要的含义。首先，初始化参数、定制的URL模式以及其他定制通过此注册名而不是类名引用此servlet。其次,可在 URL而不是类名中使用此名称。因此，利用刚才给出的定义，URL </font>
		<a href="http://host/webAppPrefix/servlet/Test">
				<font face="Arial">http://host/webAppPrefix/servlet/Test</font>
		</a>
		<font face="Arial"> 可用于 </font>
		<a href="http://host/webAppPrefix/servlet/moreservlets.TestServlet">
				<font face="Arial">http://host/webAppPrefix/servlet/moreservlets.TestServlet</font>
		</a>
		<font face="Arial"> 的场所。<br />请记住：XML元素不仅是大小写敏感的，而且定义它们的次序也很重要。例如，web-app元素内所有servlet元素必须位于所有servlet- mapping元素（下一小节介绍）之前，而且还要位于5.6节和5.11节讨论的与过滤器或文档相关的元素（如果有的话）之前。类似地，servlet 的servlet-name子元素也必须出现在servlet-class之前。5.2节"部署描述符文件内的元素次序"将详细介绍这种必需的次序。<br />例如，程序清单5-1给出了一个名为TestServlet的简单servlet，它驻留在moreservlets程序包中。因为此servlet是扎根在一个名为deployDemo的目录中的Web应用的组成部分，所以TestServlet.class放在deployDemo/WEB- INF/classes/moreservlets中。程序清单5-2给出将放置在deployDemo/WEB-INF/内的web.xml文件的一部分。此web.xml文件使用servlet-name和servlet-class元素将名称Test与TestServlet.class相关联。图 5-1和图5-2分别显示利用缺省URL和注册名调用TestServlet时的结果。<br /><br />程序清单5-1 TestServlet.java<br />package moreservlets;<br /><br />import java.io.*;<br />import javax.servlet.*;<br />import javax.servlet.http.*;<br /><br />/** Simple servlet used to illustrate servlet naming<br />* and custom URLs.<br />* &lt;P&gt;<br />* Taken from More Servlets and JavaServer Pages<br />* from Prentice Hall and Sun Microsystems Press,<br />* </font>
		<a href="http://www.moreservlets.com/">
				<font face="Arial">http://www.moreservlets.com/</font>
		</a>
		<font face="Arial">.<br />* © 2002 Marty Hall; may be freely used or adapted.<br />*/<br /><br />public class TestServlet extends HttpServlet {<br />public void doGet(HttpServletRequest request,<br />HttpServletResponse response)<br />throws ServletException, IOException {<br />response.setContentType("text/html");<br />PrintWriter out = response.getWriter();<br />String uri = request.getRequestURI();<br />out.println(ServletUtilities.headWithTitle("Test Servlet") +<br />"&lt;BODY BGCOLOR=\"#FDF5E6\"&gt;\n" +<br />"&lt;H2&gt;URI: " + uri + "&lt;/H2&gt;\n" +<br />"&lt;/BODY&gt;&lt;/HTML&gt;");<br />}<br />}<br /><br /><br />程序清单5-2 web.xml（说明servlet名称的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;<br /><br />&lt;web-app&gt;<br />&lt;!-- … --&gt;<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;moreservlets.TestServlet&lt;/servlet-class&gt;<br />&lt;/servlet&gt;<br />&lt;!-- … --&gt;<br />&lt;/web-app&gt;<br /><br />3.2 定义定制的URL<br />大多数服务器具有一个缺省的serlvet URL：<br />http://host/webAppPrefix/servlet/packageName.ServletName。虽然在开发中使用这个URL很方便，但是我们常常会希望另一个URL用于部署。例如，可能会需要一个出现在Web应用顶层的URL（如，http: //host/webAppPrefix/Anyname），并且在此URL中没有servlet项。位于顶层的URL简化了相对URL的使用。此外，对许多开发人员来说，顶层URL看上去比更长更麻烦的缺省URL更简短。<br />事实上，有时需要使用定制的URL。比如，你可能想关闭缺省URL映射，以便更好地强制实施安全限制或防止用户意外地访问无初始化参数的servlet。如果你禁止了缺省的URL，那么你怎样访问servlet呢？这时只有使用定制的URL了。<br />为了分配一个定制的URL，可使用servlet-mapping元素及其servlet-name和url-pattern子元素。Servlet- name元素提供了一个任意名称，可利用此名称引用相应的servlet；url-pattern描述了相对于Web应用的根目录的URL。url- pattern元素的值必须以斜杠（/）起始。<br />下面给出一个简单的web.xml摘录，它允许使用URL http://host/webAppPrefix/UrlTest而不是http://host/webAppPrefix/servlet/Test或<br />http: //host/webAppPrefix/servlet/moreservlets.TestServlet。请注意，仍然需要XML头、 DOCTYPE声明以及web-app封闭元素。此外，可回忆一下，XML元素出现地次序不是随意的。特别是，需要把所有servlet元素放在所有 servlet-mapping元素之前。<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;moreservlets.TestServlet&lt;/servlet-class&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/UrlTest&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />URL模式还可以包含通配符。例如，下面的小程序指示服务器发送所有以Web应用的URL前缀开始，以..asp结束的请求到名为BashMS的servlet。<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;BashMS&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;msUtils.ASPTranslator&lt;/servlet-class&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt;BashMS&lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/*.asp&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />3.3 命名JSP页面<br />因为JSP页面要转换成sevlet，自然希望就像命名servlet一样命名JSP页面。毕竟，JSP页面可能会从初始化参数、安全设置或定制的URL中受益，正如普通的serlvet那样。虽然JSP页面的后台实际上是servlet这句话是正确的，但存在一个关键的猜疑：即，你不知道JSP页面的实际类名（因为系统自己挑选这个名字）。因此，为了命名JSP页面，可将jsp-file元素替换为servlet-calss元素，如下所示：<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />&lt;jsp-file&gt;/TestPage.jsp&lt;/jsp-file&gt;<br />&lt;/servlet&gt;<br />命名JSP页面的原因与命名servlet的原因完全相同：即为了提供一个与定制设置（如，初始化参数和安全设置）一起使用的名称，并且，以便能更改激活 JSP页面的URL（比方说，以便多个URL通过相同页面得以处理，或者从URL中去掉.jsp扩展名）。但是，在设置初始化参数时，应该注意，JSP页面是利用jspInit方法，而不是init方法读取初始化参数的。<br />例如，程序清单5-3给出一个名为TestPage.jsp的简单JSP页面，它的工作只是打印出用来激活它的URL的本地部分。TestPage.jsp放置在deployDemo应用的顶层。程序清单5-4给出了用来分配一个注册名PageName，然后将此注册名与http://host/webAppPrefix/UrlTest2/anything 形式的URL相关联的web.xml文件（即，deployDemo/WEB-INF/web.xml）的一部分。<br /><br />程序清单5-3 TestPage.jsp<br />&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />&lt;HTML&gt;<br />&lt;HEAD&gt;<br />&lt;TITLE&gt;<br />JSP Test Page<br />&lt;/TITLE&gt;<br />&lt;/HEAD&gt;<br />&lt;BODY BGCOLOR="#FDF5E6"&gt;<br />&lt;H2&gt;URI: &lt;%= request.getRequestURI() %&gt;&lt;/H2&gt;<br />&lt;/BODY&gt;<br />&lt;/HTML&gt;<br /><br /><br />程序清单5-4 web.xml（说明JSP页命名的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;<br /><br />&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />&lt;jsp-file&gt;/TestPage.jsp&lt;/jsp-file&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt; PageName &lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/UrlTest2/*&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;<br /><br /><br />4 禁止激活器servlet<br /><br />对servlet或JSP页面建立定制URL的一个原因是，这样做可以注册从 init（servlet）或jspInit（JSP页面）方法中读取得初始化参数。但是，初始化参数只在是利用定制URL模式或注册名访问 servlet或JSP页面时可以使用，用缺省URL http://host/webAppPrefix/servlet/ServletName 访问时不能使用。因此，你可能会希望关闭缺省URL，这样就不会有人意外地调用初始化servlet了。这个过程有时称为禁止激活器servlet，因为多数服务器具有一个用缺省的servlet URL注册的标准servlet，并激活缺省的URL应用的实际servlet。<br />有两种禁止此缺省URL的主要方法：<br />l 在每个Web应用中重新映射/servlet/模式。<br />l 全局关闭激活器servlet。<br />重要的是应该注意到，虽然重新映射每个Web应用中的/servlet/模式比彻底禁止激活servlet所做的工作更多，但重新映射可以用一种完全可移植的方式来完成。相反，全局禁止激活器servlet完全是针对具体机器的，事实上有的服务器（如ServletExec）没有这样的选择。下面的讨论对每个Web应用重新映射/servlet/ URL模式的策略。后面提供在Tomcat中全局禁止激活器servlet的详细内容。<br />4.1 重新映射/servlet/URL模式<br />在一个特定的Web应用中禁止以http://host/webAppPrefix/servlet/ 开始的URL的处理非常简单。所需做的事情就是建立一个错误消息servlet，并使用前一节讨论的url-pattern元素将所有匹配请求转向该 servlet。只要简单地使用：<br />&lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br />作为servlet-mapping元素中的模式即可。<br />例如，程序清单5-5给出了将SorryServlet servlet（程序清单5-6）与所有以http://host/webAppPrefix/servlet/ 开头的URL相关联的部署描述符文件的一部分。<br /><br />程序清单5-5 web.xml（说明JSP页命名的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;<br /><br />&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;Sorry&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;moreservlets.SorryServlet&lt;/servlet-class&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt; Sorry &lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;<br /><br /><br />程序清单5-6 SorryServlet.java<br />package moreservlets;<br /><br />import java.io.*;<br />import javax.servlet.*;<br />import javax.servlet.http.*;<br /><br />/** Simple servlet used to give error messages to<br />* users who try to access default servlet URLs<br />* (i.e., http://host/webAppPrefix/servlet/ServletName)<br />* in Web applications that have disabled this<br />* behavior.<br />* &lt;P&gt;<br />* Taken from More Servlets and JavaServer Pages<br />* from Prentice Hall and Sun Microsystems Press,<br />* http://www.moreservlets.com/.<br />* © 2002 Marty Hall; may be freely used or adapted.<br />*/<br /><br />public class SorryServlet extends HttpServlet {<br />public void doGet(HttpServletRequest request,<br />HttpServletResponse response)<br />throws ServletException, IOException {<br />response.setContentType("text/html");<br />PrintWriter out = response.getWriter();<br />String title = "Invoker Servlet Disabled.";<br />out.println(ServletUtilities.headWithTitle(title) +<br />"&lt;BODY BGCOLOR=\"#FDF5E6\"&gt;\n" +<br />"&lt;H2&gt;" + title + "&lt;/H2&gt;\n" +<br />"Sorry, access to servlets by means of\n" +<br />"URLs that begin with\n" +<br />"http://host/webAppPrefix/servlet/\n" +<br />"has been disabled.\n" + <br />"&lt;/BODY&gt;&lt;/HTML&gt;");<br />}<br /><br />public void doPost(HttpServletRequest request,<br />HttpServletResponse response)<br />throws ServletException, IOException {<br />doGet(request, response);<br />}<br />}<br /><br /><br />4.2 全局禁止激活器：Tomcat<br />Tomcat 4中用来关闭缺省URL的方法与Tomcat 3中所用的很不相同。下面介绍这两种方法：<br />1．禁止激活器： Tomcat 4<br />Tomcat 4用与前面相同的方法关闭激活器servlet，即利用web.xml中的url-mapping元素进行关闭。不同之处在于Tomcat使用了放在 install_dir/conf中的一个服务器专用的全局web.xml文件，而前面使用的是存放在每个Web应用的WEB-INF目录中的标准 web.xml文件。<br />因此，为了在Tomcat 4中关闭激活器servlet，只需在install_dir/conf/web.xml中简单地注释出/servlet/* URL映射项即可，如下所示：<br />&lt;!-- <br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt;invoker&lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />--&gt;<br />再次提醒，应该注意这个项是位于存放在install_dir/conf的Tomcat专用的web.xml文件中的，此文件不是存放在每个Web应用的WEB-INF目录中的标准web.xml。<br />2．禁止激活器：Tomcat3<br />在Apache Tomcat的版本3中，通过在install_dir/conf/server.xml中注释出InvokerInterceptor项全局禁止缺省 servlet URL。例如，下面是禁止使用缺省servlet URL的server.xml文件的一部分。<br />&lt;!-- <br />&lt;RequsetInterceptor <br />className="org.apache.tomcat.request.InvokerInterceptor"<br />debug="0" prefix="/servlet/" /&gt;<br />--&gt;<br /><br />5 初始化和预装载servlet与JSP页面<br /><br />这里讨论控制servlet和JSP页面的启动行为的方法。特别是，说明了怎样分配初始化参数以及怎样更改服务器生存期中装载servlet和JSP页面的时刻。<br />5.1 分配servlet初始化参数<br />利用init-param元素向servlet提供初始化参数，init-param元素具有param-name和param-value子元素。例如，在下面的例子中，如果initServlet servlet是利用它的注册名（InitTest）访问的，它将能够从其方法中调用getServletConfig(). getInitParameter("param1")获得"Value 1"，调用getServletConfig().getInitParameter("param2")获得"2"。<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;InitTest&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;moreservlets.InitServlet&lt;/servlet-class&gt;<br />&lt;init-param&gt;<br />&lt;param-name&gt;param1&lt;/param-name&gt;<br />&lt;param-value&gt;value1&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />&lt;init-param&gt;<br />&lt;param-name&gt;param2&lt;/param-name&gt;<br />&lt;param-value&gt;2&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />&lt;/servlet&gt;<br />在涉及初始化参数时，有几点需要注意：<br />l 返回值。GetInitParameter的返回值总是一个String。因此，在前一个例子中，可对param2使用Integer.parseInt获得一个int。<br />l JSP中的初始化。JSP页面使用jspInit而不是init。JSP页面还需要使用jsp-file元素代替servlet-class。<br />l 缺省URL。初始化参数只在通过它们的注册名或与它们注册名相关的定制URL模式访问Servlet时可以使用。因此，在这个例子中，param1和 param2初始化参数将能够在使用URL http://host/webAppPrefix/servlet/InitTest 时可用，但在使用URL http://host/webAppPrefix/servlet/myPackage.InitServlet 时不能使用。<br />例如，程序清单5-7给出一个名为InitServlet的简单servlet，它使用init方法设置firstName和emailAddress字段。程序清单5-8给出分配名称InitTest给servlet的web.xml文件。<br />程序清单5-7 InitServlet.java<br />package moreservlets;<br /><br />import java.io.*;<br />import javax.servlet.*;<br />import javax.servlet.http.*;<br /><br />/** Simple servlet used to illustrate servlet<br />* initialization parameters.<br />* &lt;P&gt;<br />* Taken from More Servlets and JavaServer Pages<br />* from Prentice Hall and Sun Microsystems Press,<br />* http://www.moreservlets.com/.<br />* © 2002 Marty Hall; may be freely used or adapted.<br />*/<br /><br />public class InitServlet extends HttpServlet {<br />private String firstName, emailAddress;<br /><br />public void init() {<br />ServletConfig config = getServletConfig();<br />firstName = config.getInitParameter("firstName");<br />emailAddress = config.getInitParameter("emailAddress");<br />}<br /><br />public void doGet(HttpServletRequest request,<br />HttpServletResponse response)<br />throws ServletException, IOException {<br />response.setContentType("text/html");<br />PrintWriter out = response.getWriter();<br />String uri = request.getRequestURI();<br />out.println(ServletUtilities.headWithTitle("Init Servlet") +<br />"&lt;BODY BGCOLOR=\"#FDF5E6\"&gt;\n" +<br />"&lt;H2&gt;Init Parameters:&lt;/H2&gt;\n" +<br />"&lt;UL&gt;\n" +<br />"&lt;LI&gt;First name: " + firstName + "\n" +<br />"&lt;LI&gt;Email address: " + emailAddress + "\n" +<br />"&lt;/UL&gt;\n" + <br />"&lt;/BODY&gt;&lt;/HTML&gt;");<br />}<br />}<br /><br /><br />程序清单5-8 web.xml（说明初始化参数的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;<br /><br />&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;InitTest&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;moreservlets.InitServlet&lt;/servlet-class&gt;<br />&lt;init-param&gt;<br />&lt;param-name&gt;firstName&lt;/param-name&gt;<br />&lt;param-value&gt;Larry&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />&lt;init-param&gt;<br />&lt;param-name&gt;emailAddress&lt;/param-name&gt;<br />&lt;param-value&gt;Ellison@Microsoft.com&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;<br /><br />5.2 分配JSP初始化参数<br />给JSP页面提供初始化参数在三个方面不同于给servlet提供初始化参数。<br />1）使用jsp-file而不是servlet-class。因此，WEB-INF/web.xml文件的servlet元素如下所示：<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />&lt;jsp-file&gt;/RealPage.jsp&lt;/jsp-file&gt;<br />&lt;init-param&gt;<br />&lt;param-name&gt;...&lt;/param-name&gt;<br />&lt;param-value&gt;...&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />...<br />&lt;/servlet&gt;<br />2) 几乎总是分配一个明确的URL模式。对servlet，一般相应地使用以http://host/webAppPrefix/servlet/ 开始的缺省URL。只需记住，使用注册名而不是原名称即可。这对于JSP页面在技术上也是合法的。例如，在上面给出的例子中，可用URL http://host/webAppPrefix/servlet/PageName 访问RealPage.jsp的对初始化参数具有访问权的版本。但在用于JSP页面时，许多用户似乎不喜欢应用常规的servlet的URL。此外，如果 JSP页面位于服务器为其提供了目录清单的目录中（如，一个既没有index.html也没有index.jsp文件的目录），则用户可能会连接到此 JSP页面，单击它，从而意外地激活未初始化的页面。因此，好的办法是使用url-pattern（5.3节）将JSP页面的原URL与注册的 servlet名相关联。这样，客户机可使用JSP页面的普通名称，但仍然激活定制的版本。例如，给定来自项目1的servlet定义，可使用下面的 servlet-mapping定义：<br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/RealPage.jsp&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />3）JSP页使用jspInit而不是init。自动从JSP页面建立的servlet或许已经使用了inti方法。因此，使用JSP声明提供一个init方法是不合法的，必须制定jspInit方法。<br />为了说明初始化JSP页面的过程，程序清单5-9给出了一个名为InitPage.jsp的JSP页面，它包含一个jspInit方法且放置于 deployDemo Web应用层次结构的顶层。一般，http://host/deployDemo/InitPage.jsp 形式的URL将激活此页面的不具有初始化参数访问权的版本，从而将对firstName和emailAddress变量显示null。但是， web.xml文件（程序清单5-10）分配了一个注册名，然后将该注册名与URL模式/InitPage.jsp相关联。<br /><br />程序清单5-9 InitPage.jsp<br />&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />&lt;HTML&gt;<br />&lt;HEAD&gt;&lt;TITLE&gt;JSP Init Test&lt;/TITLE&gt;&lt;/HEAD&gt;<br />&lt;BODY BGCOLOR="#FDF5E6"&gt;<br />&lt;H2&gt;Init Parameters:&lt;/H2&gt;<br />&lt;UL&gt;<br />&lt;LI&gt;First name: &lt;%= firstName %&gt;<br />&lt;LI&gt;Email address: &lt;%= emailAddress %&gt;<br />&lt;/UL&gt;<br />&lt;/BODY&gt;&lt;/HTML&gt;<br />&lt;%!<br />private String firstName, emailAddress;<br /><br />public void jspInit() {<br />ServletConfig config = getServletConfig();<br />firstName = config.getInitParameter("firstName");<br />emailAddress = config.getInitParameter("emailAddress");<br />}<br />%&gt;<br /><br /><br />程序清单5-10 web.xml（说明JSP页面的init参数的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;<br /><br />&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;InitPage&lt;/servlet-name&gt;<br />&lt;jsp-file&gt;/InitPage.jsp&lt;/jsp-file&gt;<br />&lt;init-param&gt;<br />&lt;param-name&gt;firstName&lt;/param-name&gt;<br />&lt;param-value&gt;Bill&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />&lt;init-param&gt;<br />&lt;param-name&gt;emailAddress&lt;/param-name&gt;<br />&lt;param-value&gt;gates@oracle.com&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt; <br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt; InitPage&lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/InitPage.jsp&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;<br /><br /><br />5.3 提供应用范围内的初始化参数<br />一般，对单个地servlet或JSP页面分配初始化参数。指定的servlet或JSP页面利用ServletConfig的getInitParameter方法读取这些参数。但是，在某些情形下，希望提供可由任意servlet或JSP页面借助ServletContext的getInitParameter方法读取的系统范围内的初始化参数。<br />可利用context-param元素声明这些系统范围内的初始化值。context-param元素应该包含param-name、param-value以及可选的description子元素，如下所示：<br />&lt;context-param&gt;<br />&lt;param-name&gt;support-email&lt;/param-name&gt;<br />&lt;param-value&gt;blackhole@mycompany.com&lt;/param-value&gt;<br />&lt;/context-param&gt;<br />可回忆一下，为了保证可移植性，web.xml内的元素必须以正确的次序声明。但这里应该注意，context-param元素必须出现任意与文档有关的元素（icon、display-name或description）之后及filter、filter-mapping、listener或 servlet元素之前。<br />5.4 在服务器启动时装载servlet<br />假如servlet或JSP页面有一个要花很长时间执行的init （servlet）或jspInit（JSP）方法。例如，假如init或jspInit方法从某个数据库或ResourceBundle查找产量。这种情况下，在第一个客户机请求时装载servlet的缺省行为将对第一个客户机产生较长时间的延迟。因此，可利用servlet的load-on- startup元素规定服务器在第一次启动时装载servlet。下面是一个例子。<br />&lt;servlet&gt;<br />&lt;servlet-name&gt; … &lt;/servlet-name&gt;<br />&lt;servlet-class&gt; … &lt;/servlet-class&gt; &lt;!-- Or jsp-file --&gt;<br />&lt;load-on-startup/&gt;<br />&lt;/servlet&gt;<br />可以为此元素体提供一个整数而不是使用一个空的load-on-startup。想法是服务器应该在装载较大数目的servlet或JSP页面之前装载较少数目的servlet或JSP页面。例如，下面的servlet项（放置在Web应用的WEB-INF目录下的web.xml文件中的web-app元素内）将指示服务器首先装载和初始化SearchServlet，然后装载和初始化由位于Web应用的result目录中的index.jsp文件产生的 servlet。<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;Search&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;myPackage.SearchServlet&lt;/servlet-class&gt; &lt;!-- Or jsp-file --&gt;<br />&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br />&lt;/servlet&gt;<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;Results&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;/results/index.jsp&lt;/servlet-class&gt; &lt;!-- Or jsp-file --&gt;<br />&lt;load-on-startup&gt;2&lt;/load-on-startup&gt;<br />&lt;/servlet&gt;<br /><br />6 声明过滤器<br /><br />servlet版本2.3引入了过滤器的概念。虽然所有支持servlet API版本2.3的服务器都支持过滤器，但为了使用与过滤器有关的元素，必须在web.xml中使用版本2.3的DTD。<br />过滤器可截取和修改进入一个servlet或JSP页面的请求或从一个servlet或JSP页面发出的相应。在执行一个servlet或JSP页面之前，必须执行第一个相关的过滤器的doFilter方法。在该过滤器对其FilterChain对象调用doFilter时，执行链中的下一个过滤器。如果没有其他过滤器，servlet或JSP页面被执行。过滤器具有对到来的ServletRequest对象的全部访问权，因此，它们可以查看客户机名、查找到来的cookie等。为了访问servlet或JSP页面的输出，过滤器可将响应对象包裹在一个替身对象（stand-in object）中，比方说把输出累加到一个缓冲区。在调用FilterChain对象的doFilter方法之后，过滤器可检查缓冲区，如有必要，就对它进行修改，然后传送到客户机。<br />例如，程序清单5-11帝国难以了一个简单的过滤器，只要访问相关的servlet或JSP页面，它就截取请求并在标准输出上打印一个报告（开发过程中在桌面系统上运行时，大多数服务器都可以使用这个过滤器）。<br /><br />程序清单5-11 ReportFilter.java<br />package moreservlets;<br /><br />import java.io.*;<br />import javax.servlet.*;<br />import javax.servlet.http.*;<br />import java.util.*;<br /><br />/** Simple filter that prints a report on the standard output <br />* whenever the associated servlet or JSP page is accessed.<br />* &lt;P&gt;<br />* Taken from More Servlets and JavaServer Pages<br />* from Prentice Hall and Sun Microsystems Press,<br />* http://www.moreservlets.com/.<br />* © 2002 Marty Hall; may be freely used or adapted.<br />*/<br /><br />public class ReportFilter implements Filter {<br />public void doFilter(ServletRequest request,<br />ServletResponse response,<br />FilterChain chain)<br />throws ServletException, IOException {<br />HttpServletRequest req = (HttpServletRequest)request;<br />System.out.println(req.getRemoteHost() +<br />" tried to access " +<br />req.getRequestURL() +<br />" on " + new Date() + ".");<br />chain.doFilter(request,response);<br />}<br /><br />public void init(FilterConfig config)<br />throws ServletException {<br />}<br /><br />public void destroy() {}<br />}<br /><br />一旦建立了一个过滤器，可以在web.xml中利用filter元素以及filter-name（任意名称）、file-class（完全限定的类名）和（可选的）init-params子元素声明它。请注意，元素在web.xml的web-app元素中出现的次序不是任意的；允许服务器（但不是必需的）强制所需的次序，并且实际中有些服务器也是这样做的。但这里要注意，所有filter元素必须出现在任意filter-mapping元素之前， filter-mapping元素又必须出现在所有servlet或servlet-mapping元素之前。<br />例如，给定上述的ReportFilter类，可在web.xml中作出下面的filter声明。它把名称Reporter与实际的类ReportFilter（位于moreservlets程序包中）相关联。<br />&lt;filter&gt;<br />&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />&lt;filter-class&gt;moresevlets.ReportFilter&lt;/filter-class&gt;<br />&lt;/filter&gt;<br />一旦命名了一个过滤器，可利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。关于此项工作有两种选择。<br />首先，可使用filter-name和servlet-name子元素把此过滤器与一个特定的servlet名（此servlet名必须稍后在相同的 web.xml文件中使用servlet元素声明）关联。例如，下面的程序片断指示系统只要利用一个定制的URL访问名为SomeServletName 的servlet或JSP页面，就运行名为Reporter的过滤器。<br />&lt;filter-mapping&gt;<br />&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />&lt;servlet-name&gt;SomeServletName&lt;/servlet-name&gt;<br />&lt;/filter-mapping&gt;<br />其次，可利用filter-name和url-pattern子元素将过滤器与一组servlet、JSP页面或静态内容相关联。例如，相面的程序片段指示系统只要访问Web应用中的任意URL，就运行名为Reporter的过滤器。<br />&lt;filter-mapping&gt;<br />&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />&lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br />&lt;/filter-mapping&gt;<br />例如，程序清单5-12给出了将ReportFilter过滤器与名为PageName的servlet相关联的web.xml文件的一部分。名字 PageName依次又与一个名为TestPage.jsp的JSP页面以及以模式http: //host/webAppPrefix/UrlTest2/ 开头的URL相关联。TestPage.jsp的源代码已经JSP页面命名的谈论在前面的3节"分配名称和定制的URL"中给出。事实上，程序清单5- 12中的servlet和servlet-name项从该节原封不动地拿过来的。给定这些web.xml项，可看到下面的标准输出形式的调试报告（换行是为了容易阅读）。<br />audit.irs.gov tried to access <br />http://mycompany.com/deployDemo/UrlTest2/business/tax-plan.html<br />on Tue Dec 25 13:12:29 EDT 2001.<br /><br />程序清单5-12 Web.xml（说明filter用法的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;<br /><br />&lt;web-app&gt;<br />&lt;filter&gt;<br />&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />&lt;filter-class&gt;moresevlets.ReportFilter&lt;/filter-class&gt;<br />&lt;/filter&gt;<br />&lt;!-- ... --&gt;<br />&lt;filter-mapping&gt;<br />&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />&lt;/filter-mapping&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />&lt;jsp-file&gt;/RealPage.jsp&lt;/jsp-file&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt; PageName &lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/UrlTest2/*&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;<br /><br /><br />7 指定欢迎页<br /><br />假如用户提供了一个像http: //host/webAppPrefix/directoryName/ 这样的包含一个目录名但没有包含文件名的URL，会发生什么事情呢？用户能得到一个目录表？一个错误？还是标准文件的内容？如果得到标准文件内容，是 index.html、index.jsp、default.html、default.htm或别的什么东西呢？<br />Welcome-file-list 元素及其辅助的welcome-file元素解决了这个模糊的问题。例如，下面的web.xml项指出，如果一个URL给出一个目录名但未给出文件名，服务器应该首先试用index.jsp，然后再试用index.html。如果两者都没有找到，则结果有赖于所用的服务器（如一个目录列表）。<br />&lt;welcome-file-list&gt;<br />&lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;<br />&lt;welcome-file&gt;index.html&lt;/welcome-file&gt;<br />&lt;/welcome-file-list&gt;<br />虽然许多服务器缺省遵循这种行为，但不一定必须这样。因此，明确地使用welcom-file-list保证可移植性是一种良好的习惯。<br /><br />8 指定处理错误的页面<br /><br />现在我了解到，你在开发servlet和JSP页面时从不会犯错误，而且你的所有页面是那样的清晰，一般的程序员都不会被它们的搞糊涂。但是，是人总会犯错误的，用户可能会提供不合规定的参数，使用不正确的URL或者不能提供必需的表单字段值。除此之外，其它开发人员可能不那么细心，他们应该有些工具来克服自己的不足。<br />error-page元素就是用来克服这些问题的。它有两个可能的子元素，分别是：error-code和exception- type。第一个子元素error-code指出在给定的HTTP错误代码出现时使用的URL。第二个子元素excpetion-type指出在出现某个给定的Java异常但未捕捉到时使用的URL。error-code和exception-type都利用location元素指出相应的URL。此 URL必须以/开始。location所指出的位置处的页面可通过查找HttpServletRequest对象的两个专门的属性来访问关于错误的信息，这两个属性分别是：javax.servlet.error.status_code和javax.servlet.error.message。<br />可回忆一下，在web.xml内以正确的次序声明web-app的子元素很重要。这里只要记住，error-page出现在web.xml文件的末尾附近，servlet、servlet-name和welcome-file-list之后即可。<br /><br />8.1 error-code元素<br />为了更好地了解error-code元素的值，可考虑一下如果不正确地输入文件名，大多数站点会作出什么反映。这样做一般会出现一个404错误信息，它表示不能找到该文件，但几乎没提供更多有用的信息。另一方面，可以试一下在www.microsoft.com、www.ibm.com 处或者特别是在www.bea.com 处输出未知的文件名。这是会得出有用的消息，这些消息提供可选择的位置，以便查找感兴趣的页面。提供这样有用的错误页面对于Web应用来说是很有价值得。事实上rm-error-page子元素）。由form-login-page给出的HTML表单必须具有一个j_security_check的 ACTION属性、一个名为j_username的用户名文本字段以及一个名为j_password的口令字段。<br />例如，程序清单5-19指示服务器使用基于表单的验证。Web应用的顶层目录中的一个名为login.jsp的页面将收集用户名和口令，并且失败的登陆将由相同目录中名为login-error.jsp的页面报告。<br /><br />程序清单5-19 web.xml（说明login-config的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;<br /><br />&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;security-constraint&gt; ... &lt;/security-constraint&gt;<br />&lt;login-config&gt;<br />&lt;auth-method&gt; FORM &lt;/auth-method&gt;<br />&lt;form-login-config&gt;<br />&lt;form-login-page&gt;/login.jsp&lt;/form-login-page&gt;<br />&lt;form-error-page&gt;/login-error.jsp&lt;/form-error-page&gt;<br />&lt;/form-login-config&gt;<br />&lt;/login-config&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;<br /><br /><br />9.2 限制对Web资源的访问<br />现在，可以指示服务器使用何种验证方法了。"了不起，"你说道，"除非我能指定一个来收到保护的 URL，否则没有多大用处。"没错。指出这些URL并说明他们应该得到何种保护正是security-constriaint元素的用途。此元素在 web.xml中应该出现在login-config的紧前面。它包含是个可能的子元素，分别是：web-resource-collection、 auth-constraint、user-data-constraint和display-name。下面各小节对它们进行介绍。<br />l web-resource-collection<br />此元素确定应该保护的资源。所有security-constraint元素都必须包含至少一个web-resource-collection项。此元素由一个给出任意标识名称的web-resource-name元素、一个确定应该保护的URL的url-pattern元素、一个指出此保护所适用的 HTTP命令（GET、POST等，缺省为所有方法）的http-method元素和一个提供资料的可选description元素组成。例如，下面的 Web-resource-collection项（在security-constratint元素内）指出Web应用的proprietary目录中所有文档应该受到保护。<br />&lt;security-constraint&gt;<br />&lt;web-resource-coolection&gt;<br />&lt;web-resource-name&gt;Proprietary&lt;/web-resource-name&gt;<br />&lt;url-pattern&gt;/propritary/*&lt;/url-pattern&gt;<br />&lt;/web-resource-coolection&gt;<br />&lt;!-- ... --&gt;<br />&lt;/security-constraint&gt;<br />重要的是应该注意到，url-pattern仅适用于直接访问这些资源的客户机。特别是，它不适合于通过MVC体系结构利用 RequestDispatcher来访问的页面，或者不适合于利用类似jsp:forward的手段来访问的页面。这种不匀称如果利用得当的话很有好处。例如，servlet可利用MVC体系结构查找数据，把它放到bean中，发送请求到从bean中提取数据的JSP页面并显示它。我们希望保证决不直接访问受保护的JSP页面，而只是通过建立该页面将使用的bean的servlet来访问它。url-pattern和auth-contraint元素可通过声明不允许任何用户直接访问JSP页面来提供这种保证。但是，这种不匀称的行为可能让开发人员放松警惕，使他们偶然对应受保护的资源提供不受限制的访问。 <br />l auth-constraint<br />尽管web-resource-collention元素质出了哪些URL应该受到保护，但是auth-constraint元素却指出哪些用户应该具有受保护资源的访问权。此元素应该包含一个或多个标识具有访问权限的用户类别role- name元素，以及包含（可选）一个描述角色的description元素。例如，下面web.xml中的security-constraint元素部门规定只有指定为Administrator或Big Kahuna（或两者）的用户具有指定资源的访问权。<br />&lt;security-constraint&gt;<br />&lt;web-resource-coolection&gt; ... &lt;/web-resource-coolection&gt;<br />&lt;auth-constraint&gt;<br />&lt;role-name&gt;administrator&lt;/role-name&gt;<br />&lt;role-name&gt;kahuna&lt;/role-name&gt;<br />&lt;/auth-constraint&gt;<br />&lt;/security-constraint&gt;<br />重要的是认识到，到此为止，这个过程的可移植部分结束了。服务器怎样确定哪些用户处于任何角色以及它怎样存放用户的口令，完全有赖于具体的系统。<br />例如，Tomcat使用install_dir/conf/tomcat-users.xml将用户名与角色名和口令相关联，正如下面例子中所示，它指出用户joe（口令bigshot）和jane（口令enaj）属于administrator和kahuna角色。<br />&lt;tomcat-users&gt;<br />&lt;user name="joe" password="bigshot" roles="administrator,kahuna" /&gt;<br />&lt;user name="jane" password="enaj" roles="kahuna" /&gt;<br />&lt;/tomcat-users&gt;<br />l user-data-constraint<br />这个可选的元素指出在访问相关资源时使用任何传输层保护。它必须包含一个transport-guarantee子元素（合法值为NONE、 INTEGRAL或CONFIDENTIAL），并且可选地包含一个description元素。transport-guarantee为NONE值将对所用的通讯协议不加限制。INTEGRAL值表示数据必须以一种防止截取它的人阅读它的方式传送。虽然原理上（并且在未来的HTTP版本中），在 INTEGRAL和CONFIDENTIAL之间可能会有差别，但在当前实践中，他们都只是简单地要求用SSL。例如，下面指示服务器只允许对相关资源做 HTTPS连接：<br />&lt;security-constraint&gt;<br />&lt;!-- ... --&gt;<br />&lt;user-data-constraint&gt;<br />&lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;<br />&lt;/user-data-constraint&gt;<br />&lt;/security-constraint&gt;<br />l display-name<br />security-constraint的这个很少使用的子元素给予可能由GUI工具使用的安全约束项一个名称。<br />9.3 分配角色名<br />迄今为止，讨论已经集中到完全由容器（服务器）处理的安全问题之上了。但servlet以及JSP页面也能够处理它们自己的安全问题。<br />例如，容器可能允许用户从bigwig或bigcheese角色访问一个显示主管人员额外紧贴的页面，但只允许bigwig用户修改此页面的参数。完成这种更细致的控制的一种常见方法是调用HttpServletRequset的isUserInRole方法，并据此修改访问。<br />Servlet的 security-role-ref子元素提供出现在服务器专用口令文件中的安全角色名的一个别名。例如，假如编写了一个调用 request.isUserInRole（"boss"）的servlet，但后来该servlet被用在了一个其口令文件调用角色manager而不是boss的服务器中。下面的程序段使该servlet能够使用这两个名称中的任何一个。<br />&lt;servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;security-role-ref&gt;<br />&lt;role-name&gt;boss&lt;/role-name&gt; &lt;!-- New alias --&gt;<br />&lt;role-link&gt;manager&lt;/role-link&gt; &lt;!-- Real name --&gt;<br />&lt;/security-role-ref&gt;<br />&lt;/servlet&gt;<br />也可以在web-app内利用security-role元素提供将出现在role-name元素中的所有安全角色的一个全局列表。分别地生命角色使高级IDE容易处理安全信息。<br /><br />10 控制会话超时<br /><br />如果某个会话在一定的时间内未被访问，服务器可把它扔掉以节约内存。可利用HttpSession的setMaxInactiveInterval方法直接设置个别会话对象的超时值。如果不采用这种方法，则缺省的超时值由具体的服务器决定。但可利用session-config和session- timeout元素来给出一个适用于所有服务器的明确的超时值。超时值的单位为分钟，因此，下面的例子设置缺省会话超时值为三个小时（180分钟）。<br />&lt;session-config&gt;<br />&lt;session-timeout&gt;180&lt;/session-timeout&gt;<br />&lt;/session-config&gt;<br /><br />11 Web应用的文档化<br /><br />越来越多的开发环境开始提供servlet和JSP的直接支持。例子有Borland Jbuilder Enterprise Edition、Macromedia UltraDev、Allaire JRun Studio（写此文时，已被Macromedia收购）以及IBM VisuaAge for Java等。<br />大量的web.xml元素不仅是为服务器设计的，而且还是为可视开发环境设计的。它们包括icon、display-name和discription等。<br />可回忆一下，在web.xml内以适当地次序声明web-app子元素很重要。不过，这里只要记住icon、display-name和description是web.xml的web-app元素内的前三个合法元素即可。<br />l icon<br />icon元素指出GUI工具可用来代表Web应用的一个和两个图像文件。可利用small-icon元素指定一幅16 x 16的GIF或JPEG图像，用large-icon元素指定一幅32 x 32的图像。下面举一个例子： <br />&lt;icon&gt;<br />&lt;small-icon&gt;/images/small-book.gif&lt;/small-icon&gt;<br />&lt;large-icon&gt;/images/tome.jpg&lt;/large-icon&gt;<br />&lt;/icon&gt;<br />l display-name<br />display-name元素提供GUI工具可能会用来标记此Web应用的一个名称。下面是个例子。<br />&lt;display-name&gt;Rare Books&lt;/display-name&gt;<br />l description<br />description元素提供解释性文本，如下所示：<br />&lt;description&gt;<br />This Web application represents the store developed for<br />rare-books.com, an online bookstore specializing in rare<br />and limited-edition books.<br />&lt;/description&gt;<br /><br />12 关联文件与MIME类型<br /><br />服务器一般都具有一种让Web站点管理员将文件扩展名与媒体相关联的方法。例如，将会自动给予名为mom.jpg的文件一个image/jpeg的MIME 类型。但是，假如你的Web应用具有几个不寻常的文件，你希望保证它们在发送到客户机时分配为某种MIME类型。mime-mapping元素（具有 extension和mime-type子元素）可提供这种保证。例如，下面的代码指示服务器将application/x-fubar的MIME类型分配给所有以.foo结尾的文件。<br />&lt;mime-mapping&gt;<br />&lt;extension&gt;foo&lt;/extension&gt;<br />&lt;mime-type&gt;application/x-fubar&lt;/mime-type&gt;<br />&lt;/mime-mapping&gt;<br />或许，你的Web应用希望重载（override）标准的映射。例如，下面的代码将告诉服务器在发送到客户机时指定.ps文件作为纯文本（text/plain）而不是作为PostScript（application/postscript）。<br />&lt;mime-mapping&gt;<br />&lt;extension&gt;ps&lt;/extension&gt;<br />&lt;mime-type&gt;application/postscript&lt;/mime-type&gt;<br />&lt;/mime-mapping&gt;<br /><br /><br />13 定位TLD<br /><br />JSP taglib元素具有一个必要的uri属性，它给出一个TLD（Tag Library Descriptor）文件相对于Web应用的根的位置。TLD文件的实际名称在发布新的标签库版本时可能会改变，但我们希望避免更改所有现有JSP页面。此外，可能还希望使用保持taglib元素的简练性的一个简短的uri。这就是部署描述符文件的taglib元素派用场的所在了。Taglib包含两个子元素：taglib-uri和taglib-location。taglib-uri元素应该与用于JSP taglib元素的uri属性的东西相匹配。Taglib-location元素给出TLD文件的实际位置。例如，假如你将文件chart-tags- 1.3beta.tld放在WebApp/WEB-INF/tlds中。现在，假如web.xml在web-app元素内包含下列内容。<br />&lt;taglib&gt;<br />&lt;taglib-uri&gt;/charts.tld&lt;/taglib-uri&gt;<br />&lt;taglib-location&gt;<br />/WEB-INF/tlds/chart-tags-1.3beta.tld<br />&lt;/taglib-location&gt;<br />&lt;/taglib&gt;<br />给出这个说明后，JSP页面可通过下面的简化形式使用标签库。<br />&lt;%@ taglib uri="/charts.tld" prefix="somePrefix" %&gt;<br /><br />14 指定应用事件监听程序<br /><br />应用事件监听器程序是建立或修改servlet环境或会话对象时通知的类。它们是servlet规范的版本2.3中的新内容。这里只简单地说明用来向Web应用注册一个监听程序的web.xml的用法。<br />注册一个监听程序涉及在web.xml的web-app元素内放置一个listener元素。在listener元素内，listener-class元素列出监听程序的完整的限定类名，如下所示：<br />&lt;listener&gt;<br />&lt;listener-class&gt;package.ListenerClass&lt;/listener-class&gt;<br />&lt;/listener&gt;<br />虽然listener元素的结构很简单，但请不要忘记，必须正确地给出web-app元素内的子元素的次序。listener元素位于所有的servlet 元素之前以及所有filter-mapping元素之后。此外，因为应用生存期监听程序是serlvet规范的2.3版本中的新内容，所以必须使用 web.xml DTD的2.3版本，而不是2.2版本。<br />例如，程序清单5-20给出一个名为ContextReporter的简单的监听程序，只要Web应用的Servlet-Context建立（如装载Web应用）或消除（如服务器关闭）时，它就在标准输出上显示一条消息。程序清单5-21给出此监听程序注册所需要的web.xml文件的一部分。<br /><br />程序清单5-20 ContextReporterjava<br />package moreservlets;<br /><br />import javax.servlet.*;<br />import java.util.*;<br /><br />/** Simple listener that prints a report on the standard output <br />* when the ServletContext is created or destroyed.<br />* &lt;P&gt;<br />* Taken from More Servlets and JavaServer Pages<br />* from Prentice Hall and Sun Microsystems Press,<br />* http://www.moreservlets.com/.<br />* © 2002 Marty Hall; may be freely used or adapted.<br />*/<br /><br />public class ContextReporter implements ServletContextListener {<br />public void contextInitialized(ServletContextEvent event) {<br />System.out.println("Context created on " +<br />new Date() + ".");<br />}<br /><br />public void contextDestroyed(ServletContextEvent event) {<br />System.out.println("Context destroyed on " +<br />new Date() + ".");<br />}<br />}<br /><br /><br />程序清单5-21 web.xml（声明一个监听程序的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;<br /><br />&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;filter-mapping&gt; … &lt;/filter-mapping&gt;<br />&lt;listener&gt;<br />&lt;listener-class&gt;package.ListenerClass&lt;/listener-class&gt;<br />&lt;/listener&gt;<br />&lt;servlet&gt; ... &lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;<br /><br /><br />15 J2EE元素<br /><br />本节描述用作J2EE环境组成部分的Web应用的web.xml元素。这里将提供一个简明的介绍，详细内容可以参阅http://java.sun.com/j2ee/j2ee-1_3-fr-spec.pdf的Java 2 Plantform Enterprise Edition版本1.3规范的第5章。<br />l distributable<br />distributable 元素指出，Web应用是以这样的方式编程的：即，支持集群的服务器可安全地在多个服务器上分布Web应用。例如，一个可分布的应用必须只使用 Serializable对象作为其HttpSession对象的属性，而且必须避免用实例变量（字段）来实现持续性。distributable元素直接出现在discription元素之后，并且不包含子元素或数据，它只是一个如下的标志。<br />&lt;distributable /&gt;<br />l resource-env-ref<br />resource -env-ref元素声明一个与某个资源有关的管理对象。此元素由一个可选的description元素、一个resource-env-ref- name元素（一个相对于java:comp/env环境的JNDI名）以及一个resource-env-type元素（指定资源类型的完全限定的类），如下所示：<br />&lt;resource-env-ref&gt;<br />&lt;resource-env-ref-name&gt;<br />jms/StockQueue<br />&lt;/resource-env-ref-name&gt;<br />&lt;resource-env-ref-type&gt;<br />javax.jms.Queue<br />&lt;/resource-env-ref-type&gt;<br />&lt;/resource-env-ref&gt;<br />l env-entry<br />env -entry元素声明Web应用的环境项。它由一个可选的description元素、一个env-entry-name元素（一个相对于java: comp/env环境JNDI名）、一个env-entry-value元素（项值）以及一个env-entry-type元素（java.lang程序包中一个类型的完全限定类名，java.lang.Boolean、java.lang.String等）组成。下面是一个例子：<br />&lt;env-entry&gt;<br />&lt;env-entry-name&gt;minAmout&lt;/env-entry-name&gt;<br />&lt;env-entry-value&gt;100.00&lt;/env-entry-value&gt;<br />&lt;env-entry-type&gt;minAmout&lt;/env-entry-type&gt;<br />&lt;/env-entry&gt;<br />l ejb-ref<br />ejb -ref元素声明对一个EJB的主目录的应用。它由一个可选的description元素、一个ejb-ref-name元素（相对于java: comp/env的EJB应用）、一个ejb-ref-type元素（bean的类型，Entity或Session）、一个home元素（bean的主目录接口的完全限定名）、一个remote元素（bean的远程接口的完全限定名）以及一个可选的ejb-link元素（当前bean链接的另一个 bean的名称）组成。<br />l ejb-local-ref<br />ejb-local-ref元素声明一个EJB的本地主目录的引用。除了用local-home代替home外，此元素具有与ejb-ref元素相同的属性并以相同的方式使用 </font>
		<br />
<img src ="http://www.blogjava.net/jelver/aggbug/40920.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-04-13 15:58 <a href="http://www.blogjava.net/jelver/articles/40920.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>js+xml实现三级联动菜单</title><link>http://www.blogjava.net/jelver/articles/31987.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Wed, 22 Feb 2006 09:28:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/31987.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/31987.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/31987.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/31987.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/31987.html</trackback:ping><description><![CDATA[<DIV class=readf>
<P>mselect.xml<BR>&lt;?xml version="1.0" encoding="GB2312" ?&gt;<BR>&lt;Troot&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="1" pid="0" c="1"&gt;大学&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="2" pid="0" c="3"&gt;中学&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="3" pid="0" c="3"&gt;小学&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="4" pid="2" c="2"&gt;高中&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="5" pid="2" c="5"&gt;初中&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="6" pid="15" c="3"&gt;清华大学&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="7" pid="15" c="4"&gt;北京大学&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="8" pid="5" c="3"&gt;天津铁三中&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="9" pid="4" c="3"&gt;天津市二中&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="10" pid="16" c="2"&gt;天津音乐学院&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="11" pid="15" c="5"&gt;天津商学院&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="12" pid="4" c="3"&gt;耀华中学&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="13" pid="3" c="6"&gt;昆纬路小学&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="14" pid="2" c="6"&gt;七中&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="15" pid="1" c="1"&gt;综合类院校&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="16" pid="1" c="1"&gt;艺术类院校&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="17" pid="15" c="4"&gt;医科大学&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="18" pid="15" c="4"&gt;天津师范大学&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="19" pid="15" c="23"&gt;天津大学&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="20" pid="15" c="7"&gt;南开大学&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="21" pid="4" c="23"&gt;天津铁一中&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="22" pid="5" c="5"&gt;天津铁一中&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="23" pid="3" c="3"&gt;天津市铁路职工子弟第三小学&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="24" pid="3" c="3"&gt;天津市铁路职工子弟第一小学&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="25" pid="16" c="3"&gt;美术学院&lt;/Item&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;Item id="26" pid="16" c="3"&gt;体育学院&lt;/Item&gt;<BR>&lt;/Troot&gt;</P>
<P>test.html<BR>&lt;HTML&gt;<BR>&lt;HEAD&gt;<BR>&lt;TITLE&gt;XML版本的多级联动&lt;/TITLE&gt;<BR>&lt;SCRIPT LANGUAGE=javascript&gt;<BR>&lt;!--<BR>/***********************************************<BR>//<BR>// 用DOM实现：基于XML的动态N级联动<BR>//<BR>//**********************************************/</P>
<P>// 最终版权归 DSclub（任兀）拥有，您可以在未授权的情况下使用，但请保留此信息<BR>//<BR>//&nbsp;&nbsp; EMail：<A href="mailto:dsclub@hotmail.com"><FONT color=#333333>dsclub@hotmail.com</FONT></A><BR>//&nbsp;&nbsp; QQ：9967030<BR>//&nbsp;&nbsp; Nick Name: DSclub(兀儿－干部)<BR>//&nbsp;&nbsp; 姓名：任兀</P>
<P></P>
<P>// 多级联动的Select集合<BR>var objSelects = new Array();<BR><BR>// 创建应有的Select对象<BR>function funCreateSelectEl(passPid)<BR>{<BR>// 创建DOMDocument对象<BR>var xmlSrc = new ActiveXObject("MicroSoft.XMLDOM");<BR>xmlSrc = xmlSource.XMLDocument;</P>
<P>// root为文档对象的根节点<BR>var root = xmlSrc.documentElement;<BR>// 得到所传父ID的所有节点<BR>var currentItems = root.selectNodes("//Troot/Item[@pid = " + passPid + "]");<BR>var iItems = currentItems.length;</P>
<P>&nbsp;&nbsp;&nbsp; if(iItems &gt; 0)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 创建Select并把OnChange事件写好<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var newChild = document.createElement("&lt;SELECT onchange='eventSltChange()' id='slt" + objSelects.length + "'&gt;");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 向集合中添加新建的Select对象<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; objSelects[objSelects.length] = newChild;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 向Select对向添加所有的Option<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var i;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i = 0; i &lt; iItems; i++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var oOption = document.createElement("OPTION");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oOption.text = currentItems[i].text;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oOption.value = currentItems[i].attributes[0].text;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newChild.options.add(oOption);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 将新建的Select放到目标上<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oDIV.appendChild(newChild);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 先置一个空白空值<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newChild.value = "";<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>// Select的OnChange事件响应函数<BR>function eventSltChange()<BR>{<BR>&nbsp;&nbsp;&nbsp; // 删除全部本层下的孩子<BR>&nbsp;&nbsp;&nbsp; var i;<BR>&nbsp;&nbsp;&nbsp; for(i = objSelects.length - 1; i &gt; parseInt(event.srcElement.id.replace("slt",""), 10); i--)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oDIV.removeChild(objSelects[i]);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; objSelects.pop();<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; // 响应新的选择<BR>&nbsp;&nbsp;&nbsp; funCreateSelectEl(event.srcElement.value);<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; // 联动的选择结果<BR>&nbsp;&nbsp;&nbsp; var resultArray = new Array();<BR>&nbsp;&nbsp;&nbsp; for(i = 0; i &lt; objSelects.length; i++)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resultArray[i] = objSelects[i].value;<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; // 输出选定<BR>&nbsp;&nbsp;&nbsp; OUTPUT.innerText = resultArray.join("-");<BR>}<BR>//--&gt;<BR>&lt;/SCRIPT&gt;</P>
<P><BR>&lt;/HEAD&gt;<BR>&lt;BODY onload="funCreateSelectEl(0)"&gt;<BR>&lt;DIV ID="oDIV"&gt;&lt;/DIV&gt;<BR>&lt;XML ID="xmlSource" src="mselect.xml"/&gt;<BR>&lt;BR/&gt;<BR>选定结果：&lt;SPAN ID="OUTPUT"&gt;&lt;/SPAN&gt;<BR>&lt;/BODY&gt;<BR>&lt;/HTML&gt;</P></DIV><img src ="http://www.blogjava.net/jelver/aggbug/31987.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-02-22 17:28 <a href="http://www.blogjava.net/jelver/articles/31987.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>