﻿<?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-blog.Toby-随笔分类-java tips</title><link>http://www.blogjava.net/SIDNEY/category/6406.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 20 Mar 2007 08:27:04 GMT</lastBuildDate><pubDate>Tue, 20 Mar 2007 08:27:04 GMT</pubDate><ttl>60</ttl><item><title>每个JAVA初学者应该知道的问题</title><link>http://www.blogjava.net/SIDNEY/archive/2007/03/20/104864.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Tue, 20 Mar 2007 00:41:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2007/03/20/104864.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/104864.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2007/03/20/104864.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/104864.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/104864.html</trackback:ping><description><![CDATA[
		<font face="Arial">对于这个系列里的问题，每个学Java的人都应该搞懂。当然，如果只是学Java玩玩就无所谓了。如果你认为自己已经超越初学者了，却不很懂这些问题，请将你自己重归初学者行列。内容均来自于CSDN的经典老贴。<br /><br />问题一：我声明了什么！<br /><br />String s = "Hello world!";<br /><br />许多人都做过这样的事情，但是，我们到底声明了什么？回答通常是：一个String，内容是“Hello world!”。这样模糊的回答通常是概念不清的根源。如果要准确的回答，一半的人大概会回答错误。<br />这个语句声明的是一个指向对象的引用，名为“s”，可以指向类型为String的任何对象，目前指向"Hello world!"这个String类型的对象。这就是真正发生的事情。我们并没有声明一个String对象，我们只是声明了一个只能指向String对象的引用变量。所以，如果在刚才那句语句后面，如果再运行一句：<br /><br />String string = s;<br /><br />我们是声明了另外一个只能指向String对象的引用，名为string，并没有第二个对象产生，string还是指向原来那个对象，也就是，和s指向同一个对象。<br /><br />问题二："=="和equals方法究竟有什么区别？<br /><br />==操作符专门用来比较变量的值是否相等。比较好理解的一点是：<br />int a=10;<br />int b=10;<br />则a==b将是true。<br />但不好理解的地方是：<br />String a=new String("foo");<br />String b=new String("foo");<br />则a==b将返回false。<br /><br />根据前一帖说过，对象变量其实是一个引用，它们的值是指向对象所在的内存地址，而不是对象本身。a和b都使用了new操作符，意味着将在内存中产生两个内容为"foo"的字符串，既然是“两个”，它们自然位于不同的内存地址。a和b的值其实是两个不同的内存地址的值，所以使用"=="操作符，结果会是false。诚然，a和b所指的对象，它们的内容都是"foo"，应该是“相等”，但是==操作符并不涉及到对象内容的比较。<br />对象内容的比较，正是equals方法做的事。<br /><br />看一下Object对象的equals方法是如何实现的：<br />boolean equals(Object o){<br /><br />return this==o;<br /><br />}<br />Object对象默认使用了==操作符。所以如果你自创的类没有覆盖equals方法，那你的类使用equals和使用==会得到同样的结果。同样也可以看出，Object的equals方法没有达到equals方法应该达到的目标：比较两个对象内容是否相等。因为答案应该由类的创建者决定，所以Object把这个任务留给了类的创建者。<br /><br />看一下一个极端的类：<br />Class Monster{<br />private String content;<br />...<br />boolean equals(Object another){ return true;}<br /><br />}<br />我覆盖了equals方法。这个实现会导致无论Monster实例内容如何，它们之间的比较永远返回true。<br /><br />所以当你是用equals方法判断对象的内容是否相等，请不要想当然。因为可能你认为相等，而这个类的作者不这样认为，而类的equals方法的实现是由他掌握的。如果你需要使用equals方法，或者使用任何基于散列码的集合（HashSet,HashMap,HashTable），请察看一下java doc以确认这个类的equals逻辑是如何实现的。<br /><br />问题三：String到底变了没有？<br /><br />没有。因为String被设计成不可变(immutable)类，所以它的所有对象都是不可变对象。请看下列代码：<br /><br />String s = "Hello";<br />s = s + " world!";<br /><br />s所指向的对象是否改变了呢？从本系列第一篇的结论很容易导出这个结论。我们来看看发生了什么事情。在这段代码中，s原先指向一个String对象，内容是"Hello"，然后我们对s进行了+操作，那么s所指向的那个对象是否发生了改变呢？答案是没有。这时，s不指向原来那个对象了，而指向了另一个String对象，内容为"Hello world!"，原来那个对象还存在于内存之中，只是s这个引用变量不再指向它了。<br />通过上面的说明，我们很容易导出另一个结论，如果经常对字符串进行各种各样的修改，或者说，不可预见的修改，那么使用String来代表字符串的话会引起很大的内存开销。因为String对象建立之后不能再改变，所以对于每一个不同的字符串，都需要一个String对象来表示。这时，应该考虑使用StringBuffer类，它允许修改，而不是每个不同的字符串都要生成一个新的对象。并且，这两种类的对象转换十分容易。<br />同时，我们还可以知道，如果要使用内容相同的字符串，不必每次都new一个String。例如我们要在构造器中对一个名叫s的String引用变量进行初始化，把它设置为初始值，应当这样做：<br />public class Demo {<br />private String s;<br />...<br />public Demo {<br />s = "Initial Value";<br />}<br />...<br />}<br />而非<br />s = new String("Initial Value");<br />后者每次都会调用构造器，生成新对象，性能低下且内存开销大，并且没有意义，因为String对象不可改变，所以对于内容相同的字符串，只要一个String对象来表示就可以了。也就说，多次调用上面的构造器创建多个对象，他们的String类型属性s都指向同一个对象。<br />上面的结论还基于这样一个事实：对于字符串常量，如果内容相同，Java认为它们代表同一个String对象。而用关键字new调用构造器，总是会创建一个新的对象，无论内容是否相同。<br />至于为什么要把String类设计成不可变类，是它的用途决定的。其实不只String，很多Java标准类库中的类都是不可变的。在开发一个系统的时候，我们有时候也需要设计不可变类，来传递一组相关的值，这也是面向对象思想的体现。不可变类有一些优点，比如因为它的对象是只读的，所以多线程并发访问也不会有任何问题。当然也有一些缺点，比如每个不同的状态都要一个对象来代表，可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本，即StringBuffer。<br /><br />问题四：final关键字到底修饰了什么？<br /><br />final使得被修饰的变量"不变"，但是由于对象型变量的本质是“引用”，使得“不变”也有了两种含义：引用本身的不变，和引用指向的对象不变。<br /><br />引用本身的不变：<br />final StringBuffer a=new StringBuffer("immutable");<br />final StringBuffer b=new StringBuffer("not immutable");<br />a=b;//编译期错误<br /><br />引用指向的对象不变：<br />final StringBuffer a=new StringBuffer("immutable");<br />a.append(" broken!"); //编译通过<br /><br />可见，final只对引用的“值”(也即它所指向的那个对象的内存地址)有效，它迫使引用只能指向初始指向的那个对象，改变它的指向会导致编译期错误。至于它所指向的对象的变化，final是不负责的。这很类似==操作符：==操作符只负责引用的“值”相等，至于这个地址所指向的对象内容是否相等，==操作符是不管的。<br /><br />理解final问题有很重要的含义。许多程序漏洞都基于此----final只能保证引用永远指向固定对象，不能保证那个对象的状态不变。在多线程的操作中,一个对象会被多个线程共享或修改，一个线程对对象无意识的修改可能会导致另一个使用此对象的线程崩溃。一个错误的解决方法就是在此对象新建的时候把它声明为final，意图使得它“永远不变”。其实那是徒劳的。<br /><br />问题五：到底要怎么样初始化！<br /><br />本问题讨论变量的初始化，所以先来看一下Java中有哪些种类的变量。<br />1. 类的属性，或者叫值域<br />2. 方法里的局部变量<br />3. 方法的参数<br /><br />对于第一种变量，Java虚拟机会自动进行初始化。如果给出了初始值，则初始化为该初始值。如果没有给出，则把它初始化为该类型变量的默认初始值。<br /><br />int类型变量默认初始值为0<br />float类型变量默认初始值为0.0f<br />double类型变量默认初始值为0.0<br />boolean类型变量默认初始值为false<br />char类型变量默认初始值为0(ASCII码)<br />long类型变量默认初始值为0<br />所有对象引用类型变量默认初始值为null，即不指向任何对象。注意数组本身也是对象，所以没有初始化的数组引用在自动初始化后其值也是null。<br /><br />对于两种不同的类属性，static属性与instance属性，初始化的时机是不同的。instance属性在创建实例的时候初始化，static属性在类加载，也就是第一次用到这个类的时候初始化，对于后来的实例的创建，不再次进行初始化。这个问题会在以后的系列中进行详细讨论。<br /><br />对于第二种变量，必须明确地进行初始化。如果再没有初始化之前就试图使用它，编译器会抗议。如果初始化的语句在try块中或if块中，也必须要让它在第一次使用前一定能够得到赋值。也就是说，把初始化语句放在只有if块的条件判断语句中编译器也会抗议，因为执行的时候可能不符合if后面的判断条件，如此一来初始化语句就不会被执行了，这就违反了局部变量使用前必须初始化的规定。但如果在else块中也有初始化语句，就可以通过编译，因为无论如何，总有至少一条初始化语句会被执行，不会发生使用前未被初始化的事情。对于try-catch也是一样，如果只有在try块里才有初始化语句，编译部通过。如果在catch或finally里也有，则可以通过编译。总之，要保证局部变量在使用之前一定被初始化了。所以，一个好的做法是在声明他们的时候就初始化他们，如果不知道要出事化成什么值好，就用上面的默认值吧！<br /><br />其实第三种变量和第二种本质上是一样的，都是方法中的局部变量。只不过作为参数，肯定是被初始化过的，传入的值就是初始值，所以不需要初始化。<br /><br />问题六：instanceof是什么东东？<br /><br />instanceof是Java的一个二元操作符，和==，&gt;，&lt;是同一类东东。由于它是由字母组成的，所以也是Java的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例，返回boolean类型的数据。举个例子：<br /><br />String s = "I AM an Object!";<br />boolean isObject = s instanceof Object;<br /><br />我们声明了一个String对象引用，指向一个String对象，然后用instancof来测试它所指向的对象是否是Object类的一个实例，显然，这是真的，所以返回true，也就是isObject的值为True。<br />instanceof有一些用处。比如我们写了一个处理账单的系统，其中有这样三个类：<br /><br />public class Bill {//省略细节}<br />public class PhoneBill extends Bill {//省略细节}<br />public class GasBill extends Bill {//省略细节}<br /><br />在处理程序里有一个方法，接受一个Bill类型的对象，计算金额。假设两种账单计算方法不同，而传入的Bill对象可能是两种中的任何一种，所以要用instanceof来判断：<br /><br />public double calculate(Bill bill) {<br />if (bill instanceof PhoneBill) {<br />//计算电话账单<br />}<br />if (bill instanceof GasBill) {<br />//计算燃气账单<br />}<br />...<br />}<br />这样就可以用一个方法处理两种子类。<br /><br />然而，这种做法通常被认为是没有好好利用面向对象中的多态性。其实上面的功能要求用方法重载完全可以实现，这是面向对象变成应有的做法，避免回到结构化编程模式。只要提供两个名字和返回值都相同，接受参数类型不同的方法就可以了：<br /><br />public double calculate(PhoneBill bill) {<br />//计算电话账单<br />}<br /><br />public double calculate(GasBill bill) {<br />//计算燃气账单<br />}<br /><br />所以，使用instanceof在绝大多数情况下并不是推荐的做法，应当好好利用多态。</font>
<img src ="http://www.blogjava.net/SIDNEY/aggbug/104864.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2007-03-20 08:41 <a href="http://www.blogjava.net/SIDNEY/archive/2007/03/20/104864.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>log4j写SQL Server数据库日志的统一写法</title><link>http://www.blogjava.net/SIDNEY/archive/2007/02/14/99830.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Wed, 14 Feb 2007 07:29:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2007/02/14/99830.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/99830.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2007/02/14/99830.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/99830.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/99830.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: SQL Server 2000 Driver for JDBC Service Pack 3				的下载																												之前需要注意一点，sql server同样必须打上了sp3的补丁，然后才能与jdbc for sqlserver sp3连接。如果是"Error establishing socket"错误,很有可能是要在...&nbsp;&nbsp;<a href='http://www.blogjava.net/SIDNEY/archive/2007/02/14/99830.html'>阅读全文</a><img src ="http://www.blogjava.net/SIDNEY/aggbug/99830.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2007-02-14 15:29 <a href="http://www.blogjava.net/SIDNEY/archive/2007/02/14/99830.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> JAX-RPC和Web服务会话状态的保持</title><link>http://www.blogjava.net/SIDNEY/archive/2006/07/06/56957.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Thu, 06 Jul 2006 07:34:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/07/06/56957.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/56957.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/07/06/56957.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/56957.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/56957.html</trackback:ping><description><![CDATA[
		<blockquote>本文首先讨论了Web服务会话状态的保持方法，然后着重结合J2EE平台中Web服务核心技术--JAX-RPC来介绍怎么在Web服务调用过程中保持客户端的会话状态，并且提供了服务端和不同类型客户端的调用实例。</blockquote>
		<!--START RESERVED FOR FUTURE USE INCLUDE FILES-->
		<!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters -->
		<!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
		<p>本文是J2EE Web服务开发系列文章的第九篇，本文首先讨论了Web服务会话状态的保持方法，然后着重结合J2EE平台中Web服务核心技术--JAX-RPC来介绍怎么在Web服务调用过程中保持客户端的会话状态，并且提供了服务端和不同类型客户端的调用实例。 </p>
		<p>阅读本文前您需要以下的知识和工具： <br /></p>
		<ul>
				<li>J2EESDK1.4（Sun已经发布了正式版），并且会初步使用； <br /><br /></li>
				<li>了解JAX-RPC的基本概念； <br /></li>
				<li>能够使用JAX-RPC技术开发Web服务； <br /></li>
				<li>一般的Java编程知识。 <br /></li>
		</ul>
		<p>
		</p>
		<p>本文的参考资料见 <a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-session/index.html#resources"><font color="#996699">参考资料</font></a>。 </p>
		<p>本文的全部代码在这里 <a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-session/src.zip"><font color="#5c81a7">下载</font></a>。 </p>
		<p>
				<a name="1">
						<span class="atitle">
								<font face="Arial" size="4">Web服务与会话</font>
						</span>
				</a>
		</p>
		<p>
				<br />Web服务大多基于HTTP协议，而HTTP协议是一种无状态的协议。Web服务规范并没有定义客户端和服务端之间会话的保持方法。所以要在多个Web服务调用之间保持一些状态，需要使用一些额外的技术或者方法。 </p>
		<p>我们知道，基于HTTP的应用开发中，要在多个调用之间保持会话状态，通常可以采用以下几种方式： </p>
		<ul>
				<li>URL重写，把要传递的参数重写在URL中； <br /><br /></li>
				<li>使用Cookie，把要传递的参数写入到客户端cookie中； <br /><br /></li>
				<li>使用隐含表单，把要传递的参数写入到隐含的表单中； <br /><br /></li>
				<li>使用Session，把要传递的参数保存在session对象中（其实Session机制基于cookie或者URL重写）。 <br /><br /></li>
		</ul>
		<p>上面几个方式有一个共同点：把要传递的参数保存在两个页面都能共享的对象中，前一个页面在这个对象中写入状态、后一个页面从这个对象中读取状态。特别是对于使用session方式，每个客户端在服务端都对应了一个sessionid，服务端维持了由sessionid标识的一系列session对象，而session对象用于保持共享的信息。 </p>
		<p>我们似乎从上面得到一些启发，是否可以在服务端标识每个Web服务客户端，并且把它们的状态保持在某个可以共享的位置，比如内存、文件系统、数据库。是的，许多Web服务开发工具正是这样实现的。如果使用Weblogic Workshop开发Web服务，它可以把Web服务的状态保持在实体Bean中。 </p>
		<p>如果Web服务的服务端能够访问HTTP会话对象，那么就可以通过HTTP会话来支持Web服务的会话。JAX-RPC就是采用了这种方式。 </p>
		<p>如果Web服务技术或者开发工具没有提供任何的支持，那么我们可以在服务端维持一个客户端状态池，这个状态池中的对象由客户端的id标识，客户端在每次调用时，都使用以下格式的SOAP消息： </p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">&lt;soapenv:Envelope 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
 &lt;soapenv:Body&gt;
   ...
   &lt;client-id&gt;001sf3242x-234234&lt;/client-id&gt;
   &lt;call-params&gt;… &lt;/call-param&gt;
   &lt;call-method&gt;
    getLogCount
   &lt;/call-method&gt;
 &lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>服务端接收到这个SOAP消息时，可以通过这个&lt;client-id&gt;来获得对应状态池中的对象，然后进一步获得客户端预先设置的状态信息。 </p>
		<p>下面结合JAX-RPC技术来讨论具体的实现方法。 </p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/webservices/ws-session/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="2">
						<span class="atitle">
								<font face="Arial" size="4">JAX-RPC和Web服务会话</font>
						</span>
				</a>
		</p>
		<p>
				<br />概念回顾：在J2EE平台中，要开发Web服务，可以使用两种技术：JAX-RPC和JAXM。而对于JAX-RPC，又有两种不同类型的服务端点：Servlet服务端点和EJB服务端点。基于Servlet的服务端点运行在Servlet容器中，基于EJB的服务端点运行在EJB容器中。 </p>
		<p>我们知道，Servlet可以在客户端的多个调用之间保持会话状态，所以基于Servlet的JAX-RPC Web服务端点要保持客户的会话状态是可行的。但如果是EJB服务端点，由于这里的EJB是无状态会话Bean，所以要在多个调用之间保持状态必须通过其它机制实现，这里不讨论。 </p>
		<p>下面从JAX-RPC的生命周期和ServletEndpointContext接口来说明怎么保持和访问客户端的会话状态。 </p>
		<p>
				<a name="N100C5">
						<span class="smalltitle">
								<strong>
										<font face="Arial">JAX-RPC的生命周期</font>
								</strong>
						</span>
				</a>
		</p>
		<p>
				<strong>
						<font face="Arial">
						</font>
				</strong>
		</p>
		<p>根据JAX-RPC的规范，如果Web服务端点实现javax.xml.rpc.server.ServiceLifecycle接口，那么基于Servlet容器的JAX-RPC运行环境将管理这个端点的生命周期。javax.xml.rpc.server.ServiceLifecycle接口定义如下： </p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">例程1 ServiceLifecycle
package javax.xml.rpc.server;
public interface ServiceLifecycle {
void init(Object context) throws ServiceException;
void destroy();
}
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>JAX-RPC运行环境负责装载并实例化服务端点实例，装载和实例化可以在JAX-RPC运行环境启动时进行，也可以在服务端点处理SOAP RPC请求时进行。JAX-RPC运行环境使用Java类装载机制来装载服务端点，当成功装载目标类后，将实例化这个类。 </p>
		<p>当服务端点实例化后，在RPC请求到达之前JAX-RPC运行环境将初始化它们，这个初始化通过ServiceLifecycle.init方法来进行的。在初始化的过程中，可能需要设置一些访问外部资源的方法。在init方法中，有一个context参数，它用来访问由JAX-RPC运行环境提供的端点上下文（ServletEndpoint Context）。当初始化服务端点后，JAX-RPC运行环境就可以把多个远程调用派发到服务端点。在远程方法调用的过程中，JAX-RPC服务端点并不维持任何客户端的状态。所以JAX-RPC服务端点实例能够被池化（Pooling）。 </p>
		<p>当JAX-RPC运行环境决定移除服务端点实例时，它将调用服务端点实例的destroy方法。比如在系统关闭或者实例池中实例过多时，就可能发生这种操作。在destroy方法中，服务端点将释放占用的资源。当成功调用了destroy方法后，服务端点实例将被垃圾收集器收集。此时它不能处理任何远程方法调用。 </p>
		<p>
				<a name="N100DD">
						<span class="smalltitle">
								<strong>
										<font face="Arial">ServletEndpointContext接口</font>
								</strong>
						</span>
				</a>
		</p>
		<p>
				<strong>
						<font face="Arial">
						</font>
				</strong>
		</p>
		<p>在ServiceLifecycle.init（Object context）方法中，其中参数context就是ServletEndpointContext实例，ServletEndpointContext是由JAX-RPC运行环境维持的端点上下文。JAX-RPC规范规定了基于Servlet的服务端点的编程模型，但并没有为服务端点上下文（Endpoint Context）或者会话（Session）定义与组件模型、容器、绑定协议更通用的抽象，也就是说这些通用的抽象在JAX-RPC规范之外。 </p>
		<p>下面是ServletEndpointContext接口的代码。 </p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">例程2 ServletEndpointContext接口
package javax.xml.rpc.server;
public interface ServletEndpointContext {
public java.security.Principal getUserPrincipal();
public javax.xml.rpc.handler.MessageContext getMessageContext();
public javax.servlet.http.HttpSession getHttpSession();
public javax.servlet.ServletContext getServletContext();
}
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>ServletEndpointContext接口对于会话的保持非常关键，因为它定义了getHttpSession方法，这个方法返回了和当前活动的客户端调用相关的HTTP会话。客户端的会话由JAX-RPC运行环境维持。如果没有相关的HTTP会话，那么这个方法返回null。 </p>
		<p>除了getHttpSession方法外，这个接口还定义了或者SOAP消息上下文，Servlet上下文方法，在这里不讨论了。 </p>
		<p>有了上面的理论，下面我们来开发一个能够使用HTTP会话的Web服务。 </p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/webservices/ws-session/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="3">
						<span class="atitle">
								<font face="Arial" size="4">开发服务端</font>
						</span>
				</a>
		</p>
		<p>
				<br />首先定义一个端点接口，它拥有几个交互操作的方法，如例程3所示。 </p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">例程3 定义服务端点接口
package com.hellking.study.webservice.session;

import java.rmi.Remote;
import java.rmi.RemoteException;
/**
 *Web服务端点接口，它定义了三个服务方法。
 */
public interface SessionTestIF extends Remote {
    public String login(String id,String password) throws RemoteException;
    public String getLoginCount() throws RemoteException;    
    public void logout() throws RemoteException;
}
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>要想在Web服务中访问HTTP会话，那么必须拥有ServletEndpointContext实例，而这个实例必须通过ServiceLifecycle接口的init方法获得。也就是说，要使用HTTP会话，Web服务端点必须实现ServiceLifecycle接口。Web服务实现类如例程4所示。 </p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">例程4 服务实现类
package com.hellking.study.webservice.session;

import java.rmi.Remote.*;
import javax.xml.rpc.server.ServiceLifecycle;
import javax.xml.rpc.server.ServletEndpointContext;
import javax.xml.rpc.handler.soap.SOAPMessageContext;
import java.util.Properties;
import java.io.FileInputStream;
import javax.servlet.http.HttpSession;
/**
 *SessionTestImpl是Web服务实现类，用于测试Web服务中Session的使用。
 *由于要使用Session，需要实现ServiceLifecycle接口。
 */
public class SessionTestImpl implements SessionTestIF,ServiceLifecycle{
 
 //服务端点上下文
 private ServletEndpointContext serviceContext;
    
    /**
     *ServiceLifecycle方法：初始化服务端点，或者要使用的资源。
     */
    public void init(java.lang.Object context)
    {
  serviceContext=(ServletEndpointContext)context;
 }
 /**
     *ServiceLifecycle方法：销毁服务端点实例。
     */
    public void destroy() 
    {
     this.serviceContext=null;
    //可能还有其它释放资源的方法。
    }
 /**
  *Web服务方法：登录，并且保存一些信息到HTTP会话中。
  */
    public String login(String id,String password) 
    {
     String ret=null;//返回值。
     Properties users=new Properties();
     try
     {
      //获得用户名、密码属性，一般是在数据库中，这里简化，把这些信息保存在一个文件中。
        users.load(com.hellking.study.webservice.session.SessionTestImpl.class
          .getResourceAsStream("password.properties"));
     }
     catch(java.io.FileNotFoundException e)
     {
      e.printStackTrace();
     }
     catch(java.io.IOException e)
     {
      e.printStackTrace();
     }
     try
     {
      String passwd=(String)users.getProperty(id);
      if(password.equals(passwd))
      {
       ret="登录成功，你可以执行其它操作！";
    HttpSession session = serviceContext.getHttpSession();
    //保存用户会话状态，它和一般的HTTP会话一样，都使用HttpSession来进行。
    session.setAttribute("isLogin",new Boolean(true));
    session.setAttribute("userId",id);    
    //更新登录次数,在这里省略。
      }
     }
     catch(Exception e)
     {
      ret="登录失败，请确认用户名和密码正确！";
      e.printStackTrace();
     } 
     return ret;
    }
    
    /**
     *Web服务方法：获得登录的次数，需要使用HTTP会话来获得当前user的id。
     */
    public String getLoginCount() 
    {
     String ret=null;//返回值
     HttpSession session = serviceContext.getHttpSession();
        Properties logcount=new Properties();
     try
     {
      //获得用户登录次数。
      logcount.load(com.hellking.study.webservice.session.SessionTestImpl.class
      .getResourceAsStream("login.properties"));
     }
     catch(java.io.FileNotFoundException e)
     {
      e.printStackTrace();
     }
     catch(java.io.IOException e)
     {
      e.printStackTrace();
     }
     try
     {
      //从HTTP会话中获得是否登录的属性。
      Boolean isLogin=(Boolean)session.getAttribute("isLogin");
      String userId=(String)session.getAttribute("userId");
      //如果已经登录，那么返回logcount属性值。
      if(isLogin.equals(Boolean.TRUE))
      {      
       ret=logcount.getProperty(userId);
      }
     }
     catch(Exception e)
     {
      e.printStackTrace();
     }
     return ret;     
    }
    /**
     *注销，使会话无效。
     */    
    public void logout() 
    {
     HttpSession session = serviceContext.getHttpSession();
     session.invalidate();
    }        
}
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在上面代码中，SessionTestImpl 拥有一个ServletEndpointContext成员变量，这个成员变量在init方法初始化： </p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">serviceContext=(ServletEndpointContext)context;
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在login方法中，通过：</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">HttpSession session = serviceContext.getHttpSession();
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>方法来获得和当前客户端关联的HTTP会话，然后可以把一些交互的信息保存在session中，如： </p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">session.setAttribute("isLogin", new Boolean(true));
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>把用户已经登录的信息保存起来。在其它的Web服务方法中，如getLoginCount，可以通过：</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">Boolean isLogin=(Boolean)session.getAttribute("isLogin");
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>之类的方法来获得原来保存的属性值。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/webservices/ws-session/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="4">
						<span class="atitle">
								<font face="Arial" size="4">编写描述符、部署</font>
						</span>
				</a>
		</p>
		<p>
				<br />开发好以上两个类后，需要进行一些相关的描述，编写以下脚本： </p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">例程5 service-config.xml 
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;configuration 
  xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config"&gt;
  &lt;service 
      name="MySessionTestService" 
      targetNamespace="urn:SessionTest" 
      typeNamespace="urn:SessionTest" 
      packageName="sessionTest"&gt;
      &lt;interface name="com.hellking.study.webservice.session.SessionTestIF"/&gt;
  &lt;/service&gt;
&lt;/configuration&gt;
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>通过：</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">wscompile -define -d . -nd . -classpath . service-config.xml
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>命令生成一个名为MySessionTestService.wsdl的Web服务描述文件。再通过：</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">wscompile -gen -classpath . -d . -nd . -mapping mapping.xml service-config.xml
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>生成一个映射文件。另外，还需要编写几个描述符，如webservices.xml、web.xml等，在这里就不介绍了（这些描述符可以通过部署工具自动生成，见本文代码）。由于这个服务端点需要维持会话，所以在web.xml中特别描述了会话的保持时间，如例程6所示。 </p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">例程6 web.xml描述符
&lt;?xml version="1.0" encoding="UTF-8"?&gt;

&lt;!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/j2ee/dtds/web-app_2_3.dtd"&gt;

&lt;web-app&gt;
  &lt;display-name&gt;sessionTest-jaxrpc&lt;/display-name&gt;
  &lt;description&gt;A web application containing a simple JAX-RPC endpoint&lt;/description&gt;
  &lt;servlet&gt;
    &lt;servlet-name&gt;SessionTestServletImpl&lt;/servlet-name&gt;
    &lt;servlet-class&gt;com.hellking.study.webservice.session.SessionTestImpl&lt;/servlet-class&gt;
    &lt;load-on-startup&gt;0&lt;/load-on-startup&gt;
  &lt;/servlet&gt;
  &lt;servlet-mapping&gt;
    &lt;servlet-name&gt;SessionTestServletImpl&lt;/servlet-name&gt;
    &lt;url-pattern&gt;/mysessionTest&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;
  &lt;session-config&gt;
    &lt;session-timeout&gt;60&lt;/session-timeout&gt;
  &lt;/session-config&gt;
&lt;/web-app&gt;
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>可以看出，SessionTestServletImpl是作为Servlet运行的。为了在JAX-RPC环境启动时就实例化这个服务端点，需要设置&lt;load-on-startup&gt;元素值为0。另外，&lt;session-config&gt;元素值指定了客户端和JAX-RPC运行环境之间会话保持的时间。 </p>
		<p>关于打包和部署方法在这里就不赘述了，您可以参考本系列文章《使用EJB2.1无状态会话Bean作为Web服务端点》一文。 </p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/webservices/ws-session/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="5">
						<span class="atitle">
								<font face="Arial" size="4">开发客户端</font>
						</span>
				</a>
		</p>
		<p>
				<br />我们知道，JAX-RPC有三种不同类型的客户端： </p>
		<ul>
				<li>基于Stub； 
</li>
				<li>动态代理； 
</li>
				<li>动态调用。 </li>
		</ul>
		<p>下面讨论怎么在基于Stub和基于动态调用的客户端使用Web服务会话。 </p>
		<p>
				<a name="N10171">
						<span class="smalltitle">
								<strong>
										<font face="Arial">基于Stub的客户端</font>
								</strong>
						</span>
				</a>
		</p>
		<p>
				<strong>
						<font face="Arial">
						</font>
				</strong>
		</p>
		<p>我们不得不从Stub接口的SESSION_MAINTAIN_PROPERTY属性说起，如果在客户端设置这个属性为Boolean.TRUE，那么在Web服务交互过程中，服务端将维持一个HTTP会话，否则不会维持HTTP会话。基于Stub的客户端代码如例程7所示。 </p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">例程7 基于Stub的客户端
package com.hellking.study.webservice.session;
import javax.xml.rpc.Stub;
/**
 *Web服务调用客户端,测试Web服务会话。基于Stub的调用。
 */
public class SessionTestClientUseStub
{
  
   Stub stub;
   SessionTestIF sessionTest;
   //初始化Stub。
   public SessionTestClientUseStub()
   {
       stub = (Stub)(new MySessionTestService_Impl().getSessionTestIFPort());
       stub._setProperty(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY, 
                "http://127.0.0.1:8080/sessionTest/mysessionTest"); 
       stub._setProperty(Stub.SESSION_MAINTAIN_PROPERTY,Boolean.TRUE);
       sessionTest = (SessionTestIF)stub;
    }
   
    public static void main(String[] args) 
    {
  SessionTestClientUseStub test=new SessionTestClientUseStub();
  test.login();
  test.getLoginCount();
  test.logout();
        
    }
    /**
     *登录。
     */
    public void login()
    {
     try {           
             System.out.println("正在登录...");
            System.out.println(sessionTest.login("userid-001","abc"));
        } catch (Exception ex) {
            ex.printStackTrace();
        }  
   }
   /**
    *获得logincount属性值。
    */
   public void getLoginCount()
   {
      try
      {
       System.out.println("LoginCount的值为：");
       System.out.println(sessionTest.getLoginCount());
      }
      catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    /**
     *注销。
     */
    public void logout()
    {
   …//省略代码
    }
}
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在服务调用之前，通过：</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">stub._setProperty(Stub.SESSION_MAINTAIN_PROPERTY,Boolean.TRUE);
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>方法来设置SESSION_MAINTAIN_PROPERTY属性。 </p>
		<p>部署好服务端后，运行这个代码将获得如图1所示的结果。 </p>
		<br />
		<img alt="" src="http://www-128.ibm.com/developerworks/cn/webservices/ws-session/figure1.gif" />
		<br />
		<p>图1 使用会话的测试结果</p>
		<p>可以看出，上面的调用达到了预期的效果。因为在getLoginCount方法中并没有传入任何参数，但获得了前一个方法中登录id的LoginCount值。 </p>
		<p>如果我们屏蔽：</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">stub._setProperty(Stub.SESSION_MAINTAIN_PROPERTY,Boolean.TRUE)；
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>代码，或者更改为以下代码：</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">stub._setProperty(Stub.SESSION_MAINTAIN_PROPERTY,Boolean.FALSE)；
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>编译后再运行这个客户端，将获得如图2所示的结果。 </p>
		<br />
		<img alt="" src="http://www-128.ibm.com/developerworks/cn/webservices/ws-session/figure2.gif" />
		<br />
		<p>图2 不使用会话的测试结果</p>
		<p>可以看出，这里返回的LoginCount为null，说明客户端的会话并没有保持。 </p>
		<p>
				<a name="N101C8">
						<span class="smalltitle">
								<strong>
										<font face="Arial">基于动态调用客户端</font>
								</strong>
						</span>
				</a>
		</p>
		<p>
				<strong>
						<font face="Arial">
						</font>
				</strong>
		</p>
		<p>基于动态调用客户端主要是通过javax.xml.rpc.Call接口来进行的。和基于Stub的客户端一样，也必须先设置一个属性（Call.SESSION_MAINTAIN_PROPERTY）为Boolean.TRUE时才能使用HTTP会话。 </p>
		<p>我们看这个客户端的部分代码，如例程8所示。 </p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">例程8 基于Call的客户端
package com.hellking.study.webservice.session;

… // imports
/**
 *测试Web服务会话的使用
 */
public class SessionTestClient {
    //一些调用参数。
    private static String qnameService = "MySessionTestService";
    private static String qnamePort = "SessionTestIFPort";

    private static String BODY_NAMESPACE_VALUE =   "urn:SessionTest";
    private static String ENCODING_STYLE_PROPERTY =
         "javax.xml.rpc.encodingstyle.namespace.uri"; 
    private static String NS_XSD =   "http://www.w3.org/2001/XMLSchema";
    private static String URI_ENCODING =  "http://schemas.xmlsoap.org/soap/encoding/";
         
    ServiceFactory factory;
    Service service; 
    Call call;
    QName port;
   //初始化。 
   public SessionTestClient()
   {
        try
        {
          factory = ServiceFactory.newInstance();
          service =  factory.createService(new QName(qnameService));
          port = new QName(qnamePort);
          call = service.createCall(port);
          call.setTargetEndpointAddress("http://127.0.0.1:8000/sessionTest/mysessionTest");
          …//省略部分代码
    }
    catch(Exception e)
    {
     e.printStackTrace();
    }       
    
   }
   /**
    *测试login操作。
    */
   
   public void login()
    {
     try {
       
            QName QNAME_TYPE_STRING = new QName(NS_XSD, "string");
            call.setReturnType(QNAME_TYPE_STRING);
            call.setProperty(Call.SESSION_MAINTAIN_PROPERTY,Boolean.TRUE);
            call.setOperationName(new QName(BODY_NAMESPACE_VALUE,"login"));
            call.addParameter("String_1", QNAME_TYPE_STRING, 
                ParameterMode.IN);
            call.addParameter("String_2", QNAME_TYPE_STRING, 
                ParameterMode.IN);    
            String[] params = {new String("userid-001"),new String("abc")};
            String result = (String)call.invoke(params);
            System.out.println("正在登录...");
            System.out.println(result);

        } catch (Exception ex) {
            ex.printStackTrace();
       }
    }
    /**
     *和Web服务交互，获得LoginCount值。
     */
    public void getLoginCount()
    {
     try {
      
            call.removeAllParameters();         
            …//省略部分代码
             call.setProperty(Call.SESSION_MAINTAIN_PROPERTY,Boolean.TRUE);
             …//省略部分代码
            String result = (String)call.invoke(params);
            System.out.println(result);

        } catch (Exception ex) {
            ex.printStackTrace();
       }
     
    }
    /**
     *和Web服务交互,注销操作
     */
    public void logout()
    {
       try {
            call.removeAllParameters();    
              call.setProperty(Call.SESSION_MAINTAIN_PROPERTY,Boolean.TRUE);
            …//省略部分代码
       }
    public static void main(String[] args) {
     SessionTestClient test=new SessionTestClient();
     test.login();
     test.getLoginCount();
     test.logout();
    }       
}
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>它的运行结果如图3所示。 </p>
		<br />
		<img alt="" src="http://www-128.ibm.com/developerworks/cn/webservices/ws-session/figure3.gif" />
		<br />
		<p>图3 基于Call的调用</p>
		<p>可以看出，它同样获得了预期的结果。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/webservices/ws-session/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="6">
						<span class="atitle">
								<font face="Arial" size="4">总结</font>
						</span>
				</a>
		</p>
		<p>
				<br />JAX-RPC以HTTP作为传输协议，那么会话的保持可以从HTTP应用入手。JAX-RPC两种服务端点中，只有基于Servlet的端点才能直接使用HTTP会话。要想在服务端点中访问HTTP会话，Web服务实现类必须实现javax.xml.rpc.server.ServiceLifecycle接口，实现了这个接口的服务端点的生命周期由JAX-RPC运行环境来管理。 </p>
		<p>通过ServletEndpointContext接口的getHttpSession来获得客户端的会话，这个会话由JAX-RPC运行环境维护。如果要在客户端使用HTTP会话，那么不论是Stub还是Call都必须设置SESSION_MAINTAIN_PROPERTY属性值为Boolean.TRUE。<br /><br /><br />来源：<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-session/index.html">http://www-128.ibm.com/developerworks/cn/webservices/ws-session/index.html</a><br /></p>
<img src ="http://www.blogjava.net/SIDNEY/aggbug/56957.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-07-06 15:34 <a href="http://www.blogjava.net/SIDNEY/archive/2006/07/06/56957.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java中四种操作xml方式的比较</title><link>http://www.blogjava.net/SIDNEY/archive/2006/07/04/56487.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Tue, 04 Jul 2006 02:52:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/07/04/56487.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/56487.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/07/04/56487.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/56487.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/56487.html</trackback:ping><description><![CDATA[
		<h3> </h3>作者：<strong>best2010</strong><br /><br /><p>1. 介绍</p><p>1）DOM(JAXP Crimson解析器) <br />        DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找 特定信息。分析该结构通常需要加载整个文档和构造层次结构，然后才能做任何工作。由于它是基于信息层次的，因而DOM被认为是基于树或基于对象的。DOM 以及广义的基于树的处理具有几个优点。首先，由于树在内存中是持久的，因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下 导航，而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。</p><p>2）SAX</p><p>        SAX处理的优点非常类似于流媒体的优点。分析能够立即开始，而不是等待所有的数据被处理。而且，由于应用程序只是在读取数据时检查数据，因此不需要将数 据存储在内存中。这对于大型文档来说是个巨大的优点。事实上，应用程序甚至不必解析整个文档；它可以在某个条件得到满足时停止解析。一般来说，SAX还比 它的替代者DOM快许多。 <br /> 　　选择DOM还是选择SAX？ 对于需要自己编写代码来处理XML文档的开发人员来说，  选择DOM还是SAX解析模型是一个非常重要的设计决策。 DOM采用建立树形结构的方式访问XML文档，而SAX采用的事件模型。 <br /><br />　 　DOM解析器把XML文档转化为一个包含其内容的树，并可以对树进行遍历。用DOM解析模型的优点是编程容易，开发人员只需要调用建树的指令，然后利用 navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用DOM解析器的时候需要处理整个XML文 档，所以对性能和内存的要求比较高，尤其是遇到很大的XML文件的时候。由于它的遍历能力，DOM解析器常用于XML文档需要频繁的改变的服务中。 <br /><br />　 　SAX解析器采用了基于事件的模型，它在解析XML文档的时候可以触发一系列的事件，当发现给定的tag的时候，它可以激活一个回调方法，告诉该方法制 定的标签已经找到。SAX对内存的要求通常会比较低，因为它让开发人员自己来决定所要处理的tag。特别是当开发人员只需要处理文档中所包含的部分数据 时，SAX这种扩展能力得到了更好的体现。但用SAX解析器的时候编码工作会比较困难，而且很难同时访问同一个文档中的多处不同数据。 </p><p>3）JDOM           <a href="http://www.jdom.org/">http://www.jdom.org</a></p><p>          JDOM的目的是成为Java特定文档模型，它简化与XML的交互并且比使用DOM实现更快。由于是第一个Java特定模型，JDOM一直得到大力推广和 促进。正在考虑通过“Java规范请求JSR-102”将它最终用作“Java标准扩展”。从2000年初就已经开始了JDOM开发。 </p><p>　　JDOM与DOM主要有两方面不同。首先，JDOM仅使用具体类而不使用接口。这在某些方面简化了API，但是也限制了灵活性。第二，API大量使用了Collections类，简化了那些已经熟悉这些类的Java开发者的使用。 </p><p>　 　JDOM文档声明其目的是“使用20%(或更少)的精力解决80%(或更多)Java/XML问题”(根据学习曲线假定为20%)。JDOM对于大多数 Java/XML应用程序来说当然是有用的，并且大多数开发者发现API比DOM容易理解得多。JDOM还包括对程序行为的相当广泛检查以防止用户做任何 在XML中无意义的事。然而，它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情况下的错误)。这也许是比学习DOM或JDOM接口 都更有意义的工作。 </p><p>　　JDOM自身不包含解析器。它通常使用SAX2解析器来解析和验证输入XML文档(尽管它还可以将以前构造的 DOM表示作为输入)。它包含一些转换器以将JDOM表示输出成SAX2事件流、DOM模型或XML文本文档。JDOM是在Apache许可证变体下发布 的开放源码。</p><p>4）DOM4J <a href="http://dom4j.sourceforge.net/">http://dom4j.sourceforge.net</a> <br />             <br />        虽然DOM4J代表了完全独立的开发结果，但最初，它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能，包括集成的XPath支持、 XML Schema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项，它通过DOM4J API和标准DOM接口具有并行访问功能。从2000下半年开始，它就一直处于开发之中。 </p><p>　　为支持所有这些功能，DOM4J使用接口 和抽象基本类方法。DOM4J大量使用了API中的Collections类，但是在许多情况下，它还提供一些替代方法以允许更好的性能或更直接的编码方 法。直接好处是，虽然DOM4J付出了更复杂的API的代价，但是它提供了比JDOM大得多的灵活性。 </p><p>　　在添加灵活性、XPath集 成和对大文档处理的目标时，DOM4J的目标与JDOM是一样的：针对Java开发者的易用性和直观操作。它还致力于成为比JDOM更完整的解决方案，实 现在本质上处理所有Java/XML问题的目标。在完成该目标时，它比JDOM更少强调防止不正确的应用程序行为。 </p><p>　　DOM4J是一 个非常非常优秀的Java XML API，具有性能优异、功能强大和极端易用使用的特点，同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写 XML，特别值得一提的是连Sun的JAXM也在用DOM4J。 <br /></p><p>2.. 比较</p><p>1）DOM4J性能最好，连Sun的JAXM也在用DOM4J。目前许多开源项目中大量采用DOM4J，例如大名鼎鼎的Hibernate也用DOM4J来读取XML配置文件。如果不考虑可移植性，那就采用DOM4J.</p><p>2） JDOM和DOM在性能测试时表现不佳，在测试10M文档时内存溢出。在小文档情况下还值得考虑使用DOM和JDOM。虽然JDOM的开发者已经说明他们 期望在正式发行版前专注性能问题，但是从性能观点来看，它确实没有值得推荐之处。另外，DOM仍是一个非常好的选择。DOM实现广泛应用于多种编程语言。 它还是许多其它与XML相关的标准的基础，因为它正式获得W3C推荐(与基于非标准的Java模型相对)，所以在某些类型的项目中可能也需要它(如在 JavaScript中使用DOM)。</p><p>3）SAX表现较好，这要依赖于它特定的解析方式－事件驱动。一个SAX检测即将到来的XML流，但并没有载入到内存(当然当XML流被读入时，会有部分文档暂时隐藏在内存中)。</p><p>3. 四种xml操作方式的基本使用方法</p><p>xml文件：</p><p>＜?xml version="1.0" encoding="GB2312"?＞<br />＜RESULT＞<br />    ＜VALUE＞ <br />　　      ＜NO＞A1234＜/NO＞ <br />　　     ＜ADDR＞四川省XX县XX镇XX路X段XX号＜/ADDR＞<br />    ＜/VALUE＞<br />    ＜VALUE＞ <br />　　      ＜NO＞B1234＜/NO＞ <br />　     　＜ADDR＞四川省XX市XX乡XX村XX组＜/ADDR＞<br />    ＜/VALUE＞<br />＜/RESULT＞ </p><p>1）DOM</p><p>import java.io.*;<br />import java.util.*;<br />import org.w3c.dom.*;<br />import javax.xml.parsers.*; </p><p>public class MyXMLReader{ <br />　public static void main(String arge[]){ </p><p>　　long lasting =System.currentTimeMillis(); <br />　　try{  <br />　　　File f=new File("data_10k.xml"); <br />　　　DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); <br />　　　DocumentBuilder builder=factory.newDocumentBuilder(); <br />　　　Document doc = builder.parse(f); <br />　　　NodeList nl = doc.getElementsByTagName("VALUE"); <br />　　　for (int i=0;i＜nl.getLength();i++){ <br />　　　　System.out.print("车牌号码:" + doc.getElementsByTagName("NO").item(i).getFirstChild().getNodeValue()); <br />　　　　System.out.println("车主地址:" + doc.getElementsByTagName("ADDR").item(i).getFirstChild().getNodeValue()); <br />　 　} <br />　　}catch(Exception e){ <br />　　　e.printStackTrace(); <br />} </p><p>2）SAX</p><p>import org.xml.sax.*;<br />import org.xml.sax.helpers.*;<br />import javax.xml.parsers.*; </p><p>public class MyXMLReader extends DefaultHandler { </p><p>　java.util.Stack tags = new java.util.Stack(); <br />　public MyXMLReader() { <br />　　super();<br />   } </p><p>　public static void main(String args[]) { <br />　　long lasting = System.currentTimeMillis(); <br />　　try { <br />　　　SAXParserFactory sf = SAXParserFactory.newInstance(); <br />　　　SAXParser sp = sf.newSAXParser(); <br />　　　MyXMLReader reader = new MyXMLReader(); <br />　　　sp.parse(new InputSource("data_10k.xml"), reader); <br />　　} catch (Exception e) { <br />　　　e.printStackTrace(); <br />　　} </p><p>　　System.out.println("运行时间：" + (System.currentTimeMillis() - lasting) + "毫秒");} <br />　　public void characters(char ch[], int start, int length) throws SAXException { <br />　　String tag = (String) tags.peek(); <br />　　if (tag.equals("NO")) {  <br />　　　System.out.print("车牌号码：" + new String(ch, start, length));<br />    }<br />    if (tag.equals("ADDR")) { <br />　　System.out.println("地址:" + new String(ch, start, length));<br />    }<br />   } </p><p>　　public void startElement(String uri,String localName,String qName,Attributes attrs) { <br />　　tags.push(qName);}<br />}  </p><p>3） JDOM</p><p>import java.io.*;<br />import java.util.*;<br />import org.jdom.*;<br />import org.jdom.input.*; </p><p>public class MyXMLReader { </p><p>　public static void main(String arge[]) { <br />　　long lasting = System.currentTimeMillis(); <br />　　try { <br />　　　SAXBuilder builder = new SAXBuilder();  <br />　　　Document doc = builder.build(new File("data_10k.xml"));  <br />　　　Element foo = doc.getRootElement();  <br />　　　List allChildren = foo.getChildren();  <br />　　　for(int i=0;i＜allChildren.size();i++) {  <br />　　　　System.out.print("车牌号码:" + ((Element)allChildren.get(i)).getChild("NO").getText()); <br />　　　　System.out.println("车主地址:" + ((Element)allChildren.get(i)).getChild("ADDR").getText()); <br />　　　} <br />　　} catch (Exception e) { <br />　　　e.printStackTrace(); <br />} </p><p>}</p><p>4）DOM4J</p><p>import java.io.*;<br />import java.util.*;<br />import org.dom4j.*;<br />import org.dom4j.io.*; </p><p>public class MyXMLReader { </p><p>　public static void main(String arge[]) { <br />　　long lasting = System.currentTimeMillis(); <br />　　try { <br />　　　File f = new File("data_10k.xml"); <br />　　　SAXReader reader = new SAXReader(); <br />　　　Document doc = reader.read(f); <br />　　　Element root = doc.getRootElement(); <br />　　　Element foo; <br />　　　for (Iterator i = root.elementIterator("VALUE"); i.hasNext();) { <br />　　　　foo = (Element) i.next(); <br />　　　　System.out.print("车牌号码:" + foo.elementText("NO")); <br />　　　　System.out.println("车主地址:" + foo.elementText("ADDR")); <br />　　　} <br />　　} catch (Exception e) { <br />　　　e.printStackTrace(); <br />    } <br />}</p> <br /><br /><p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=845972</p><img src ="http://www.blogjava.net/SIDNEY/aggbug/56487.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-07-04 10:52 <a href="http://www.blogjava.net/SIDNEY/archive/2006/07/04/56487.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Axis发布简单的Web服务 </title><link>http://www.blogjava.net/SIDNEY/archive/2006/07/03/webservice.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Mon, 03 Jul 2006 06:40:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/07/03/webservice.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/56345.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/07/03/webservice.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/56345.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/56345.html</trackback:ping><description><![CDATA[
		<p>使用Axis，要发布一个Web服务非常简单，简直不能再简单了，尽管看起来过程和相关代码有些长。我这个帖子里用到了这些软件：Axis 1.1、Eclipse 2.1和Eclipse的Tomcat插件2.2（<a href="http://www.sysdeo.com/eclipse/tomcatPlugin.html"><font color="#000080">Sysdeo Tomcat plugin</font></a>）。发布的方法如下：</p>
		<p>我要发布的服务是一个图书商店，公布的方法有添加图书addBook、列表图书listBooks、删除图书deleteBook等等，为简单起见这里就只发布一个添加图书方法，因为其他方法的发布是类似的。</p>
		<p>1、首先在Eclipse里新建一个名为bookstore的Tomcat工程，注意要安装了前面说的Tomcat插件才有这个选项的。如果没有安装可以建立一个java工程，然后手动建立必要的目录结构（WEB-INF等），并在Tomcat的server.xml里手动增加与项目对应的&lt;context&gt;项。</p>
		<p>2、接下来建立图书类（com.bookstore.model.Book），图书有名称、ISDN号和页数三个属性，这是一个Bean类，代码如下：</p>
		<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
				<div>
						<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #000000">package com.bookstore.model;<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />public class Book {<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    private String name;<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    private String ISDN;<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    private </span>
						<span style="COLOR: #0000ff">int</span>
						<span style="COLOR: #000000"> page;<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    public String getISDN() {<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #0000ff">return</span>
						<span style="COLOR: #000000"> ISDN;<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    }<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    public String getName() {<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #0000ff">return</span>
						<span style="COLOR: #000000"> name;<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    }<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    public </span>
						<span style="COLOR: #0000ff">int</span>
						<span style="COLOR: #000000"> getPage() {<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #0000ff">return</span>
						<span style="COLOR: #000000"> page;<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    }<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    public </span>
						<span style="COLOR: #0000ff">void</span>
						<span style="COLOR: #000000"> setISDN(String string) {<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />        ISDN </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> string;<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    }<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    public </span>
						<span style="COLOR: #0000ff">void</span>
						<span style="COLOR: #000000"> setName(String string) {<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />        name </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> string;<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    }<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    public </span>
						<span style="COLOR: #0000ff">void</span>
						<span style="COLOR: #000000"> setPage(</span>
						<span style="COLOR: #0000ff">int</span>
						<span style="COLOR: #000000"> i) {<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />        page </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> i;<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    }<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />}<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /></span>
				</div>
		</div>
		<p>3、接下来建立用来提供服务的类（com.bookstore.BookSvc），这个类就是实际的功能类了，它里面只有一个public的addBook()方法，而它的参数只有一个就是要添加的图书。代码如下：</p>
		<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
				<div>
						<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #000000">package com.bookstore;<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />import com.bookstore.model.Book;<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />public class BookSvc {<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    <br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    public </span>
						<span style="COLOR: #0000ff">void</span>
						<span style="COLOR: #000000"> addBook(Book book){<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #008000">//</span>
						<span style="COLOR: #008000">here you save a book into database</span>
						<span style="COLOR: #008000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
						</span>
						<span style="COLOR: #000000">        System.out.println(</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">Book has been added.</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">);<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    }<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />}<br /><img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /></span>
				</div>
		</div>
		<p>4、现在，把下载来的Axis解压缩到一个文件夹，这里假设你解到C:\axis-1_1。把C:\axis-1_1\webapps\axis\WEB-INF\lib目录下的所有.jar文件复制到你的这个web应用程序的WEB-INF\lib下，再把C:\axis-1_1\webapps\axis\WEB-INF目录下的web.xml复制到你的web应用程序的WEB-INF下。这个步骤相当于在你的web应用程序中配置了Axis。</p>
		<p>5、为了让Axis知道你要发布哪些服务，你得在WEB-INF下建立一个名为server-config.wsdd的文件，内容如下：</p>
		<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
				<div>
						<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #0000ff">&lt;?</span>
						<span style="COLOR: #ff00ff">xml version="1.0" encoding="UTF-8"</span>
						<span style="COLOR: #0000ff">?&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
						</span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">deployment </span>
						<span style="COLOR: #ff0000">xmlns</span>
						<span style="COLOR: #0000ff">="http://xml.apache.org/axis/wsdd/"</span>
						<span style="COLOR: #ff0000"> xmlns:java</span>
						<span style="COLOR: #0000ff">="http://xml.apache.org/axis/wsdd/providers/java"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">globalConfiguration</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="adminPassword"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">="admin"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="attachments.Directory"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">="C:\eclipse\workspace\bookstore\WEB-INF\attachments"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="attachments.implementation"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">="org.apache.axis.attachments.AttachmentsImpl"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="sendXsiTypes"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">="true"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="sendMultiRefs"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">="true"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="sendXMLDeclaration"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">="true"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="axis.sendMinimizedElements"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">="true"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">requestFlow</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />   </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">handler </span>
						<span style="COLOR: #ff0000">type</span>
						<span style="COLOR: #0000ff">="java:org.apache.axis.handlers.JWSHandler"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="scope"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">="session"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />   </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">handler</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />   </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">handler </span>
						<span style="COLOR: #ff0000">type</span>
						<span style="COLOR: #0000ff">="java:org.apache.axis.handlers.JWSHandler"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="scope"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">="request"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="extension"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">=".jwr"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />   </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">handler</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">requestFlow</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">globalConfiguration</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">handler </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="LocalResponder"</span>
						<span style="COLOR: #ff0000"> type</span>
						<span style="COLOR: #0000ff">="java:org.apache.axis.transport.local.LocalResponder"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">handler </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="Authenticate"</span>
						<span style="COLOR: #ff0000"> type</span>
						<span style="COLOR: #0000ff">="java:org.apache.axis.handlers.SimpleAuthenticationHandler"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">handler </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="URLMapper"</span>
						<span style="COLOR: #ff0000"> type</span>
						<span style="COLOR: #0000ff">="java:org.apache.axis.handlers.http.URLMapper"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">service </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="Version"</span>
						<span style="COLOR: #ff0000"> provider</span>
						<span style="COLOR: #0000ff">="java:RPC"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="allowedMethods"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">="getVersion"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="className"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">="org.apache.axis.Version"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">service</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">service </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="BookSvc"</span>
						<span style="COLOR: #ff0000"> provider</span>
						<span style="COLOR: #0000ff">="java:RPC"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="allowedMethods"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">="*"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="className"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">="com.bookstore.BookSvc"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">service</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">service </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="AdminService"</span>
						<span style="COLOR: #ff0000"> provider</span>
						<span style="COLOR: #0000ff">="java:MSG"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="allowedMethods"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">="AdminService"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="enableRemoteAdmin"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">="false"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="className"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">="org.apache.axis.utils.Admin"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">namespace</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">http://xml.apache.org/axis/wsdd/</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">namespace</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">service</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">transport </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="local"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">responseFlow</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />   </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">handler </span>
						<span style="COLOR: #ff0000">type</span>
						<span style="COLOR: #0000ff">="LocalResponder"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">responseFlow</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">transport</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">transport </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="http"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">requestFlow</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />   </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">handler </span>
						<span style="COLOR: #ff0000">type</span>
						<span style="COLOR: #0000ff">="URLMapper"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />   </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">handler </span>
						<span style="COLOR: #ff0000">type</span>
						<span style="COLOR: #0000ff">="java:org.apache.axis.handlers.http.HTTPAuthHandler"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">requestFlow</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">transport</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
						</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">deployment</span>
						<span style="COLOR: #0000ff">&gt;</span>
				</div>
		</div>
		<p>这个文件里发布了三个服务：Version、AdminService和我们的BookSvc。还有一个方法可以生成这个文件，好象Axis推荐使用这种生成的方法，就是在同样目录下写一个deploy.wsdd文件（如果不想看可以直接跳到下一步），内容如下：</p>
		<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
				<div>
						<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">deployment </span>
						<span style="COLOR: #ff0000">xmlns</span>
						<span style="COLOR: #0000ff">="http://xml.apache.org/axis/wsdd/"</span>
						<span style="COLOR: #ff0000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />            xmlns:java</span>
						<span style="COLOR: #0000ff">="http://xml.apache.org/axis/wsdd/providers/java"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">service </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="BookSvc"</span>
						<span style="COLOR: #ff0000"> provider</span>
						<span style="COLOR: #0000ff">="java:RPC"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="className"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">="com.bookstore.BookSvc"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">parameter </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="allowedMethods"</span>
						<span style="COLOR: #ff0000"> value</span>
						<span style="COLOR: #0000ff">="*"</span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">service</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
						</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">deployment</span>
						<span style="COLOR: #0000ff">&gt;</span>
				</div>
		</div>
		<p>也就是说deploy.wsdd里只包含关于我们的服务的描述，确认Tomcat已经启动，然后在同一目录下用下面这个命令生成server-config.wsdd文件：</p>
		<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
				<div>
						<img src="http://bjzhanghao.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #000000">java org.apache.axis.client.AdminClient </span>
						<span style="COLOR: #000000">-</span>
						<span style="COLOR: #000000">lhttp:</span>
						<span style="COLOR: #008000">//</span>
						<span style="COLOR: #008000">localhost:8080/bookstore/services/AdminService deploy.wsdd</span>
				</div>
		</div>
		<p>其中bookstore是我这个web应用程序的虚拟路径。</p>
		<p align="justify">6、重新启动Tomcat，访问路径<a href="http://localhost:8080/bookstore/services"><font color="#000080">http://localhost:8080/bookstore/services</font></a>，就可以看到现在发布了三个Web服务，如下图。点击每个服务后的wsdl链接可以看到对应的WSDL描述。</p>
		<p align="center">
				<img height="396" src="http://bjzhanghao.cnblogs.com/images/cnblogs_com/bjzhanghao/axis-services.gif" width="594" border="0" />
		</p>
<img src ="http://www.blogjava.net/SIDNEY/aggbug/56345.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-07-03 14:40 <a href="http://www.blogjava.net/SIDNEY/archive/2006/07/03/webservice.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>浅谈SOAP </title><link>http://www.blogjava.net/SIDNEY/archive/2006/07/03/soap.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Mon, 03 Jul 2006 02:58:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/07/03/soap.html</guid><description><![CDATA[随着计算机技术的不断发展，现代企业面临的环境越来越复杂，其信息系统大多数为多平台、多系统的复杂系统。这就要求今天的企业解决方案具有广泛的兼容能力，可以支持不同的系统平台、数据格式和多种连接方式，要求在 
<p><span class="myp11">Internet 环境下，实现系统是松散耦合的、跨平台的，与语言无关的，与特定接口无关的，而且要提供对Web 应用程序的可靠访问。 <br /><br />　　随着异种计算环境的不断增加，各种系统间的互操作性就愈显得必要，要求系统能够无缝地进行通信和共享数据，从而在Internet环境下，消除巨大的信息孤岛，实现信息共享、进行数据交换，达到信息的一致性。Web services 希望实现不同的系统之间能够用“软件-软件对话”的方式相互调用，打破了软件应用、网站和各种设备之间的格格不入的状态，实现“基于WEB无缝集成”的目标。<br /><br /></span></p><center><img src="http://www.pconline.com.cn/pcedu/empolder/wz/xml/0404/pic/78504.gif" /></center><center><font color="#000099"><strong>什么是SOAP？</strong></font></center><p><br />　　SOAP（Simple Object Access Protocol ）简单对象访问协议是在分散或分布式的环境中交换信息的简单的协议，是一个基于XML的协议，它包括四个部分：SOAP封装(envelop)，封装定义了一个描述消息中的内容是什么，是谁发送的，谁应当接受并处理它以及如何处理它们的框架；SOAP编码规则（encoding rules），用于表示应用程序需要使用的数据类型的实例; SOAP RPC表示(RPC representation)，表示远程过程调用和应答的协定;SOAP绑定（binding），使用底层协议交换信息。 <br /><br />　　虽然这四个部分都作为SOAP的一部分，作为一个整体定义的，但他们在功能上是相交的、彼此独立的。特别的，信封和编码规则是被定义在不同的XML命名空间(namespace)中，这样使得定义更加简单。<br /><br /><a href="http://www.pconline.com.cn/pcedu/empolder/wz/xml/0404/348921.html">http://www.pconline.com.cn/pcedu/empolder/wz/xml/0404/348921.html</a> <br /><br /><br /></p><center><font color="#000099"><strong>SOAP=RPC+HTTP+XML</strong></font></center><p>　　SOAP简单的理解，就是这样的一个开放协议SOAP=RPC+HTTP+XML：采用HTTP作为底层通讯协议；RPC作为一致性的调用途径，ＸＭＬ作为数据传送的格式，允许服务提供者和服务客户经过防火墙在INTERNET进行通讯交互。RPC的描叙可能不大准确，因为SOAP一开始构思就是要实现平台与环境的无关性和独立性，每一个通过网络的远程调用都可以通过SOAP封装起来，包括DCE（Distributed Computing Environment ）　RPC CALLS，COM/DCOM CALLS, CORBA CALLS, JAVA CALLS，etc。 <br /><br />　　SOAP 使用 HTTP 传送 XML，尽管HTTP 不是有效率的通讯协议，而且 XML 还需要额外的文件解析（parse），两者使得交易的速度大大低于其它方案。但是XML 是一个开放、健全、有语义的讯息机制，而 HTTP 是一个广泛又能避免许多关于防火墙的问题，从而使SOAP得到了广泛的应用。但是如果效率对你来说很重要，那么你应该多考虑其它的方式，而不要用 SOAP。 <br /></p><img src ="http://www.blogjava.net/SIDNEY/aggbug/56262.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-07-03 10:58 <a href="http://www.blogjava.net/SIDNEY/archive/2006/07/03/soap.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字符集编码 问题研究 </title><link>http://www.blogjava.net/SIDNEY/archive/2006/06/12/52113.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Mon, 12 Jun 2006 01:36:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/06/12/52113.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/52113.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/06/12/52113.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/52113.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/52113.html</trackback:ping><description><![CDATA[
		<h1 style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; TEXT-ALIGN: center" align="center">问题研究</h1>
		<p class="MsoBodyTextIndent" style="MARGIN-BOTTOM: 24pt; TEXT-INDENT: 21pt; TEXT-ALIGN: center" align="center">--字符集编码</p>
		<p class="1">1. 概述</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 22pt">本文主要包括以下几个方面：编码基本知识，java，系统软件，url，工具软件等。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 22pt">在下面的描述中，将以"中文"两个字为例，经查表可以知道其GB2312编码是"<u>d6d0 cec4</u>"，Unicode编码为"<u>4e2d 6587</u>"，UTF编码就是"<u>e4b8ad e69687</u>"。注意，这两个字没有iso8859-1编码，但可以用iso8859-1编码来"表示"。</p>
		<p class="1">2. 编码基本知识</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">最早的编码是iso8859-1，和ascii编码相似。但为了方便表示各种各样的语言，逐渐出现了很多标准编码，重要的有如下几个。</p>
		<p class="2">2.1. iso8859-1</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">属于单字节编码，最多能表示的字符范围是0-255，应用于英文系列。比如，字母'a'的编码为0x61=97。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">很明显，iso8859-1编码表示的字符范围很窄，无法表示中文字符。但是，由于是单字节编码，和计算机最基础的表示单位一致，所以很多时候，仍旧使用iso8859-1编码来表示。而且在很多协议上，默认使用该编码。比如，虽然"中文"两个字不存在iso8859-1编码，以gb2312编码为例，应该是"<u>d6d0 cec4</u>"两个字符，使用iso8859-1编码的时候则将它拆开为4个字节来表示："<u>d6 d0 ce c4</u>"（事实上，在进行存储的时候，也是以字节为单位处理的）。而如果是UTF编码，则是6个字节"<u>e4 b8 ad e6 96 87</u>"。很明显，这种表示方法还需要以另一种编码为基础。</p>
		<p class="2">2.2. GB2312/GBK</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">这就是汉子的国标码，专门用来表示汉字，是双字节编码，而英文字母和iso8859-1一致（兼容iso8859-1编码）。其中gbk编码能够用来同时表示繁体字和简体字，而gb2312只能表示简体字，gbk是兼容gb2312编码的。</p>
		<p class="2">2.3. unicode</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">这是最统一的编码，可以用来表示所有语言的字符，而且是定长双字节（也有四字节的）编码，包括英文字母在内。所以可以说它是不兼容iso8859-1编码的，也不兼容任何编码。不过，相对于iso8859-1编码来说，uniocode编码只是在前面增加了一个0字节，比如字母'a'为"<u>00 61</u>"。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 22pt">需要说明的是，定长编码便于计算机处理（注意GB2312/GBK不是定长编码），而unicode又可以用来表示所有字符，所以在很多软件内部是使用unicode编码来处理的，比如java。</p>
		<p class="2">2.4. UTF</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">考虑到unicode编码不兼容iso8859-1编码，而且容易占用更多的空间：因为对于英文字母，unicode也需要两个字节来表示。所以unicode不便于传输和存储。因此而产生了utf编码，utf编码兼容iso8859-1编码，同时也可以用来表示所有语言的字符，不过，utf编码是不定长编码，每一个字符的长度从1-6个字节不等。另外，utf编码自带简单的校验功能。一般来讲，英文字母都是用一个字节表示，而汉字使用三个字节。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">注意，虽然说utf是为了使用更少的空间而使用的，但那只是相对于unicode编码来说，如果已经知道是汉字，则使用GB2312/GBK无疑是最节省的。不过另一方面，值得说明的是，虽然utf编码对汉字使用3个字节，但即使对于汉字网页，utf编码也会比unicode编码节省，因为网页中包含了很多的英文字符。</p>
		<p class="1">3. java对字符的处理</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">在java应用软件中，会有多处涉及到字符集编码，有些地方需要进行正确的设置，有些地方需要进行一定程度的处理。</p>
		<p class="2">3.1. getBytes(charset)</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">这是java字符串处理的一个标准函数，其作用是将字符串所表示的字符按照charset编码，并以字节方式表示。注意字符串在java内存中总是按unicode编码存储的。比如"中文"，正常情况下（即没有错误的时候）存储为"<u>4e2d 6587</u>"，如果charset为"gbk"，则被编码为"<u>d6d0 cec4</u>"，然后返回字节"<u>d6 d0 ce c4</u>"。如果charset为"utf8"则最后是"<u>e4 b8 ad e6 96 87</u>"。如果是"iso8859-1"，则由于无法编码，最后返回 "<u>3f 3f</u>"（两个问号）。</p>
		<p class="2">3.2. new String(charset)</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">这是java字符串处理的另一个标准函数，和上一个函数的作用相反，将字节数组按照charset编码进行组合识别，最后转换为unicode存储。参考上述getBytes的例子，"gbk" 和"utf8"都可以得出正确的结果"<u>4e2d 6587</u>"，但iso8859-1最后变成了"<u>003f 003f</u>"（两个问号）。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 22pt">因为utf8可以用来表示/编码所有字符，所以new String( str.getBytes( "utf8" ), "utf8" ) === str，即完全可逆。</p>
		<p class="2">3.3. setCharacterEncoding()</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">该函数用来设置http请求或者相应的编码。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">对于request，是指提交内容的编码，指定后可以通过getParameter()则直接获得正确的字符串，如果不指定，则默认使用iso8859-1编码，需要进一步处理。参见下述"表单输入"。值得注意的是在执行setCharacterEncoding()之前，不能执行任何getParameter()。java doc上说明：This method must be called prior to reading request parameters or reading input using getReader()。而且，该指定只对POST方法有效，对GET方法无效。分析原因，应该是在执行第一个getParameter()的时候，java将会按照编码分析所有的提交内容，而后续的getParameter()不再进行分析，所以setCharacterEncoding()无效。而对于GET方法提交表单是，提交的内容在URL中，一开始就已经按照编码分析所有的提交内容，setCharacterEncoding()自然就无效。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">对于response，则是指定输出内容的编码，同时，该设置会传递给浏览器，告诉浏览器输出内容所采用的编码。</p>
		<p class="2">3.4. 处理过程</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">下面分析两个有代表性的例子，说明java对编码有关问题的处理方法。</p>
		<p class="3">3.4.1. 表单输入</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 22pt">User input<u>  *(gbk:d6d0 cec4)  </u>browser<u>  *(gbk:d6d0 cec4)  </u>web server<u>  iso8859-1(00d6 00d 000ce 00c4)  </u>class，需要在class中进行处理：getbytes("iso8859-1")为<u>d6 d0 ce c4</u>，new String("gbk")为<u>d6d0 cec4</u>，内存中以unicode编码则为<u>4e2d 6587</u>。</p>
		<p class="MsoBodyTextIndent" style="MARGIN-LEFT: 43pt; TEXT-INDENT: -21pt; tab-stops: list 43.0pt">
				<span lang="EN-US" style="FONT-SIZE: 11pt; FONT-FAMILY: Wingdings">l</span> 用户输入的编码方式和页面指定的编码有关，也和用户的操作系统有关，所以是不确定的，上例以gbk为例。</p>
		<p class="MsoBodyTextIndent" style="MARGIN-LEFT: 43pt; TEXT-INDENT: -21pt; tab-stops: list 43.0pt">
				<span lang="EN-US" style="FONT-SIZE: 11pt; FONT-FAMILY: Wingdings">l</span> 从browser到web server，可以在表单中指定提交内容时使用的字符集，否则会使用页面指定的编码。而如果在url中直接用?的方式输入参数，则其编码往往是操作系统本身的编码，因为这时和页面无关。上述仍旧以gbk编码为例。</p>
		<p class="MsoBodyTextIndent" style="MARGIN-LEFT: 43pt; TEXT-INDENT: -21pt; tab-stops: list 43.0pt">
				<span lang="EN-US" style="FONT-SIZE: 11pt; FONT-FAMILY: Wingdings">l</span> Web server接收到的是字节流，默认时（getParameter）会以iso8859-1编码处理之，结果是不正确的，所以需要进行处理。但如果预先设置了编码（通过request. setCharacterEncoding ()），则能够直接获取到正确的结果。</p>
		<p class="MsoBodyTextIndent" style="MARGIN-LEFT: 43pt; TEXT-INDENT: -21pt; tab-stops: list 43.0pt">
				<span lang="EN-US" style="FONT-SIZE: 11pt; FONT-FAMILY: Wingdings">l</span> 在页面中指定编码是个好习惯，否则可能失去控制，无法指定正确的编码。</p>
		<p class="3">3.4.2. 文件编译</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 22pt">假设文件是gbk编码保存的，而编译有两种编码选择：gbk或者iso8859-1，前者是中文windows的默认编码，后者是linux的默认编码，当然也可以在编译时指定编码。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 22pt">Jsp<u>  *(gbk:d6d0 cec4)  </u>java file<u>  *(gbk:d6d0 cec4)  </u>compiler read<u>  uincode(gbk: 4e2d 6587; iso8859-1: 00d6 00d 000ce 00c4)  </u>compiler write<u>  utf(gbk: e4b8ad e69687; iso8859-1: *)  </u>compiled file<u>  unicode(gbk: 4e2d 6587; iso8859-1: 00d6 00d 000ce 00c4)  </u>class。所以用gbk编码保存，而用iso8859-1编译的结果是不正确的。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 22pt">class<u>  unicode(4e2d 6587)  </u>system.out / jsp.out<u>  gbk(d6d0 cec4)  </u>os console / browser。</p>
		<p class="MsoBodyTextIndent" style="MARGIN-LEFT: 43pt; TEXT-INDENT: -21pt; tab-stops: list 43.0pt">
				<span lang="EN-US" style="FONT-SIZE: 11pt; FONT-FAMILY: Wingdings">l</span> 文件可以以多种编码方式保存，中文windows下，默认为ansi/gbk。</p>
		<p class="MsoBodyTextIndent" style="MARGIN-LEFT: 43pt; TEXT-INDENT: -21pt; tab-stops: list 43.0pt">
				<span lang="EN-US" style="FONT-SIZE: 11pt; FONT-FAMILY: Wingdings">l</span> 编译器读取文件时，需要得到文件的编码，如果未指定，则使用系统默认编码。一般class文件，是以系统默认编码保存的，所以编译不会出问题，但对于jsp文件，如果在中文windows下编辑保存，而部署在英文linux下运行/编译，则会出现问题。所以需要在jsp文件中用pageEncoding指定编码。</p>
		<p class="MsoBodyTextIndent" style="MARGIN-LEFT: 43pt; TEXT-INDENT: -21pt; tab-stops: list 43.0pt">
				<span lang="EN-US" style="FONT-SIZE: 11pt; FONT-FAMILY: Wingdings">l</span> Java编译的时候会转换成统一的unicode编码处理，最后保存的时候再转换为utf编码。</p>
		<p class="MsoBodyTextIndent" style="MARGIN-LEFT: 43pt; TEXT-INDENT: -21pt; tab-stops: list 43.0pt">
				<span lang="EN-US" style="FONT-SIZE: 11pt; FONT-FAMILY: Wingdings">l</span> 当系统输出字符的时候，会按指定编码输出，对于中文windows下，System.out将使用gbk编码，而对于response（浏览器），则使用jsp文件头指定的contentType，或者可以直接为response指定编码。同时，会告诉browser网页的编码。如果未指定，则会使用iso8859-1编码。对于中文，应该为browser指定输出字符串的编码。</p>
		<p class="MsoBodyTextIndent" style="MARGIN-LEFT: 43pt; TEXT-INDENT: -21pt; tab-stops: list 43.0pt">
				<span lang="EN-US" style="FONT-SIZE: 11pt; FONT-FAMILY: Wingdings">l</span> browser显示网页的时候，首先使用response中指定的编码（jsp文件头指定的contentType最终也反映在response上），如果未指定，则会使用网页中meta项指定中的contentType。</p>
		<p class="2">3.5. 几处设置</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">对于web应用程序，和编码有关的设置或者函数如下。</p>
		<p class="3">3.5.1. jsp编译</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">指定文件的存储编码，很明显，该设置应该置于文件的开头。例如：&lt;%@page pageEncoding="GBK"%&gt;。另外，对于一般class文件，可以在编译的时候指定编码。</p>
		<p class="3">3.5.2. jsp输出</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">指定文件输出到browser是使用的编码，该设置也应该置于文件的开头。例如：&lt;%@ page contentType="text/html; charset= GBK" %&gt;。该设置和response.setCharacterEncoding("GBK")等效。</p>
		<p class="3">3.5.3. meta设置</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">指定网页使用的编码，该设置对静态网页尤其有作用。因为静态网页无法采用jsp的设置，而且也无法执行response.setCharacterEncoding()。例如：&lt;<?XML:NAMESPACE PREFIX = ST1 /?><st1:place w:st="on">META http-equiv="Content-Type" content="text/html; charset=GBK" /&gt;</st1:place></p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">如果同时采用了jsp输出和meta设置两种编码指定方式，则jsp指定的优先。因为jsp指定的直接体现在response中。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">需要注意的是，apache有一个设置可以给无编码指定的网页指定编码，该指定等同于jsp的编码指定方式，所以会覆盖静态网页中的meta指定。所以有人建议关闭该设置。</p>
		<p class="3">3.5.4. form设置</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">当浏览器提交表单的时候，可以指定相应的编码。例如：&lt;form accept-charset= "gb2312"&gt;。一般不必不使用该设置，浏览器会直接使用网页的编码。</p>
		<p class="1">4. 系统软件</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">下面讨论几个相关的系统软件。</p>
		<p class="2">4.1. mysql数据库</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 22pt">很明显，要支持多语言，应该将数据库的编码设置成utf或者unicode，而utf更适合与存储。但是，如果中文数据中包含的英文字母很少，其实unicode更为适合。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 22pt">数据库的编码可以通过mysql的配置文件设置，例如default-character-set=utf8。还可以在数据库链接URL中设置，例如： useUnicode=true&amp;characterEncoding=UTF-8。注意这两者应该保持一致，在新的sql版本里，在数据库链接URL里可以不进行设置，但也不能是错误的设置。</p>
		<p class="2">4.2. apache</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">appache和编码有关的配置在httpd.conf中，例如AddDefaultCharset UTF-8。如前所述，该功能会将所有静态页面的编码设置为UTF-8，最好关闭该功能。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">另外，apache还有单独的模块来处理网页响应头，其中也可能对编码进行设置。</p>
		<p class="2">4.3. linux默认编码</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">这里所说的linux默认编码，是指运行时的环境变量。两个重要的环境变量是LC_ALL和LANG，默认编码会影响到java URLEncode的行为，下面有描述。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">建议都设置为"zh_CN.UTF-8"。</p>
		<p class="2">4.4. 其它</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">为了支持中文文件名，linux在加载磁盘时应该指定字符集，例如：mount /dev/hda5 /mnt/hda5/ -t ntfs -o iocharset=gb2312。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">另外，如前所述，使用GET方法提交的信息不支持request.setCharacterEncoding()，但可以通过tomcat的配置文件指定字符集，在tomcat的server.xml文件中，形如：&lt;Connector ... URIEncoding="GBK"/&gt;。这种方法将统一设置所有请求，而不能针对具体页面进行设置，也不一定和browser使用的编码相同，所以有时候并不是所期望的。</p>
		<p class="1">5. URL地址</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">URL地址中含有中文字符是很麻烦的，前面描述过使用GET方法提交表单的情况，使用GET方法时，参数就是包含在URL中。</p>
		<p class="2">5.1. URL编码</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">对于URL中的一些特殊字符，浏览器会自动进行编码。这些字符除了"/?&amp;"等外，还包括unicode字符，比如汉子。这时的编码比较特殊。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">IE有一个选项"总是使用UTF-8发送URL"，当该选项有效时，IE将会对特殊字符进行UTF-8编码，同时进行URL编码。如果改选项无效，则使用默认编码"GBK"，并且不进行URL编码。但是，对于URL后面的参数，则总是不进行编码，相当于UTF-8选项无效。比如"中文.html?a=中文"，当UTF-8选项有效时，将发送链接"%<u>e4%b8%ad%e6%96%87.html?a=\x4e\x2d\x65\x87</u>"；而UTF-8选项无效时，将发送链接"<u>\x4e\x2d\x65\x87.html?a=\x4e\x2d\x65\x87</u>"。注意后者前面的"中文"两个字只有4个字节，而前者却有18个字节，这主要时URL编码的原因。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 22pt">当web server（tomcat）接收到该链接时，将会进行URL解码，即去掉"%"，同时按照ISO8859-1编码（上面已经描述，可以使用URLEncoding来设置成其它编码）识别。上述例子的结果分别是"<u>\ue4\ub8\uad\ue6\u96\u87.html?a=\u4e\u2d\u65\u87</u>"和"<u>\u4e\u2d\u65\u87.html?a=\u4e\u2d\u65\u87</u>"，注意前者前面的"中文"两个字恢复成了6个字符。这里用"\u"，表示是unicode。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 22pt">所以，由于客户端设置的不同，相同的链接，在服务器上得到了不同结果。这个问题不少人都遇到，却没有很好的解决办法。所以有的网站会建议用户尝试关闭UTF-8选项。不过，下面会描述一个更好的处理办法。</p>
		<p class="2">5.2. rewrite</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">熟悉的人都知道，apache有一个功能强大的rewrite模块，这里不描述其功能。需要说明的是该模块会自动将URL解码（去除%），即完成上述web server（tomcat）的部分功能。有相关文档介绍说可以使用[NE]参数来关闭该功能，但我试验并未成功，可能是因为版本（我使用的是apache <st1:chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899">2.0.54）问题。另外，当参数中含有"?&amp; "等符号的时候，该功能将导致系统得不到正常结果。</st1:chsdate></p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">rewrite本身似乎完全是采用字节处理的方式，而不考虑字符串的编码，所以不会带来编码问题。</p>
		<p class="2">5.3. URLEncode.encode()</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">这是Java本身提供对的URL编码函数，完成的工作和上述UTF-8选项有效时浏览器所做的工作相似。值得说明的是，java已经不赞成不指定编码来使用该方法（deprecated）。应该在使用的时候增加编码指定。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">当不指定编码的时候，该方法使用系统默认编码，这会导致软件运行结果得不确定。比如对于"中文"，当系统默认编码为"gb2312"时，结果是"%<u>4e%2d%65%87</u>"，而默认编码为"UTF-8"，结果却是"%<u>e4%b8%ad%e6%96%87</u>"，后续程序将难以处理。另外，这儿说的系统默认编码是由运行tomcat时的环境变量LC_ALL和LANG等决定的，曾经出现过tomcat重启后就出现乱码的问题，最后才郁闷的发现是因为修改修改了这两个环境变量。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">建议统一指定为"UTF-8"编码，可能需要修改相应的程序。</p>
		<p class="2">5.4. 一个解决方案</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">上面说起过，因为浏览器设置的不同，对于同一个链接，web server收到的是不同内容，而软件系统有无法知道这中间的区别，所以这一协议目前还存在缺陷。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">针对具体问题，不应该侥幸认为所有客户的IE设置都是UTF-8有效的，也不应该粗暴的建议用户修改IE设置，要知道，用户不可能去记住每一个web server的设置。所以，接下来的解决办法就只能是让自己的程序多一点智能：根据内容来分析编码是否UTF-8。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">比较幸运的是UTF-8编码相当有规律，所以可以通过分析传输过来的链接内容，来判断是否是正确的UTF-8字符，如果是，则以UTF-8处理之，如果不是，则使用客户默认编码（比如"GBK"），下面是一个判断是否UTF-8的例子，如果你了解相应规律，就容易理解。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">public static boolean isValidUtf8(byte[] b,int aMaxCount){</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">       int lLen=b.length,lCharCount=0;</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">       for(int i=0;i&lt;lLen &amp;&amp; lCharCount&lt;aMaxCount;++lCharCount){</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">              byte lByte=b[i++];//to fast operation, ++ now, ready for the following for(;;)</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">              if(lByte&gt;=0) continue;//&gt;=0 is normal ascii</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">              if(lByte&lt;(byte)0xc0 || lByte&gt;(byte)0xfd) return false;</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">              int lCount=lByte&gt;(byte)0xfc?5:lByte&gt;(byte)0xf8?4</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">                     :lByte&gt;(byte)0xf0?3:lByte&gt;(byte)0xe0?2:1;</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">              if(i+lCount&gt;lLen) return false;</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">              for(int j=0;j&lt;lCount;++j,++i) if(b[i]&gt;=(byte)0xc0) return false;</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">       }</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">       return true;</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">}</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">相应地，一个使用上述方法的例子如下：</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">public static String getUrlParam(String aStr,String aDefaultCharset)</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">throws UnsupportedEncodingException{</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">       if(aStr==null) return null;</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">       byte[] lBytes=aStr.getBytes("ISO-8859-1");</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">       return new String(lBytes,StringUtil.isValidUtf8(lBytes)?"utf8":aDefaultCharset);</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">}</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">不过，该方法也存在缺陷，如下两方面：</p>
		<p class="MsoBodyTextIndent" style="MARGIN-LEFT: 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt">
				<span lang="EN-US" style="FONT-FAMILY: Wingdings">l</span> 没有包括对用户默认编码的识别，这可以根据请求信息的语言来判断，但不一定正确，因为我们有时候也会输入一些韩文，或者其他文字。</p>
		<p class="MsoBodyTextIndent" style="MARGIN-LEFT: 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt">
				<span lang="EN-US" style="FONT-FAMILY: Wingdings">l</span> 可能会错误判断UTF-8字符，一个例子是"学习"两个字，其GBK编码是" <u>\xd1\xa7\xcf\xb0</u>"，如果使用上述isValidUtf8方法判断，将返回true。可以考虑使用更严格的判断方法，不过估计效果不大。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">有一个例子可以证明google也遇到了上述问题，而且也采用了和上述相似的处理方法，比如，如果在地址栏中输入"<a href="http://www.google.com/search?hl=zh-CN&amp;newwindow=1&amp;q=学习">http://www.google.com/search?hl=zh-CN&amp;newwindow=1&amp;q=学习</a>"，google将无法正确识别，而其他汉字一般能够正常识别。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">最后，应该补充说明一下，如果不使用rewrite规则，或者通过表单提交数据，其实并不一定会遇到上述问题，因为这时可以在提交数据时指定希望的编码。另外，中文文件名确实会带来问题，应该谨慎使用。</p>
		<p class="1">6. 其它</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">下面描述一些和编码有关的其他问题。</p>
		<p class="2">6.1. SecureCRT</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">除了浏览器和控制台与编码有关外，一些客户端也很有关系。比如在使用SecureCRT连接linux时，应该让SecureCRT的显示编码（不同的session，可以有不同的编码设置）和linux的编码环境变量保持一致。否则看到的一些帮助信息，就可能是乱码。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">另外，mysql有自己的编码设置，也应该保持和SecureCRT的显示编码一致。否则通过SecureCRT执行sql语句的时候，可能无法处理中文字符，查询结果也会出现乱码。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">对于Utf-8文件，很多编辑器（比如记事本）会在文件开头增加三个不可见的标志字节，如果作为mysql的输入文件，则必须要去掉这三个字符。（用linux的vi保存可以去掉这三个字符）。一个有趣的现象是，在中文windows下，创建一个新txt文件，用记事本打开，输入"连通"两个字，保存，再打开，你会发现两个字没了，只留下一个小黑点。</p>
		<p class="2">6.2. 过滤器</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">如果需要统一设置编码，则通过filter进行设置是个不错的选择。在filter class中，可以统一为需要的请求或者回应设置编码。参加上述setCharacterEncoding()。这个类apache已经给出了可以直接使用的例子SetCharacterEncodingFilter。</p>
		<p class="2">6.3. POST和GET</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">很明显，以POST提交信息时，URL有更好的可读性，而且可以方便的使用setCharacterEncoding()来处理字符集问题。但GET方法形成的URL能够更容易表达网页的实际内容，也能够用于收藏。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">从统一的角度考虑问题，建议采用GET方法，这要求在程序中获得参数是进行特殊处理，而无法使用setCharacterEncoding()的便利，如果不考虑rewrite，就不存在IE的UTF-8问题，可以考虑通过设置URIEncoding来方便获取URL中的参数。</p>
		<p class="2">6.4. 简繁体编码转换</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">GBK同时包含简体和繁体编码，也就是说同一个字，由于编码不同，在GBK编码下属于两个字。有时候，为了正确取得完整的结果，应该将繁体和简体进行统一。可以考虑将UTF、GBK中的所有繁体字，转换为相应的简体字，BIG5编码的数据，也应该转化成相应的简体字。当然，仍旧以UTF编码存储。</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt">例如，对于"语言 語言"，用UTF表示为"<u>\x</u><u>E8\xAF\xAD\xE8\xA8\x80 \xE8\xAA\x9E\xE8\xA8\x80</u>"，进行简繁体编码转换后应该是两个相同的 "<u>\x</u><u>E8\xAF\xAD\xE8\xA8\x80&gt;</u>"。</p>
		<p class="MsoBodyTextIndent"> </p>
		<p class="MsoBodyTextIndent" style="WORD-BREAK: break-all; TEXT-INDENT: 21pt; TEXT-ALIGN: right" align="right">
				<a href="http://china.eceel.com/">Eceel东西在线</a> 刘科垠</p>
		<p class="MsoBodyTextIndent" style="TEXT-INDENT: 21pt; TEXT-ALIGN: right" align="right">2006-3-8</p>
<img src ="http://www.blogjava.net/SIDNEY/aggbug/52113.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-06-12 09:36 <a href="http://www.blogjava.net/SIDNEY/archive/2006/06/12/52113.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于struts+spring+ibatis的轻量级J2EE开发     </title><link>http://www.blogjava.net/SIDNEY/archive/2006/04/21/42314.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Fri, 21 Apr 2006 06:47:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/04/21/42314.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/42314.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/04/21/42314.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/42314.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/42314.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 多数				IT 						组织都必须解决三个主要问题：				1						．帮助组织减少成本				 2						．增加并且保持客户								3								．加快业务效率。完成这些问题一般都需要实现对多个业务系统的数据和业务逻辑的无缝访问，也就是说，要实施系统集成工程，以便联结业务流程、实现数据的访问与共享。...&nbsp;&nbsp;<a href='http://www.blogjava.net/SIDNEY/archive/2006/04/21/42314.html'>阅读全文</a><img src ="http://www.blogjava.net/SIDNEY/aggbug/42314.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-04-21 14:47 <a href="http://www.blogjava.net/SIDNEY/archive/2006/04/21/42314.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用JSP技术和Chart组件实现基于WEB的统计图表</title><link>http://www.blogjava.net/SIDNEY/archive/2006/04/04/39071.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Tue, 04 Apr 2006 01:07:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/04/04/39071.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/39071.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/04/04/39071.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/39071.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/39071.html</trackback:ping><description><![CDATA[
		<table class="showinfo" style="TABLE-LAYOUT: fixed; WORD-BREAK: break-all" cellspacing="0" cellpadding="3" width="100%" align="center" border="0">
				<tbody>
						<tr>
								<td class="showTitle" align="middle">
								</td>
						</tr>
						<tr>
								<td>
										<table cellspacing="0" cellpadding="0" align="left" border="0">
												<tbody>
														<tr>
																<td>
																		<script language="javascript" src="/ad/js/edu_left_300-300.js">
																		</script>
																</td>
														</tr>
												</tbody>
										</table>JSP（Java Server Pages）[1]是由Sun微系统公司于1999年6月推出的一项新技术，是基于JavaServlet以及整个java体系的Web开发技术，利用这一技术可以建立先进、安全和跨平台的动态网站。JSP 与Microsoft的ASP（Active Server Pages）技术非常相似。两者都提供在HTML 代码中混合某种程序代码、由语言引擎解释执行程序代码的能力。在ASP或JSP 环境下，HTML代码主要负责描述信息的显示样式，而程序代码则用来描述处理逻辑。ASP下的编程语言是 vb script 之类的脚本语言，而JSP 使用的是Java。 <br /><br />Microsoft? Office Web 组件[2]首次包含在 Microsoft? Office 2000 中。它们是用于向 Web 页添加电子表格、图表和数据处理功能的 ActiveX? 控件的集合。在使用 Microsoft? Internet Explorer 浏览包含 Office Web 组件的 Web 页时，您可以直接在 Internet Explorer 中处理显示的数据，如对数据进行排序和筛选，输入新的数值，展开和折叠明细数据，进行行列旋转以查看源数据的不同汇总信息等。Microsoft? Office Web 控件能够提供所有这些功能，共有三种 Office Web 组件：Spreadsheet 组件、Chart 组件和 PivotTable? 组件。本文将使用其中的Chart 组件。 <br /><br />1、JSP技术与Chart组件 <br /><br />JSP技术是一种在服务器端编译执行的Web设计语言，其脚本语言采用Java，完全继承了Java的所有优点。它能将网页的动态部分与静态部分有效分开，你只要用任何一种你熟悉的网页制作工具，编写规则的HTML，然后通过JSP标记（tag）[3]将动态部分包含进来就可以了,tag绝大部分是以"&lt;%"开始，以"%&gt;"结束的。 <br /><br />Chart组件是 Microsoft Office 使用的数据绑定 ActiveX 控件，用于向 Web 页添加图表功能。我们在安装微软的Office 2000时会缺省安装一个组件Office Web Components，Chart组件就含在这个组件中，对应的文件是msowc.dll。 <br /><br />2、实现实例 <br /><br />本文的运行环境是：Jbuilder7＋Oracle8i，同时运用了JAVABEAN技术来实现与Oracle数据库的连接[4]。 <br /><br />下面的程序graph.jsp实现了从数据库中读出一段时间内内燃机车和电力机车的数值，然后用统计图表显示，用户可以选择图形方式。(以下斜体部分为JSP代码) <br /><br />&lt;%@page contentType="text/html;charset=gb2312" %&gt; <br /><br />&lt;%@ page import="java.sql.*,java.io.*,java.util.*,java.util.Date"%&gt; <br /><br />&lt;jsp:useBean id="zzjwbean" scope="page" class="jsp.zzjw"/&gt; <br /><br />&lt;!-- 用JAVABEAN实现与数据库连接（本段代码略） --&gt; <br /><br />&lt;% <br /><br />/*变量定义略*/ <br /><br />/*获得查询的年,月,起始日期,即: year,month,f_gk_startdate和截至日期f_gk_enddate，本段代码略*/ <br /><br />%&gt; <br /><br />&lt;html&gt; <br /><br />&lt;head&gt; <br /><br />&lt;title&gt; <br /><br />&lt;/title&gt; <br /><br />&lt;form name=fm action="" method="post"&gt; <br /><br />&lt;/form&gt; <br /><br />&lt;body bgcolor="#DAFAFC"&gt; <br /><br />&lt;script language="vb script"&gt; <br /><br />sub window_onload() <br /><br />Dim categories(34) ''将横坐标的值赋给vb script环境下的数组categories <br /><br />Dim values(34) ''将纵坐标的值赋给vb script环境下的数组values <br /><br />&lt;% <br /><br />i = 0; <br /><br />rs = zzjwbean.executeQuery("select * from T_zzj_dw"); /*获得单位名称*/ <br /><br />while(rs.next()) <br /><br />{ <br /><br />%&gt; <br /><br />categories(&lt;%=i%&gt;)=&lt;%="\""+rs.getString("f_fjmc")+"\""%&gt; <br /><br />&lt;% <br /><br />i++; <br /><br />} <br /><br />%&gt; <br /><br />ChartSpace1.Charts.Add‘将图表添加到图表工作区中 <br /><br />''将变量c设置为 Constants 属性所返回的对象, 因为在 vb script 中不能使用已命名的常量 <br /><br />Set c = ChartSpace1.Constants <br /><br />ChartSpace1.Charts(0).hastitle=true ''图表有标题 <br /><br />ChartSpace1.Charts(0).Title.Font.Name = "仿宋_GB231280" ''标题字体 <br /><br />ChartSpace1.Charts(0).Title.Font.size=11 ''标题字体大小 <br /><br />ChartSpace1.Charts(0).Title.Font.color="blue" ''标题字体颜色 <br /><br />ChartSpace1.Charts(0).Title.caption="&lt;%=year%&gt;年&lt;%=month%&gt;月机车概况月报表统计图" ''标题内容 <br /><br />ChartSpace1.Charts(0).HasLegend = True ''指定图表具有图例 <br /><br />''指定图表的图形方式为列状图 <br /><br />ChartSpace1.Charts(0).type=c.chChartTypeColumnClustered <br /><br />''给图表赋横坐标的值 <br /><br />ChartSpace1.Charts(0).SetData c.chDimCategories, c.chDataLiteral,categories <br /><br />''系列0对应内燃机车统计数值 <br /><br />ChartSpace1.Charts(0).SeriesCollection(0).Caption="内燃机车统计" ''系列0的图例 <br /><br />''将内燃机车统计的值赋给vb script环境下的数组values <br /><br />&lt;% <br /><br />i = 0; <br /><br />rs1 = null; <br /><br />f_fjbm = ""; <br /><br />rs = zzjwbean.executeQuery("select * from T_zzj_dw"); <br /><br />while(rs.next()) <br /><br />{ <br /><br />f_fjbm = rs.getString("f_fjbm"); <br /><br />rs1 = zzjwbean.executeQuery("select sum(f_jc_nrhj) from T_jccwygk where f_jccwy_fj=''"+f_fjbm+"'' and f_date&gt;=''"+f_gk_startdate+"'' and f_date&lt;=''"+f_gk_enddate+"''");/*统计数据*/ <br /><br />if(rs1.next()) <br /><br />{ <br /><br />%&gt; <br /><br />values(&lt;%=i%&gt;)=&lt;%=rs1.getInt(1)%&gt; <br /><br />&lt;% <br /><br />i++; <br /><br />} <br /><br />} <br /><br />%&gt; <br /><br />''将内燃机车统计的值赋给图表的系列0 <br /><br />ChartSpace1.Charts(0).SeriesCollection(0).SetData c.chDimValues, c.chDataLiteral, values <br /><br />ChartSpace1.Charts(0).SeriesCollection.Add ''向图表中添加系列1 <br /><br />ChartSpace1.Charts(0).SeriesCollection(1).Caption="电力机车统计" ''系列1的图例 <br /><br />''将电力机车统计的值赋给vb script环境下的数组values <br /><br />&lt;% <br /><br />i = 0; <br /><br />rs1 = null; <br /><br />f_fjbm = ""; <br /><br />rs = zzjwbean.executeQuery("select * from T_zzj_dw"); <br /><br />while(rs.next()) <br /><br />{ <br /><br />f_fjbm = rs.getString("f_fjbm"); <br /><br />rs1 = zzjwbean.executeQuery("select sum(f_jc_dlhj) from T_jccwygk where f_jccwy_fj=''"+f_fjbm+"'' and f_date&gt;=''"+f_gk_startdate+"'' and f_date&lt;=''"+f_gk_enddate+"''"); <br /><br />if(rs1.next()) <br /><br />{ <br /><br />%&gt; <br /><br />values(&lt;%=i%&gt;)=&lt;%=rs1.getInt(1)%&gt; <br /><br />&lt;% <br /><br />i++; <br /><br />} <br /><br />} <br /><br />%&gt; <br /><br />''将电力机车统计的值赋给图表的系列1 <br /><br />ChartSpace1.Charts(0).SeriesCollection(1).SetData c.chDimValues, c.chDataLiteral, values <br /><br />''指定纵坐标轴有标题，并赋值，然后指定数据的显示格式 <br /><br />ChartSpace1.Charts(0).axes(c.chAxisPositionLeft).hastitle=true <br /><br />ChartSpace1.Charts(0).axes(c.chAxisPositionLeft).title.Font.Name = "黑体" <br /><br />ChartSpace1.Charts(0).axes(c.chAxisPositionLeft).title.Font.size = 11 <br /><br />ChartSpace1.Charts(0).axes(c.chAxisPositionLeft).title.caption="机车合计(台数)" <br /><br />ChartSpace1.Charts(0).Axes(c.chAxisPositionLeft).NumberFormat = "0.##" <br /><br />''指定横坐标轴有标题，并赋值 <br /><br />ChartSpace1.Charts(0).axes(c.chAxisPositionBottom).hastitle=true <br /><br />ChartSpace1.Charts(0).axes(c.chAxisPositionBottom).title.Font.Name = "黑体" <br /><br />ChartSpace1.Charts(0).axes(c.chAxisPositionBottom).title.Font.size = 12 <br /><br />ChartSpace1.Charts(0).axes(c.chAxisPositionBottom).title.caption="郑州局机车概况月报表" <br /><br />end sub <br /><br />''根据用户选择的图形方式，改变图表的形状 <br /><br />sub dd_onchange() <br /><br />ChartSpace1.Charts(0).type=dd(dd.selectedIndex).value <br /><br />end sub <br /><br />&lt;/script&gt; <br /><br />&lt;/head&gt; <br /><br />&lt;body&gt; <br /><br />&lt;select name="dd" size="1"&gt; <br /><br />&lt;option value="0" selected&gt;列状图&lt;/option&gt; <br /><br />&lt;option value="3"&gt;栏状图&lt;/option&gt; <br /><br />&lt;option value="6"&gt;平滑曲线图&lt;/option&gt; <br /><br />&lt;option value="18"&gt;饼行图&lt;/option&gt; <br /><br />&lt;option value="29"&gt;面积图&lt;/option&gt; <br /><br />&lt;/select&gt; <br /><br />&lt;!-- 创建一个图表工作区对象, 名为“ChartSpace1” --&gt; <br /><br />&lt;p&gt; <br /><br />&lt;object id=ChartSpace1 classid=CLSID:0002E500-0000-0000-C000-000000000046 codebase="msowc.dll" style="width:100%;height:350"&gt; <br /><br />&lt;/object&gt; <br /><br />&lt;/p&gt; <br /><br />&lt;/body&gt; <br /><br />&lt;/html&gt; <br /></td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/SIDNEY/aggbug/39071.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-04-04 09:07 <a href="http://www.blogjava.net/SIDNEY/archive/2006/04/04/39071.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate特点与思考     选择自 baggio785 的 Blog </title><link>http://www.blogjava.net/SIDNEY/archive/2006/03/25/37320.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Sat, 25 Mar 2006 03:26:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/03/25/37320.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/37320.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/03/25/37320.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/37320.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/37320.html</trackback:ping><description><![CDATA[
		<span id="ArticleContent1_ArticleContent1_lblContent"> 
<p>转载：转载请保留本信息，本文来自<a href="http://www.matrix.org.cn/resource/news/381_Hibernate.html"><font color="#002c99">http://www.matrix.org.cn/resource/news/381_Hibernate.html</font></a></p><p><a href="http://blog.matrix.org.cn/page/magicgod" target="_new"><font color="#002c99">magicgod</font></a> 昨天在他的blog上发布了一篇关于<a href="http://blog.matrix.org.cn/page/magicgod?entry=%E9%92%88%E5%AF%B9hibernate_jdbc_sql%E7%9A%84%E6%80%9D%E8%80%83" target="_new"><font color="#002c99">Hibernate的特点思考</font></a>的文章。</p><p>原文：<br /><br />想了很长时间hibernate的一些弱点<br />1.对象与数据库的映射，关键在于对象关系的映射，但是没做到很理想，配置过多，控制复杂，另外还会出错。其实本质在于对象不够自由。<br /><br />2.事务处理。这点上更容易出问题，相对于各种各样的事务管理器，要兼容是一个大问题，总归在各种应用服务器上有很多问题。其本质在于创建了一个自我数据存取小环境，必然面临各种兼容问题。<br /><br />3.HQL语言。建立对象查询语言，类SQL，但是不同于任何一种SQL，调试环境复杂。本质在于创建了一种语言，增加学习成本。<br /><br />减化hibernate，将其退化成一个sql生成器，既可以保留原有的主要功能，又可以兼容各种应用服务器和数据库服务器，另外还不需要学习HQL语言。<br /><br />只需要一系列的功能函数，作一下包装，再根据不同数据库生成不同的SQL即可，连数据库类型都不用指定，因为从Connection中可以获得数据库类型属性。<br /><br />假想中的API：<br /><br />public Object ResultMapObject(ResultSet rs,String xml)　//一行映射单个对象，可以用XML绑定，也可以不用。<br /><br />public List SQLMapObjects(Connection conn,String []sqls,String xml)  //将一堆SQL映射成一个对象树，可以用xml来描述绑定，也可以不用，仅使用ror方式的约定。<br /><br />借助JDBC和SQL可以构建整个数据存取层。<br /><br />映射单个对象的代码，将一行记录映射成单个对象。sql可以是任意的。<br /><br /></p><pre class="overflow" title="pre code"><br />    Connection conn=DriverManager.getConnection(url);<br />    PreparedStatement ps = conn.prepareStatement(sql);<br />    <br />    ResultSet rs = ps.executeQuery();<br />    while(rs.next())<br />    {<br />      user=(Users)ResultMapObject(rs);<br />      //TODO 可以使用user<br />    }<br /></pre><p><br /><br />映射对象树。<br /><br /></p><pre class="overflow" title="pre code"><br />    /*<br />    sale_orders销售订单表<br />    sale_order_details销售订单细表<br />    products商品表<br />    product_catalogs商品类别表<br />    从sql中就可以分析出<br />    id是主鍵<br />    sale_order_details.sale_order_id===&gt;sale_orders.id<br />    sale_order_details.product_catalog_id==&gt;product_catalogs.id<br />    sale_order_details.product_id==&gt;products.id<br />     */<br />    String []sqls=new String []{<br />        " select id, total_sum, memo, state, modify_date, creator, checker from sale_orders ",<br />        " select id, sale_order_id, product_id, product_name, product_catalog_id, model, product_unit, product_amount, product_price, product_sum, memo from sale_order_details ",<br />        " select id, name, catalog, model, price, unit, memo, createtime, state, code, productno from products ",<br />        " select id, name, memo from product_catalogs"<br />    };<br />    //不帶XML映射的，但是無法得知一对一还是一对多还是多对多的关系，所以一律建成多对多关系。<br />    List l=SQLMapObjects(conn,sqls);<br />    /*<br />    l的结构：<br />    sale_orders[]<br />        |-----sale_order_details[](sale_order_details.sale_order_id===&gt;sale_orders.id)<br />                |-----products[](sale_order_details.product_id==&gt;products.id)<br />                |-----product_catalogs[](sale_order_details.product_catalog_id==&gt;product_catalogs.id)                <br />     */<br /></pre><p><br /><br />    /*<br />     带xml<br />     */<br /><br /></p><pre class="overflow" title="pre code"><br />    /*<br />    sale_orders销售订单表<br />    sale_order_details销售订单细表<br />    products商品表<br />    product_catalogs商品类别表<br />    从sql中就可以分析出<br />    id是主鍵<br />    sale_order_details.sale_order_id===&gt;sale_orders.id<br />    sale_order_details.product_catalog_id==&gt;product_catalogs.id<br />    sale_order_details.product_id==&gt;products.id<br />     */<br />    String []sqls=new String []{<br />        " select id, total_sum, memo, state, modify_date, creator, checker from sale_orders ",<br />        " select id, sale_order_id, product_id, product_name, product_catalog_id, model, product_unit, product_amount, product_price, product_sum, memo from sale_order_details ",<br />        " select id, name, catalog, model, price, unit, memo, createtime, state, code, productno from products ",<br />        " select id, name, memo from product_catalogs"<br />    };<br /><br />    /*<br />&lt;?xml version="1.0"?&gt;<br />&lt;MapObject&gt;<br />&lt;!--类似hibernate的映射，但是更容易理解，而且可以省略字段映射--&gt;<br />    &lt;Object tablename="sale_orders" class="org.test.pojo.SaleOrder"&gt;<br />        &lt;OneToMany tablename="sale_order_details" class="org.test.pojo.SaleOrderDetail"&gt;<br />        &lt;!--主细表映射--&gt;<br />            &lt;ParentKey&gt;id&lt;/ParentKey&gt;<br />            &lt;ChildKey&gt;id&lt;/ChildKey&gt;<br />        &lt;/OneToMany&gt;<br />        &lt;!--字段映射可选，一般是相同或根据ROR规则--&gt;<br />        &lt;FieldMap&gt;可选...&lt;/FieldMap&gt;<br />    &lt;/Object&gt;<br />    &lt;Object tablename="sale_order_details" class="org.test.pojo.SaleOrderDetail"&gt;<br />        &lt;!-- 附加代码表映射１对１关系 --&gt;<br />        &lt;OneToOne tablename="products" class="org.test.pojo.Product"&gt;<br />            &lt;ParentKey tablename="sale_order_details"&gt;product_id&lt;/ParentKey&gt;<br />            &lt;ChildKey tablename="products"&gt;id&lt;/ChildKey&gt;<br />        &lt;/OneToMany&gt;<br />        &lt;FieldMap&gt;可选...&lt;/FieldMap&gt;<br />    &lt;/Object&gt;<br />    &lt;Object tablename="sale_order_details" class="org.test.pojo.SaleOrderDetail"&gt;<br />        &lt;OneToOne tablename="product_catalogs" class="org.test.pojo.ProductCatalog"&gt;<br />            &lt;ParentKey tablename="sale_order_details"&gt;product_catalog_id&lt;/ParentKey&gt;<br />            &lt;ChildKey tablename="product_catalogs"&gt;id&lt;/ChildKey&gt;<br />        &lt;/OneToMany&gt;<br />        &lt;FieldMap&gt;可选...&lt;/FieldMap&gt;<br />    &lt;/Object&gt;<br />    &lt;Object tablename="product_catalogs" class="org.test.pojo.ProductCatalog"&gt;<br />        &lt;FieldMap&gt;可选...&lt;/FieldMap&gt;<br />    &lt;/Object&gt;<br />&lt;/MapObject&gt;<br />     */<br /><br />    String xml="...";<br />    //带xml映射<br />    List l=SQLMapObjects(conn,sqls,xml);<br />    /*<br />    l的结构：<br />    sale_orders[]<br />        |-----sale_order_details[](sale_order_details.sale_order_id===&gt;sale_orders.id)<br />                |-----products[](sale_order_details.product_id==&gt;products.id)<br />                |-----product_catalogs[](sale_order_details.product_catalog_id==&gt;product_catalogs.id)                <br />     */<br /></pre><p><br /><br />当然类要事先写好，这里就不详细写了。<br /><br />保存问题更严重，取出来用sql映射已经可以很好地解决了，基本上一个函数、一群SQL，加上少少的XML就可以表达清楚了，但是这不能解决保存对象的问题。<br /><br />假想中的保存API。<br /><br />public void saveObject(Connection conn, Object obj,String xml);  //保存单个对象，简单地将对象扩展成sql，允许xml映射，也可以不映射<br /><br />public void saveObjects(Connection conn, List objs, String xml);  //将对象树保存到数据库<br /><br />上一篇取出的List或人工组合的List可以用saveObjects来保存，这个函数的任务就比较重了，因为没有状态，所以要判断修改过非常麻烦。<br /><br />一种思路是在对象是增加属性，然后由开发者维护，比如界面上是否修改很有可能是有状态位的，这个状态位就可以用起来，然后函数根据这个状态位来判断是否去更新。<br /><br />一种思路是从Class本身中就得知对象是否被改过，类似AOP，在修改的时候记录一下，然后函数来判断是否改过，然后组成SQL来更新。<br /><br />至于批量修改是强项，直接用SQL即可，学习SQL比HQL的成本要低，毕竟这么多年了。<br /><br />外围实用函数的思考：基本上都针对SQL的生成，或数据库函数的替换<br /><br />public String generateInsertSQL(DBType type,Object obj);//生成insert语句<br /><br />public String generateUpdateSQL(DBType type,Object obj);//生成update语句<br /><br />public String generateSelectSQL(DBType type,Object obj);//生成select语句<br /><br />总之这个函数工具箱的思路有这几条：<br /><br />1.使用函数，而不是使用环境来代替JDBC或应用服务器。<br /><br />2.使用成熟的SQL，而不是自创语言，最多增加SQL预处理器，将一些函数转成数据库相关，简单的文本功能。<br /><br />3.保持对各种环境的兼容性。对象是干净的，当然如果用AOP就很难说对象干不干净了，不过基本上应该适用于所有的环境中。<br /><br />缺点：由于没有了环境，保存对象有点麻烦，用SQL来解决批量更新和删除，必要时增加几个SQL语句生成器即可。保存对象树是一个大缺点，没有非常好的办法能够将对象树整个保存下来而且效率非常高，只有上面提到的两种不太完美的办法，这都是因为JVM没有提供对象状态的原因。<br /><br />不过这样用函数的方法来解决多继承的问题还是比较干净舒服的，既可以动态，又可以静态，随心所欲，灵活性、效率和兼容性兼得。<br /><br />关注：<br /><a href="http://blog.matrix.org.cn/page/magicgod" target="_new"><font color="#002c99">magicgod的Blog</font></a><br /><a href="http://www.matrix.org.cn/topic.shtml?forumId=23" target="_new"><font color="#002c99">Hibernate论坛</font></a><br /><br />对此，你有何看法？</p></span>
<img src ="http://www.blogjava.net/SIDNEY/aggbug/37320.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-03-25 11:26 <a href="http://www.blogjava.net/SIDNEY/archive/2006/03/25/37320.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一篇不错的讲解Java异常的文章     选择自 whoopee 的 Blog </title><link>http://www.blogjava.net/SIDNEY/archive/2006/03/25/37318.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Sat, 25 Mar 2006 03:23:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/03/25/37318.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/37318.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/03/25/37318.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/37318.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/37318.html</trackback:ping><description><![CDATA[
		<span id="ArticleContent1_ArticleContent1_lblContent"> 
<p><font size="2">六种异常处理的陋习</font></p><p><font size="2">你觉得自己是一个Java专家吗？是否肯定自己已经全面掌握了Java的异常处理机制？在下面这段代码中，你能够迅速找出异常处理的六个问题吗？ <br /><br /></font></p><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td><font size="2">1 OutputStreamWriter out = ... <br />2 java.sql.Connection conn = ... <br />3 try { // ⑸ <br />4 　Statement stat = conn.createStatement(); <br />5 　ResultSet rs = stat.executeQuery( <br />6 　　"select uid, name from user"); <br />7 　while (rs.next()) <br />8 　{ <br />9 　　out.println("ID：" + rs.getString("uid") // ⑹ <br />10 　　　"，姓名：" + rs.getString("name")); <br />11 　} <br />12 　conn.close(); // ⑶ <br />13 　out.close(); <br />14 } <br />15 catch(Exception ex) // ⑵ <br />16 { <br />17 　ex.printStackTrace(); //⑴，⑷ <br />18 }</font></td></tr></tbody></table><p><br /><font size="2">　　作为一个Java程序员，你至少应该能够找出两个问题。但是，如果你不能找出全部六个问题，请继续阅读本文。 <br /><br />　　本文讨论的不是Java异常处理的一般性原则，因为这些原则已经被大多数人熟知。我们要做的是分析各种可称为“反例”（anti-pattern）的违背优秀编码规范的常见坏习惯，帮助读者熟悉这些典型的反面例子，从而能够在实际工作中敏锐地察觉和避免这些问题。 <br /><br />　　<b>反例之一：丢弃异常 </b><br /><br />　　代码：15行-18行。 <br /><br />　　这段代码捕获了异常却不作任何处理，可以算得上Java编程中的杀手。从问题出现的频繁程度和祸害程度来看，它也许可以和C/C++程序的一个恶名远播的问题相提并论??不检查缓冲区是否已满。如果你看到了这种丢弃（而不是抛出）异常的情况，可以百分之九十九地肯定代码存在问题（在极少数情况下，这段代码有存在的理由，但最好加上完整的注释，以免引起别人误解）。 <br /><br />　　这段代码的错误在于，异常（几乎）总是意味着某些事情不对劲了，或者说至少发生了某些不寻常的事情，我们不应该对程序发出的求救信号保持沉默和无动于衷。调用一下printStackTrace算不上“处理异常”。不错，调用printStackTrace对调试程序有帮助，但程序调试阶段结束之后，printStackTrace就不应再在异常处理模块中担负主要责任了。 <br /><br />　　丢弃异常的情形非常普遍。打开JDK的ThreadDeath类的文档，可以看到下面这段说明：“特别地，虽然出现ThreadDeath是一种‘正常的情形’，但ThreadDeath类是Error而不是Exception的子类，因为许多应用会捕获所有的Exception然后丢弃它不再理睬。”这段话的意思是，虽然ThreadDeath代表的是一种普通的问题，但鉴于许多应用会试图捕获所有异常然后不予以适当的处理，所以JDK把ThreadDeath定义成了Error的子类，因为Error类代表的是一般的应用不应该去捕获的严重问题。可见，丢弃异常这一坏习惯是如此常见，它甚至已经影响到了Java本身的设计。 <br /><br />　　那么，应该怎样改正呢？主要有四个选择： <br /><br />　　1、处理异常。针对该异常采取一些行动，例如修正问题、提醒某个人或进行其他一些处理，要根据具体的情形确定应该采取的动作。再次说明，调用printStackTrace算不上已经“处理好了异常”。 <br /><br />　　2、重新抛出异常。处理异常的代码在分析异常之后，认为自己不能处理它，重新抛出异常也不失为一种选择。 <br /><br />　　3、把该异常转换成另一种异常。大多数情况下，这是指把一个低级的异常转换成应用级的异常（其含义更容易被用户了解的异常）。 <br /><br />　　4、不要捕获异常。 <br /><br />　　结论一：既然捕获了异常，就要对它进行适当的处理。不要捕获异常之后又把它丢弃，不予理睬。 <br /><br />　　<b>反例之二：不指定具体的异常 </b><br /><br />　　代码：15行。 <br /><br />　　许多时候人们会被这样一种“美妙的”想法吸引：用一个catch语句捕获所有的异常。最常见的情形就是使用catch(Exception ex)语句。但实际上，在绝大多数情况下，这种做法不值得提倡。为什么呢？ <br /><br />　　要理解其原因，我们必须回顾一下catch语句的用途。catch语句表示我们预期会出现某种异常，而且希望能够处理该异常。异常类的作用就是告诉Java编译器我们想要处理的是哪一种异常。由于绝大多数异常都直接或间接从java.lang.Exception派生，catch(Exception ex)就相当于说我们想要处理几乎所有的异常。 <br /><br />　　再来看看前面的代码例子。我们真正想要捕获的异常是什么呢？最明显的一个是SQLException，这是JDBC操作中常见的异常。另一个可能的异常是IOException，因为它要操作OutputStreamWriter。显然，在同一个catch块中处理这两种截然不同的异常是不合适的。如果用两个catch块分别捕获SQLException和IOException就要好多了。这就是说，catch语句应当尽量指定具体的异常类型，而不应该指定涵盖范围太广的Exception类。 <br /><br />　　另一方面，除了这两个特定的异常，还有其他许多异常也可能出现。例如，如果由于某种原因，executeQuery返回了null，该怎么办？答案是让它们继续抛出，即不必捕获也不必处理。实际上，我们不能也不应该去捕获可能出现的所有异常，程序的其他地方还有捕获异常的机会??直至最后由JVM处理。 <br /><br />　　结论二：在catch语句中尽可能指定具体的异常类型，必要时使用多个catch。不要试图处理所有可能出现的异常。 <br /><br />　　<b>反例之三：占用资源不释放 </b><br /><br />　　代码：3行-14行。 <br /><br />　　异常改变了程序正常的执行流程。这个道理虽然简单，却常常被人们忽视。如果程序用到了文件、Socket、JDBC连接之类的资源，即使遇到了异常，也要正确释放占用的资源。为此，Java提供了一个简化这类操作的关键词finally。 <br /><br />　　finally是样好东西：不管是否出现了异常，Finally保证在try/catch/finally块结束之前，执行清理任务的代码总是有机会执行。遗憾的是有些人却不习惯使用finally。 <br /><br />　　当然，编写finally块应当多加小心，特别是要注意在finally块之内抛出的异常??这是执行清理任务的最后机会，尽量不要再有难以处理的错误。 <br /><br />　　结论三：保证所有资源都被正确释放。充分运用finally关键词。</font></p><p><font size="2"><strong>反例之四：不说明异常的详细信息 <br /><br /></strong>　　代码：3行-18行。 <br /><br />　　仔细观察这段代码：如果循环内部出现了异常，会发生什么事情？我们可以得到足够的信息判断循环内部出错的原因吗？不能。我们只能知道当前正在处理的类发生了某种错误，但却不能获得任何信息判断导致当前错误的原因。 <br /><br />　　printStackTrace的堆栈跟踪功能显示出程序运行到当前类的执行流程，但只提供了一些最基本的信息，未能说明实际导致错误的原因，同时也不易解读。 <br /><br />　　因此，在出现异常时，最好能够提供一些文字信息，例如当前正在执行的类、方法和其他状态信息，包括以一种更适合阅读的方式整理和组织printStackTrace提供的信息。 <br /><br />　　结论四：在异常处理模块中提供适量的错误原因信息，组织错误信息使其易于理解和阅读。 <br /><br />　　<b>反例之五：过于庞大的try块 </b><br /><br />　　代码：3行-14行。 <br /><br />　　经常可以看到有人把大量的代码放入单个try块，实际上这不是好习惯。这种现象之所以常见，原因就在于有些人图省事，不愿花时间分析一大块代码中哪几行代码会抛出异常、异常的具体类型是什么。把大量的语句装入单个巨大的try块就象是出门旅游时把所有日常用品塞入一个大箱子，虽然东西是带上了，但要找出来可不容易。 <br /><br />　　一些新手常常把大量的代码放入单个try块，然后再在catch语句中声明Exception，而不是分离各个可能出现异常的段落并分别捕获其异常。这种做法为分析程序抛出异常的原因带来了困难，因为一大段代码中有太多的地方可能抛出Exception。 <br /><br />　　结论五：尽量减小try块的体积。 <br /><br />　　<b>反例之六：输出数据不完整</b><br /><br />　　代码：7行-11行。 <br /><br />　　不完整的数据是Java程序的隐形杀手。仔细观察这段代码，考虑一下如果循环的中间抛出了异常，会发生什么事情。循环的执行当然是要被打断的，其次，catch块会执行??就这些，再也没有其他动作了。已经输出的数据怎么办？使用这些数据的人或设备将收到一份不完整的（因而也是错误的）数据，却得不到任何有关这份数据是否完整的提示。对于有些系统来说，数据不完整可能比系统停止运行带来更大的损失。 <br /><br />　　较为理想的处置办法是向输出设备写一些信息，声明数据的不完整性；另一种可能有效的办法是，先缓冲要输出的数据，准备好全部数据之后再一次性输出。 <br /><br />　　结论六：全面考虑可能出现的异常以及这些异常对执行流程的影响。 <br /><br />　　<b>改写后的代码</b><br /><br />　　根据上面的讨论，下面给出改写后的代码。也许有人会说它稍微有点?嗦，但是它有了比较完备的异常处理机制。 <br /><br /></font></p><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1"><tbody><tr><td><font size="2">OutputStreamWriter out = ... <br />java.sql.Connection conn = ... <br />try { <br />　Statement stat = conn.createStatement(); <br />　ResultSet rs = stat.executeQuery( <br />　　"select uid, name from user"); <br />　while (rs.next()) <br />　{ <br />　　out.println("ID：" + rs.getString("uid") + "，姓名: " + rs.getString("name")); <br />　} <br />} <br />catch(SQLException sqlex) <br />{ <br />　out.println("警告：数据不完整"); <br />　throw new ApplicationException("读取数据时出现SQL错误", sqlex); <br />} <br />catch(IOException ioex) <br />{ <br />　throw new ApplicationException("写入数据时出现IO错误", ioex); <br />} <br />finally <br />{ <br />　if (conn != null) { <br />　　try { <br />　　　conn.close(); <br />　　} <br />　　catch(SQLException sqlex2) <br />　　{ <br />　　　System.err(this.getClass().getName() + ".mymethod - 不能关闭数据库连接: " + sqlex2.toString()); <br />　　} <br />　} <br /><br />　if (out != null) { <br />　　try { <br />　　　out.close(); <br />　　} <br />　　catch(IOException ioex2) <br />　　{ <br />　　　System.err(this.getClass().getName() + ".mymethod - 不能关闭输出文件" + ioex2.toString()); <br />　　} <br />　} <br />} </font></td></tr></tbody></table><br /><font size="2">　　本文的结论不是放之四海皆准的教条，有时常识和经验才是最好的老师。如果你对自己的做法没有百分之百的信心，务必加上详细、全面的注释。 <br /><br />　　另一方面，不要笑话这些错误，不妨问问你自己是否真地彻底摆脱了这些坏习惯。即使最有经验的程序员偶尔也会误入歧途，原因很简单，因为它们确确实实带来了“方便”。所有这些反例都可以看作Java编程世界的恶魔，它们美丽动人，无孔不入，时刻诱惑着你。也许有人会认为这些都属于鸡皮蒜毛的小事，不足挂齿，但请记住：勿以恶小而为之，勿以善小而不为。 <br /></font></span>
<img src ="http://www.blogjava.net/SIDNEY/aggbug/37318.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-03-25 11:23 <a href="http://www.blogjava.net/SIDNEY/archive/2006/03/25/37318.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java简单的获取windows系统网卡mac地址</title><link>http://www.blogjava.net/SIDNEY/archive/2006/03/25/37310.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Sat, 25 Mar 2006 03:12:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/03/25/37310.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/37310.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/03/25/37310.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/37310.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/37310.html</trackback:ping><description><![CDATA[
		<span id="ArticleContent1_ArticleContent1_lblContent"> 
<p>package com.youkone.tool;</p><p>import java.io.BufferedReader;<br />import java.io.InputStreamReader;<br />import java.io.IOException;</p><p>/**<br /> * &lt;p&gt;Title: &lt;/p&gt;<br /> *<br /> * &lt;p&gt;Description: &lt;/p&gt;<br /> *<br /> * &lt;p&gt;Copyright: Copyright (c) 2006&lt;/p&gt;<br /> *<br /> * &lt;p&gt;Company: &lt;/p&gt;<br /> *<br /> * @author not attributable<br /> * @version 1.0<br /> */<br />public class MACAddress {<br />    public MACAddress() {<br />    }</p><p>    public static String getMACAddress() {</p><p>        String address = "";<br />        String os = System.getProperty("os.name");<br />        if (os != null &amp;&amp; os.startsWith("Windows")) {<br />            try {<br />                String command = "cmd.exe /c ipconfig /all";<br />                Process p = Runtime.getRuntime().exec(command);<br />                BufferedReader br =<br />                        new BufferedReader(<br />                                new InputStreamReader(p.getInputStream()));<br />                String line;<br />                while ((line = br.readLine()) != null) {<br />                    if (line.indexOf("Physical Address") &gt; 0) {<br />                        int index = line.indexOf(":");<br />                        index += 2;<br />                        address = line.substring(index);<br />                        break;<br />                    }<br />                }<br />                br.close();<br />                return address.trim();<br />            } catch (IOException e) {}<br />        }<br />        return address;<br />    }</p><p> </p><p>public static void main(String[] args) {<br />    System.out.println(""+MACAddress.getMACAddress());<br />}<br />}</p></span>
		<br />
		<div style="FONT-SIZE: 14px; LINE-HEIGHT: 25px">
				<strong>作者Blog：</strong>
				<a id="ArticleContent1_ArticleContent1_AuthorBlogLink" href="http://blog.csdn.net/woowindice/" target="_blank">
						<font color="#002c99">http://blog.csdn.net/woowindice/</font>
				</a>
		</div>
<img src ="http://www.blogjava.net/SIDNEY/aggbug/37310.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-03-25 11:12 <a href="http://www.blogjava.net/SIDNEY/archive/2006/03/25/37310.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>  将中英文混合的字符串换行     选择自 kasam 的 Blog </title><link>http://www.blogjava.net/SIDNEY/archive/2006/03/25/37309.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Sat, 25 Mar 2006 03:03:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/03/25/37309.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/37309.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/03/25/37309.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/37309.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/37309.html</trackback:ping><description><![CDATA[
		<p>
				<span id="ArticleContent1_ArticleContent1_lblContent">
				</span>
		</p>
		<p>由于接到一任务，大致是这样子的：一个弹页面里面要显示一段文字（多国字符），弹出页面的宽度是定死的。客户不希望文字长度过长时，下面出现水平的拉条。这就关系到一个自动换行的问题。</p>
		<p>由于中文，日文，韩文等一般占2个字节，英文一般占1个字节，所以要换行，首先要计算长度。只有在字节长度相同的情况下换行，同时又要注意不能将中文字拆开了，否则就会是乱码了。</p>
		<p>经过一番努力，这个问题终于搞定了。具体函数如下</p>
		<p>/*判断是否双字节字符*/ </p>
		<p>public boolean isDoublebyteWord(String str){<br />  byte[] b;<br />  int temp;<br />  for (int i = 0; i &lt; str.length(); i++) {<br />  b = str.substring(i, i + 1).getBytes();<br />  temp = b[0];<br />  if (temp &gt; 0) {<br />  return false;<br />  }<br />  }<br />  return true;<br /> }</p>
		<p>/*给字符串添加换行符，其中linepos是需要换行的位置，按字节算的*/ </p>
		<p>public String lineStr(String s,int linePos){<br />  String new_str="";<br />  int total_len=0;<br />  int brNum=0;<br />  for(int i=1;i&lt;=s.length();i++){<br />   if(isDoublebyteWord(s.substring(i-1,i))){<br />    total_len+=2;<br />    if(total_len&gt;=(linePos*(brNum+1))){<br />     new_str+=s.substring(i-1,i)+"&lt;br/&gt;";<br />     brNum++;<br />    }else{<br />     new_str+=s.substring(i-1,i);<br />    }    <br />   }else{<br />    total_len+=1;<br />    if(total_len&gt;=(linePos*(brNum+1))){<br />     new_str+=s.substring(i-1,i)+"&lt;br/&gt;";<br />     brNum++;     <br />    }else{<br />     new_str+=s.substring(i-1,i);<br />    }<br />   }<br />   <br />  }<br />  return new_str;<br /> }<br /><br /><br /><br /><br /><span id="ArticleContent1_ArticleContent1_lblContent"> </span></p>
		<p>在上一篇文章《将中英文混合的字符串换行》中提到了一个换行的算法，后来在实际应用中发现，还是有些问题的，比如，一行全是英文，或者全是中文，排出来的长度是不一样的。所以。后来不得不借用表格以及css来控制，其实也很简单，就加一句话 style="word-break:break-all"。这样自动换行没问题。</p>
		<p>但是，我们还要实现的另外一个功能是：截取字符串的一部分，作为图片的简介，比如说：在一个iframe中显示最新的消息，配有图片，但是给出的位置不可能全部显示所有数据，因此要截取一部分。而且字符串中有 &lt;br/&gt;这样的换行符，因为不能简单的截取。再有就是显示的行数不能超过三行。</p>
		<p>经过一番努力，将于写了个截取函数，还能将就这样。函数如下</p>
		<p> public String getShortString(String source,int cutPos){<br />  String shortStr = "";<br />  int brNum=0;<br />  String tmp="";<br />  String tmp2 = "";<br />  String tmpShort="";<br />  int pos = 0;<br />  int total_len = 0; </p>
		<p>  try{<br />  pos = source.indexOf("&lt;br/&gt;");<br />  System.out.println("1 pos = "+pos);<br />  if(pos&gt;0){<br />   if(source.length()&lt;=cutPos){<br />    <br />    tmpShort = source;<br />   }else{<br />    //判断在截取位置是否有&lt;br/&gt;出现,所以往前往后各取4位，判断是否有&lt;br/&gt;出现<br />    //为什么取四，那是因为&lt;br/&gt;长度是5,而要&lt;br/&gt;中一个字符出现在cutPos位置，<br />    //取四最可能是cutPos位置是&gt; 或者 &lt; ；所以取四包括了所有可能出现情况<br />    //1:当原字符串长度大于截取位置+&lt;br/&gt;的长度<br />    if ( (source.length()-cutPos) &gt;=4){<br />     if(cutPos&gt;=4){<br />      tmp = source.substring(cutPos-4,cutPos+4);<br />     }else{<br />      tmp= source.substring(0,cutPos+4);<br />     }<br />    }else{<br />     if(cutPos&gt;=4){<br />      tmp = source.substring(cutPos-4,source.length());<br />     }else{<br />      tmp= source.substring(0,source.length());<br />     }<br />    }<br />    System.out.println("1 tmp = "+tmp);<br />    int ipos = tmp.indexOf("&lt;br/&gt;");<br />    if (ipos&gt;0){<br />      tmpShort = source.substring(0,cutPos-4)+tmp.substring(0,ipos)+"&lt;br/&gt;";     <br />    }else{<br />     tmpShort = source.substring(0,cutPos);<br />    }</p>
		<p>   }<br />   System.out.println("1 tmpShort = "+tmpShort);<br />    tmp = tmpShort;<br />    tmp2 = tmpShort;<br />    while(pos&gt;0){<br />     brNum+=1;<br />     tmp = tmp2.substring(0,pos);<br />    <br />     if(brNum&gt;2){<br />      <br />      tmp = tmp2.substring(0,pos);<br />      System.out.println("tmp="+tmp);<br />      //shortStr+=tmp; <br />      pos = 0;<br />      //tmp2 = tmp;<br />     }else{<br />      shortStr+=tmp+"&lt;br/&gt;";<br />      tmp = tmp2.substring(pos+5);<br />      System.out.println("tmp 2 ="+tmp);<br />      pos = tmp.indexOf("&lt;br/&gt;");<br />      System.out.println("pos="+pos);<br />      tmp2 = tmp;  <br />     }<br />      <br />    }<br />    if (brNum==1){ <br />     System.out.println("1");<br />     if(tmp.length()&gt;cutPos/2){<br />      shortStr+=tmp.substring(0,cutPos/2)+" ...";//当有一个&lt;br/&gt;时 后面再也没有的时候，第二行截取设定长度的一半。<br />     }else{<br />      shortStr+=tmp+" ...";<br />     }<br />    }else if(brNum==2){<br />     System.out.println("2");<br />     if(tmp.length()&gt;cutPos/3){<br />      shortStr+=tmp.substring(0,cutPos/3)+" ...";//当有二个&lt;br/&gt;时 后面再也没有的时候，第三行截取设定长度的1/3。<br />     }else{<br />      shortStr+=tmp+" ...";<br />     }<br />    }else if(brNum==3){<br />     System.out.println("3");<br />     if(tmp.length()&gt;cutPos/4){<br />      shortStr+=tmp.substring(0,cutPos/4)+" ...";//当有三个&lt;br/&gt;时 后面再也没有的时候，第三行截取设定长度的1/4<br />     }else{<br />      shortStr+=tmp+" ...";<br />     }     <br />     //shortStr+=tmp+"&lt;br/&gt;"+" ...";<br />    } <br />  <br />   }else{<br />    if(source.length()&lt;=cutPos){<br />    <br />     tmpShort = source;<br />    }else{<br />     tmpShort = source.substring(0,cutPos)+" ...";<br />    }<br />/*    if(source.length()&gt;cutPos){<br />     if(tmpShort.length()&gt;cutPos){<br />      shortStr = tmpShort.substring(0,cutPos)+" ...";<br />     <br />     }else{<br />      shortStr = tmpShort+" ...";<br />     }<br />    }else{<br />     shortStr = tmpShort;<br />    }*/<br />    shortStr = tmpShort;<br />      <br />  }<br />  }catch(Exception e){<br />   if(source.length()&lt;=cutPos){<br />    <br />    tmpShort = source;<br />   }else{<br />    tmpShort = source.substring(0,cutPos)+" ...";<br />   }<br />   e.printStackTrace();<br />   shortStr= tmpShort;<br />  }<br />  <br />  return shortStr;<br />  <br /> } <br /><br /><br /><br /><strong>作者Blog：</strong><a id="ArticleContent1_ArticleContent1_AuthorBlogLink" href="http://blog.csdn.net/kasam/" target="_blank"><font color="#002c99">http://blog.csdn.net/kasam/</font></a><br /></p>
<img src ="http://www.blogjava.net/SIDNEY/aggbug/37309.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-03-25 11:03 <a href="http://www.blogjava.net/SIDNEY/archive/2006/03/25/37309.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java中3DES加密解密调用示例(来自网络)</title><link>http://www.blogjava.net/SIDNEY/archive/2006/02/16/31054.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Thu, 16 Feb 2006 06:45:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/02/16/31054.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/31054.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/02/16/31054.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/31054.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/31054.html</trackback:ping><description><![CDATA[<P>/**<BR>&nbsp;* Created by IntelliJ IDEA.<BR>&nbsp;* User: Administrator<BR>&nbsp;* Date: 2006-2-16<BR>&nbsp;* Time: 14:33:57<BR>&nbsp;* To change this template use File | Settings | File Templates.<BR>&nbsp;*/<BR>/*<BR>字符串 DESede(3DES) 加密<BR>*/<BR>import java.security.*;<BR>import javax.crypto.*;<BR>import javax.crypto.spec.SecretKeySpec;</P>
<P>public class Test3Des {</P>
<P>&nbsp;&nbsp;&nbsp; private static final String Algorithm = "DESede"; //定义 加密算法,可用 DES,DESede,Blowfish</P>
<P>&nbsp;&nbsp;&nbsp; //keybyte为加密密钥，长度为24字节<BR>&nbsp;&nbsp;&nbsp; //src为被加密的数据缓冲区（源）<BR>&nbsp;&nbsp;&nbsp; public static byte[] encryptMode(byte[] keybyte, byte[] src) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //生成密钥<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //加密<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Cipher c1 = Cipher.getInstance(Algorithm);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c1.init(Cipher.ENCRYPT_MODE, deskey);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return c1.doFinal(src);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (java.security.NoSuchAlgorithmException e1) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e1.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (javax.crypto.NoSuchPaddingException e2) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e2.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (java.lang.Exception e3) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e3.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; //keybyte为加密密钥，长度为24字节<BR>&nbsp;&nbsp;&nbsp; //src为加密后的缓冲区<BR>&nbsp;&nbsp;&nbsp; public static byte[] decryptMode(byte[] keybyte, byte[] src) {<BR>&nbsp;try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //生成密钥<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //解密<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Cipher c1 = Cipher.getInstance(Algorithm);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c1.init(Cipher.DECRYPT_MODE, deskey);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return c1.doFinal(src);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (java.security.NoSuchAlgorithmException e1) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e1.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (javax.crypto.NoSuchPaddingException e2) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e2.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (java.lang.Exception e3) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e3.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; //转换成十六进制字符串<BR>&nbsp;&nbsp;&nbsp; public static String byte2hex(byte[] b) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String hs="";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String stmp="";</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int n=0;n&lt;b.length;n++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stmp=(java.lang.Integer.toHexString(b[n] &amp; 0XFF));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (stmp.length()==1) hs=hs+"0"+stmp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else hs=hs+stmp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (n&lt;b.length-1)&nbsp; hs=hs+":";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return hs.toUpperCase();<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; public static void main(String[] args)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //添加新安全算法,如果用JCE就要把它添加进去<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Security.addProvider(new com.sun.crypto.provider.SunJCE());</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final byte[] keyBytes = {0x11, 0x22, 0x4F, 0x58, (byte)0x88, 0x10, 0x40, 0x38<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , 0x28, 0x25, 0x79, 0x51, (byte)0xCB, (byte)0xDD, 0x55, 0x66<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , 0x77, 0x29, 0x74, (byte)0x98, 0x30, 0x40, 0x36, (byte)0xE2};&nbsp;//24字节的密钥<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String szSrc = "my name is Sidney.";</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("加密前的字符串:" + szSrc);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte[] encoded = encryptMode(keyBytes, szSrc.getBytes());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("加密后的字符串:" + new String(encoded));</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte[] srcBytes = decryptMode(keyBytes, encoded);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("解密后的字符串:" + (new String(srcBytes)));<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>&nbsp;</P><img src ="http://www.blogjava.net/SIDNEY/aggbug/31054.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-02-16 14:45 <a href="http://www.blogjava.net/SIDNEY/archive/2006/02/16/31054.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JFreeChart API一览</title><link>http://www.blogjava.net/SIDNEY/archive/2006/02/08/29918.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Wed, 08 Feb 2006 05:42:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/02/08/29918.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/29918.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/02/08/29918.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/29918.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/29918.html</trackback:ping><description><![CDATA[<P>JFreeChart类：<BR>void setAntiAlias(boolean flag)&nbsp;&nbsp;&nbsp;&nbsp;字体模糊边界<BR>void setBackgroundImage(Image image)&nbsp;&nbsp;&nbsp;背景图片<BR>void setBackgroundImageAlignment(int alignment)&nbsp;&nbsp;背景图片对齐方式（参数常量在org.jfree.ui.Align类中定义）<BR>void setBackgroundImageAlpha(float alpha)&nbsp;&nbsp;背景图片透明度（0.0～1.0）<BR>void setBackgroundPaint(Paint paint)&nbsp;&nbsp;&nbsp;背景色<BR>void setBorderPaint(Paint paint)&nbsp;&nbsp;&nbsp;边界线条颜色<BR>void setBorderStroke(Stroke stroke)&nbsp;&nbsp;&nbsp;边界线条笔触<BR>void setBorderVisible(boolean visible)&nbsp;&nbsp;&nbsp;边界线条是否可见</P>
<P>-----------------------------------------------------------------------------------------------------------</P>
<P>TextTitle类：<BR>void setFont(Font font)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;标题字体<BR>void setPaint(Paint paint)&nbsp;&nbsp;&nbsp;&nbsp;标题字体颜色<BR>void setText(String text)&nbsp;&nbsp;&nbsp;&nbsp;标题内容</P>
<P>-----------------------------------------------------------------------------------------------------------</P>
<P>StandardLegend(Legend)类：<BR>void setBackgroundPaint(Paint paint)&nbsp;&nbsp;&nbsp;图示背景色<BR>void setTitle(String title)&nbsp;&nbsp;&nbsp;&nbsp;图示标题内容<BR>void setTitleFont(Font font)&nbsp;&nbsp;&nbsp;&nbsp;图示标题字体<BR>void setBoundingBoxArcWidth(int arcWidth)&nbsp;&nbsp;图示边界圆角宽<BR>void setBoundingBoxArcHeight(int arcHeight)&nbsp;&nbsp;图示边界圆角高<BR>void setOutlinePaint(Paint paint)&nbsp;&nbsp;&nbsp;图示边界线条颜色<BR>void setOutlineStroke(Stroke stroke)&nbsp;&nbsp;&nbsp;图示边界线条笔触<BR>void setDisplaySeriesLines(boolean flag)&nbsp;&nbsp;图示项是否显示横线（折线图有效）<BR>void setDisplaySeriesShapes(boolean flag)&nbsp;&nbsp;图示项是否显示形状（折线图有效）<BR>void setItemFont(Font font)&nbsp;&nbsp;&nbsp;&nbsp;图示项字体<BR>void setItemPaint(Paint paint)&nbsp;&nbsp;&nbsp;&nbsp;图示项字体颜色<BR>void setAnchor(int anchor)&nbsp;&nbsp;&nbsp;&nbsp;图示在图表中的显示位置（参数常量在Legend类中定义）</P>
<P>-----------------------------------------------------------------------------------------------------------</P>
<P>Axis类：<BR>void setVisible(boolean flag)&nbsp;&nbsp;&nbsp;&nbsp;坐标轴是否可见<BR>void setAxisLinePaint(Paint paint)&nbsp;&nbsp;&nbsp;坐标轴线条颜色（3D轴无效）<BR>void setAxisLineStroke(Stroke stroke)&nbsp;&nbsp;&nbsp;坐标轴线条笔触（3D轴无效）<BR>void setAxisLineVisible(boolean visible)&nbsp;&nbsp;坐标轴线条是否可见（3D轴无效）<BR>void setFixedDimension(double dimension)&nbsp;&nbsp;（用于复合表中对多坐标轴的设置）<BR>void setLabel(String label)&nbsp;&nbsp;&nbsp;&nbsp;坐标轴标题<BR>void setLabelFont(Font font)&nbsp;&nbsp;&nbsp;&nbsp;坐标轴标题字体<BR>void setLabelPaint(Paint paint)&nbsp;&nbsp;&nbsp;&nbsp;坐标轴标题颜色<BR>void setLabelAngle(double angle)`&nbsp;&nbsp;&nbsp;坐标轴标题旋转角度（纵坐标可以旋转）<BR>void setTickLabelFont(Font font)&nbsp;&nbsp;&nbsp;坐标轴标尺值字体<BR>void setTickLabelPaint(Paint paint)&nbsp;&nbsp;&nbsp;坐标轴标尺值颜色<BR>void setTickLabelsVisible(boolean flag)&nbsp;&nbsp;&nbsp;坐标轴标尺值是否显示<BR>void setTickMarkPaint(Paint paint)&nbsp;&nbsp;&nbsp;坐标轴标尺颜色<BR>void setTickMarkStroke(Stroke stroke)&nbsp;&nbsp;&nbsp;坐标轴标尺笔触<BR>void setTickMarksVisible(boolean flag)&nbsp;&nbsp;&nbsp;坐标轴标尺是否显示</P>
<P>ValueAxis(Axis)类：<BR>void setAutoRange(boolean auto)&nbsp;&nbsp;&nbsp;&nbsp;自动设置数据轴数据范围<BR>void setAutoRangeMinimumSize(double size)&nbsp;&nbsp;自动设置数据轴数据范围时数据范围的最小跨度<BR>void setAutoTickUnitSelection(boolean flag)&nbsp;&nbsp;数据轴的数据标签是否自动确定（默认为true）<BR>void setFixedAutoRange(double length)&nbsp;&nbsp;&nbsp;数据轴固定数据范围（设置100的话就是显示MAXVALUE到MAXVALUE-100那段数据范围）<BR>void setInverted(boolean flag)&nbsp;&nbsp;&nbsp;&nbsp;数据轴是否反向（默认为false）<BR>void setLowerMargin(double margin)&nbsp;&nbsp;&nbsp;数据轴下（左）边距<BR>void setUpperMargin(double margin)&nbsp;&nbsp;&nbsp;数据轴上（右）边距<BR>void setLowerBound(double min)&nbsp;&nbsp;&nbsp;&nbsp;数据轴上的显示最小值<BR>void setUpperBound(double max)&nbsp;&nbsp;&nbsp;&nbsp;数据轴上的显示最大值<BR>void setPositiveArrowVisible(boolean visible)&nbsp;&nbsp;是否显示正向箭头（3D轴无效）<BR>void setNegativeArrowVisible(boolean visible)&nbsp;&nbsp;是否显示反向箭头（3D轴无效）<BR>void setVerticalTickLabels(boolean flag)&nbsp;&nbsp;数据轴数据标签是否旋转到垂直<BR>void setStandardTickUnits(TickUnitSource source)&nbsp;数据轴的数据标签（可以只显示整数标签，需要将AutoTickUnitSelection设false）</P>
<P>NumberAxis(ValueAxis)类：<BR>void setAutoRangeIncludesZero(boolean flag)&nbsp;&nbsp;是否强制在自动选择的数据范围中包含0<BR>void setAutoRangeStickyZero(boolean flag)&nbsp;&nbsp;是否强制在整个数据轴中包含0，即使0不在数据范围中<BR>void setNumberFormatOverride(NumberFormat formatter)&nbsp;数据轴数据标签的显示格式<BR>void setTickUnit(NumberTickUnit unit)&nbsp;&nbsp;&nbsp;数据轴的数据标签（需要将AutoTickUnitSelection设false）</P>
<P>DateAxis(ValueAxis)类：<BR>void setMaximumDate(Date maximumDate)&nbsp;&nbsp;&nbsp;日期轴上的最小日期<BR>void setMinimumDate(Date minimumDate)&nbsp;&nbsp;&nbsp;日期轴上的最大日期<BR>void setRange(Date lower,Date upper)&nbsp;&nbsp;&nbsp;日期轴范围<BR>void setDateFormatOverride(DateFormat formatter)&nbsp;日期轴日期标签的显示格式<BR>void setTickUnit(DateTickUnit unit)&nbsp;&nbsp;&nbsp;日期轴的日期标签（需要将AutoTickUnitSelection设false）<BR>void setTickMarkPosition(DateTickMarkPosition position)&nbsp;日期标签位置（参数常量在org.jfree.chart.axis.DateTickMarkPosition类中定义）</P>
<P>CategoryAxis(Axis)类：<BR>void setCategoryMargin(double margin)&nbsp;&nbsp;&nbsp;分类轴边距<BR>void setLowerMargin(double margin)&nbsp;&nbsp;&nbsp;分类轴下（左）边距<BR>void setUpperMargin(double margin)&nbsp;&nbsp;&nbsp;分类轴上（右）边距<BR>void setVerticalCategoryLabels(boolean flag)&nbsp;&nbsp;分类轴标题是否旋转到垂直<BR>void setMaxCategoryLabelWidthRatio(float ratio)&nbsp;&nbsp;分类轴分类标签的最大宽度</P>
<P>-----------------------------------------------------------------------------------------------------------</P>
<P>Plot类：<BR>void setBackgroundImage(Image image)&nbsp;&nbsp;&nbsp;数据区的背景图片<BR>void setBackgroundImageAlignment(int alignment)&nbsp;&nbsp;数据区的背景图片对齐方式（参数常量在org.jfree.ui.Align类中定义）<BR>void setBackgroundPaint(Paint paint)&nbsp;&nbsp;&nbsp;数据区的背景图片背景色<BR>void setBackgroundAlpha(float alpha)&nbsp;&nbsp;&nbsp;数据区的背景透明度（0.0～1.0）<BR>void setForegroundAlpha(float alpha)&nbsp;&nbsp;&nbsp;数据区的前景透明度（0.0～1.0）<BR>void setDataAreaRatio(double ratio)&nbsp;&nbsp;&nbsp;数据区占整个图表区的百分比<BR>void setOutLinePaint(Paint paint)&nbsp;&nbsp;&nbsp;数据区的边界线条颜色<BR>void setOutLineStroke(Stroke stroke)&nbsp;&nbsp;&nbsp;数据区的边界线条笔触<BR>void setNoDataMessage(String message)&nbsp;&nbsp;&nbsp;没有数据时显示的消息<BR>void setNoDataMessageFont(Font font)&nbsp;&nbsp;&nbsp;没有数据时显示的消息字体<BR>void setNoDataMessagePaint(Paint paint)&nbsp;&nbsp;&nbsp;没有数据时显示的消息颜色</P>
<P>CategoryPlot(Plot)类：<BR>void setDataset(CategoryDataset dataset)&nbsp;&nbsp;数据区的2维数据表<BR>void setColumnRenderingOrder(SortOrder order)&nbsp;&nbsp;数据分类的排序方式<BR>void setAxisOffset(Spacer offset)&nbsp;&nbsp;&nbsp;坐标轴到数据区的间距<BR>void setOrientation(PlotOrientation orientation)&nbsp;数据区的方向（PlotOrientation.HORIZONTAL或PlotOrientation.VERTICAL）<BR>void setDomainAxis(CategoryAxis axis)&nbsp;&nbsp;&nbsp;数据区的分类轴<BR>void setDomainAxisLocation(AxisLocation location)&nbsp;分类轴的位置（参数常量在org.jfree.chart.axis.AxisLocation类中定义）<BR>void setDomainGridlinesVisible(boolean visible)&nbsp;&nbsp;分类轴网格是否可见<BR>void setDomainGridlinePaint(Paint paint)&nbsp;&nbsp;分类轴网格线条颜色<BR>void setDomainGridlineStroke(Stroke stroke)&nbsp;&nbsp;分类轴网格线条笔触<BR>void setRangeAxis(ValueAxis axis)&nbsp;&nbsp;&nbsp;数据区的数据轴<BR>void setRangeAxisLocation(AxisLocation location)&nbsp;数据轴的位置（参数常量在org.jfree.chart.axis.AxisLocation类中定义）<BR>void setRangeGridlinesVisible(boolean visible)&nbsp;&nbsp;数据轴网格是否可见<BR>void setRangeGridlinePaint(Paint paint)&nbsp;&nbsp;&nbsp;数据轴网格线条颜色<BR>void setRangeGridlineStroke(Stroke stroke)&nbsp;&nbsp;数据轴网格线条笔触<BR>void setRenderer(CategoryItemRenderer renderer)&nbsp;&nbsp;数据区的表示者（详见Renderer组）<BR>void addAnnotation(CategoryAnnotation annotation)&nbsp;给数据区加一个注释<BR>void addRangeMarker(Marker marker,Layer layer)&nbsp;&nbsp;给数据区加一个数值范围区域</P>
<P>PiePlot(Plot)类：<BR>void setDataset(PieDataset dataset)&nbsp;&nbsp;&nbsp;数据区的1维数据表<BR>void setIgnoreNullValues(boolean flag)&nbsp;&nbsp;&nbsp;忽略无值的分类<BR>void setCircular(boolean flag)&nbsp;&nbsp;&nbsp;&nbsp;饼图是否一定是正圆<BR>void setStartAngle(double angle)&nbsp;&nbsp;&nbsp;饼图的初始角度<BR>void setDirection(Rotation direction)&nbsp;&nbsp;&nbsp;饼图的旋转方向<BR>void setExplodePercent(int section,double percent)&nbsp;抽取的那块（1维数据表的分类下标）以及抽取出来的距离（0.0～1.0），3D饼图无效<BR>void setLabelBackgroundPaint(Paint paint)&nbsp;&nbsp;分类标签的底色<BR>void setLabelFont(Font font)&nbsp;&nbsp;&nbsp;&nbsp;分类标签的字体<BR>void setLabelPaint(Paint paint)&nbsp;&nbsp;&nbsp;&nbsp;分类标签的字体颜色<BR>void setLabelLinkMargin(double margin)&nbsp;&nbsp;&nbsp;分类标签与图的连接线边距<BR>void setLabelLinkPaint(Paint paint)&nbsp;&nbsp;&nbsp;分类标签与图的连接线颜色<BR>void setLabelLinkStroke(Stroke stroke)&nbsp;&nbsp;&nbsp;分类标签与图的连接线笔触<BR>void setLabelOutlinePaint(Paint paint)&nbsp;&nbsp;&nbsp;分类标签边框颜色<BR>void setLabelOutlineStroke(Paint paint)&nbsp;&nbsp;&nbsp;分类标签边框笔触<BR>void setLabelShadowPaint(Paint paint)&nbsp;&nbsp;&nbsp;分类标签阴影颜色<BR>void setMaximumLabelWidth(double width)&nbsp;&nbsp;&nbsp;分类标签的最大长度（0.0～1.0）<BR>void setPieIndex(int index)&nbsp;&nbsp;&nbsp;&nbsp;饼图的索引（复合饼图中用到）<BR>void setSectionOutlinePaint(int section,Paint paint)&nbsp;指定分类饼的边框颜色<BR>void setSectionOutlineStroke(int section,Stroke stroke)&nbsp;指定分类饼的边框笔触<BR>void setSectionPaint(int section,Paint paint)&nbsp;&nbsp;指定分类饼的颜色<BR>void setShadowPaint(Paint paint)&nbsp;&nbsp;&nbsp;饼图的阴影颜色<BR>void setShadowXOffset(double offset)&nbsp;&nbsp;&nbsp;饼图的阴影相对图的水平偏移<BR>void setShadowYOffset(double offset)&nbsp;&nbsp;&nbsp;饼图的阴影相对图的垂直偏移<BR>void setLabelGenerator(PieSectionLabelGenerator generator)&nbsp;分类标签的格式，设置成null则整个标签包括连接线都不显示<BR>void setToolTipGenerator(PieToolTipGenerator generator)&nbsp;&nbsp;MAP中鼠标移上的显示格式<BR>void setURLGenerator(PieURLGenerator generator)&nbsp;&nbsp;&nbsp;MAP中钻取链接格式</P>
<P>PiePlot3D(PiePlot)类：<BR>void setDepthFactor(double factor)&nbsp;&nbsp;&nbsp;3D饼图的Z轴高度（0.0～1.0）</P>
<P>MultiplePiePlot(Plot)类：<BR>void setLimit(double limit)&nbsp;&nbsp;&nbsp;&nbsp;每个饼图之间的数据关联（详细比较复杂）&nbsp;&nbsp;&nbsp;<BR>void setPieChart(JFreeChart pieChart)&nbsp;&nbsp;&nbsp;每个饼图的显示方式（见JFreeChart类个PiePlot类）</P>
<P>-----------------------------------------------------------------------------------------------------------</P>
<P>AbstractRenderer类：<BR>void setItemLabelAnchorOffset(double offset)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数据标签的与数据点的偏移<BR>void setItemLabelsVisible(boolean visible)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数据标签是否可见<BR>void setItemLabelFont(Font font)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数据标签的字体<BR>void setItemLabelPaint(Paint paint)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数据标签的字体颜色<BR>void setItemLabelPosition(ItemLabelPosition position)&nbsp;&nbsp;&nbsp;&nbsp;数据标签位置<BR>void setPositiveItemLabelPosition(ItemLabelPosition position)&nbsp;&nbsp;&nbsp;正数标签位置<BR>void setNegativeItemLabelPosition(ItemLabelPosition position)&nbsp;&nbsp;&nbsp;负数标签位置<BR>void setOutLinePaint(Paint paint)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;图形边框的线条颜色<BR>void setOutLineStroke(Stroke stroke)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;图形边框的线条笔触<BR>void setPaint(Paint paint)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;所有分类图形的颜色<BR>void setShape(Shape shape)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;所有分类图形的形状（如折线图的点）<BR>void setStroke(Stroke stroke)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;所有分类图形的笔触（如折线图的线）<BR>void setSeriesItemLabelsVisible(int series,boolean visible)&nbsp;&nbsp;&nbsp;指定分类的数据标签是否可见<BR>void setSeriesItemLabelFont(int series,Font font)&nbsp;&nbsp;&nbsp;&nbsp;指定分类的数据标签的字体<BR>void setSeriesItemLabelPaint(int series,Paint paint)&nbsp;&nbsp;&nbsp;&nbsp;指定分类的数据标签的字体颜色<BR>void setSeriesItemLabelPosition(int series,ItemLabelPosition position)&nbsp;&nbsp;数据标签位置<BR>void setSeriesPositiveItemLabelPosition(int series,ItemLabelPosition position)&nbsp;正数标签位置<BR>void setSeriesNegativeItemLabelPosition(int series,ItemLabelPosition position)&nbsp;负数标签位置<BR>void setSeriesOutLinePaint(int series,Paint paint)&nbsp;&nbsp;&nbsp;&nbsp;指定分类的图形边框的线条颜色<BR>void setSeriesOutLineStroke(int series,Stroke stroke)&nbsp;&nbsp;&nbsp;&nbsp;指定分类的图形边框的线条笔触<BR>void setSeriesPaint(int series,Paint paint)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;指定分类图形的颜色<BR>void setSeriesShape(int series,Shape shape)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;指定分类图形的形状（如折线图的点）<BR>void setSeriesStroke(int series,Stroke stroke)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;指定分类图形的笔触（如折线图的线）</P>
<P>AbstractCategoryItemRenderer(AbstractRenderer)类：<BR>void setLabelGenerator(CategoryLabelGenerator generator)&nbsp;&nbsp;&nbsp;数据标签的格式<BR>void setToolTipGenerator(CategoryToolTipGenerator generator)&nbsp;&nbsp;&nbsp;MAP中鼠标移上的显示格式<BR>void setItemURLGenerator(CategoryURLGenerator generator)&nbsp;&nbsp;&nbsp;MAP中钻取链接格式<BR>void setSeriesLabelGenerator(int series,CategoryLabelGenerator generator)&nbsp;指定分类的数据标签的格式<BR>void setSeriesToolTipGenerator(int series,CategoryToolTipGenerator generator)&nbsp;指定分类的MAP中鼠标移上的显示格式<BR>void setSeriesItemURLGenerator(int series,CategoryURLGenerator generator)&nbsp;指定分类的MAP中钻取链接格式</P>
<P>BarRenderer(AbstractCategoryItemRenderer)类：<BR>void setDrawBarOutline(boolean draw)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;是否画图形边框<BR>void setItemMargin(double percent)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每个BAR之间的间隔<BR>void setMaxBarWidth(double percent)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每个BAR的最大宽度<BR>void setMinimumBarLength(double min)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;最短的BAR长度，避免数值太小而显示不出<BR>void setPositiveItemLabelPositionFallback(ItemLabelPosition position)&nbsp;&nbsp;无法在BAR中显示的正数标签位置<BR>void setNegativeItemLabelPositionFallback(ItemLabelPosition position)&nbsp;&nbsp;无法在BAR中显示的负数标签位置</P>
<P>BarRenderer3D(BarRenderer)类：<BR>void setWallPaint(Paint paint)&nbsp;&nbsp;&nbsp;&nbsp;3D坐标轴的墙体颜色</P>
<P>StackedBarRenderer(BarRenderer)类：<BR>没有特殊的设置</P>
<P>StackedBarRenderer3D(BarRenderer3D)类：<BR>没有特殊的设置</P>
<P>GroupedStackedBarRenderer(StackedBarRenderer)类：<BR>void setSeriesToGroupMap(KeyToGroupMap map)&nbsp;&nbsp;将分类自由的映射成若干个组（KeyToGroupMap.mapKeyToGroup(series,group)）</P>
<P>LayeredBarRenderer(BarRenderer)类：<BR>void setSeriesBarWidth(int series,double width)&nbsp;&nbsp;设定每个分类的宽度（注意设置不要使某分类被覆盖）</P>
<P>WaterfallBarRenderer(BarRenderer)类：<BR>void setFirstBarPaint(Paint paint)&nbsp;&nbsp;&nbsp;第一个柱图的颜色<BR>void setLastBarPaint(Paint paint)&nbsp;&nbsp;&nbsp;最后一个柱图的颜色<BR>void setPositiveBarPaint(Paint paint)&nbsp;&nbsp;&nbsp;正值柱图的颜色<BR>void setNegativeBarPaint(Paint paint)&nbsp;&nbsp;&nbsp;负值柱图的颜色</P>
<P>IntervalBarRenderer(BarRenderer)类：<BR>需要传IntervalCategoryDataset作为数据源</P>
<P>GanttBarRenderer(IntervalBarRenderer)类：<BR>void setCompletePaint(Paint paint)&nbsp;&nbsp;&nbsp;完成进度颜色<BR>void setIncompletePaint(Paint paint)&nbsp;&nbsp;&nbsp;未完成进度颜色<BR>void setStartPercent(double percent)&nbsp;&nbsp;&nbsp;设置进度条在整条中的起始位置（0.0～1.0）<BR>void setEndPercent(double percent)&nbsp;&nbsp;&nbsp;设置进度条在整条中的结束位置（0.0～1.0）</P>
<P>StatisticBarRenderer(BarRenderer)类：<BR>需要传StatisticCategoryDataset作为数据源</P>
<P>LineAndShapeRenderer(AbstractCategoryItemRenderer)类：<BR>void setDrawLines(boolean draw)&nbsp;&nbsp;&nbsp;&nbsp;是否折线的数据点之间用线连<BR>void setDrawShapes(boolean draw)&nbsp;&nbsp;&nbsp;是否折线的数据点根据分类使用不同的形状<BR>void setShapesFilled(boolean filled)&nbsp;&nbsp;&nbsp;所有分类是否填充数据点图形<BR>void setSeriesShapesFilled(int series,boolean filled)&nbsp;指定分类是否填充数据点图形<BR>void setUseFillPaintForShapeOutline(boolean use)&nbsp;指定是否填充数据点的Paint也被用于画数据点形状的边框</P>
<P>LevelRenderer(AbstractCategoryItemRenderer)类：<BR>void setItemMargin(double percent)&nbsp;&nbsp;&nbsp;每个分类之间的间隔<BR>void setMaxItemWidth(double percent)&nbsp;&nbsp;&nbsp;每个分类的最大宽度</P>
<P>CategoryStepRenderer(AbstractCategoryItemRenderer)类：<BR>void setStagger(boolean shouldStagger)&nbsp;&nbsp;&nbsp;不同分类的图是否交错</P>
<P>MinMaxCategoryRenderer(AbstractCategoryItemRenderer)类：<BR>void setDrawLines(boolean drawLines)&nbsp;&nbsp;&nbsp;是否在每个分类线间画连接线<BR>void setGroupPaint(Paint groupPaint)&nbsp;&nbsp;&nbsp;一组图形连接线的颜色<BR>void setGroupStroke(Stroke groupStroke)&nbsp;&nbsp;&nbsp;一组图形连接线的笔触<BR>void setMaxIcon(Icon maxIcon)&nbsp;&nbsp;&nbsp;&nbsp;最大值的ICON<BR>void setMinIcon(Icon minIcon)&nbsp;&nbsp;&nbsp;&nbsp;最小值的ICON<BR>void setObjectIcon(Icon objectIcon)&nbsp;&nbsp;&nbsp;所有值的ICON</P>
<P>AreaRender(AbstractCategoryItemRenderer)类：<BR>没有特殊的设置</P>
<P>StackedAreaRender(AreaRender)类：<BR>没有特殊的设置<BR><BR><BR>----------------------<BR>//display values on the Top of the Corrasponding Bar&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CategoryLabelGenerator generator = new StandardCategoryLabelGenerator("{2}", NumberFormat.getInstance());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; renderer.setLabelGenerator(generator);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; renderer.setItemLabelsVisible(true);</P>
<P>&nbsp;</P>
<P>//using multiple axis </P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XYPlot plot = new XYPlot();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; plot.setDataset(0,xyDataset);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; plot.setDataset(1,xyDataset2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; plot.setDomainAxis(timeAxis);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //plot.setDomainAxis(1,timeAxis2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; plot.setRangeAxis(valueAxis);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //plot.setRangeAxis(1,valueAxis2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; plot.setRenderer(0,renderer);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; plot.setRenderer(1,renderer2);</P><img src ="http://www.blogjava.net/SIDNEY/aggbug/29918.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-02-08 13:42 <a href="http://www.blogjava.net/SIDNEY/archive/2006/02/08/29918.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA中数据库操作的各种方式与设计模式的应用</title><link>http://www.blogjava.net/SIDNEY/archive/2006/01/25/29200.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Wed, 25 Jan 2006 07:00:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/01/25/29200.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/29200.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/01/25/29200.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/29200.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/29200.html</trackback:ping><description><![CDATA[<SPAN id=ArticleContent1_ArticleContent1_lblContent>&nbsp;(来自<FONT color=#3366ff>&nbsp; </FONT><A href="http://blog.csdn.net/wangyihust/"><SPAN style="COLOR: #3366ff">青山不改</SPAN><SPAN style="COLOR: #3366ff">绿水长流</SPAN><SPAN style="COLOR: #3366ff">－</SPAN><SPAN style="COLOR: #3366ff">EKing</SPAN></A><FONT color=#3366ff> </FONT>)
<DIV><SPAN>&nbsp;</SPAN></DIV>
<DIV style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt"><STRONG>1.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp; </SPAN></STRONG><STRONG>在业务层使用JDBC直接操作数据库－最简单，最直接的操作</STRONG></DIV>
<DIV style="TEXT-INDENT: 108.4pt"><STRONG><SPAN style="BACKGROUND: #d9d9d9">紧耦合方式，黑暗中的痛苦</SPAN></STRONG></DIV>
<DIV style="TEXT-INDENT: 108pt">&nbsp;</DIV>
<DIV>1）数据库url,username,password写死在代码中</DIV>
<DIV>&nbsp;&nbsp;&nbsp; Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();&nbsp;</DIV>
<DIV><SPAN>&nbsp;&nbsp;&nbsp; String url="jdbc:oracle:thin:@localhost:1521:orcl";&nbsp;</SPAN></DIV>
<DIV><SPAN>&nbsp;&nbsp;&nbsp; String user="scott";&nbsp;</SPAN></DIV>
<DIV><SPAN>&nbsp;&nbsp;&nbsp; String password="tiger";&nbsp;</SPAN></DIV>
<DIV><SPAN>&nbsp;&nbsp;&nbsp; Connection conn= DriverManager.getConnection(url,user,password);&nbsp; </SPAN></DIV>
<DIV><SPAN>&nbsp;&nbsp;&nbsp; </SPAN>Statement stmt=conn.createStatement(</DIV>
<DIV style="TEXT-INDENT: 48pt">ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);&nbsp;</DIV>
<DIV><SPAN>&nbsp;&nbsp;&nbsp; String sql="select * from test";&nbsp;</SPAN></DIV>
<DIV><SPAN>&nbsp;&nbsp;&nbsp; </SPAN>ResultSet rs=stmt.executeQuery(sql); </DIV>
<DIV>&nbsp;</DIV>
<DIV>2）采用Facade和Command模式，使用DBUtil类封装JDBC操作；</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 数据库url,username,password可以放在配置文件中（如xml,properties,ini等）。</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这种方法在小程序中应用较多。</DIV>
<DIV>&nbsp;</DIV>
<DIV><STRONG>2.DAO(Data Accessor Object)模式－松耦合的开始</STRONG></DIV>
<DIV style="TEXT-INDENT: 30pt">DAO = data + accessor + domain object</DIV>
<DIV style="TEXT-INDENT: 30pt">&nbsp;</DIV>
<DIV>&nbsp;例如User类－domain object (javabean)</DIV>
<DIV style="TEXT-INDENT: 30pt">UserDAO类－accessor ，提供的方法getUser(int id)，save(User user)内包含了JDBC操作</DIV>
<DIV style="TEXT-INDENT: 30pt">在业务逻辑中使用这两个类来完成数据操作。</DIV>
<DIV style="TEXT-INDENT: 30pt">&nbsp;</DIV>
<DIV>使用Factory模式可以方便不同数据库连接之间的移植。</DIV>
<DIV>&nbsp;</DIV>
<DIV><STRONG>3.数据库资源管理模式</STRONG></DIV>
<DIV style="TEXT-INDENT: 12.05pt"><STRONG>3.1 数据库连接池技术</STRONG></DIV>
<DIV style="TEXT-INDENT: 36pt">资源重用，避免频繁创建，释放连接引起大大量性能开销；</DIV>
<DIV style="TEXT-INDENT: 36pt">更快的系统响应速度；</DIV>
<DIV style="TEXT-INDENT: 36pt">&nbsp;</DIV>
<DIV style="TEXT-INDENT: 24pt">通过实现JDBC的部分资源对象接口( Connection, Statement, ResultSet )，可以使用Decorator设计模式分别产生三种逻辑资源对象: PooledConnection, PooledStatement和 PooledResultSet。</DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN style="BACKGROUND: #d9d9d9">一个最简单地数据库连接池实现</SPAN>：</DIV>
<DIV align=left><STRONG><SPAN style="BACKGROUND: white; COLOR: #7f0055">public</SPAN></STRONG><SPAN style="BACKGROUND: white"> <STRONG><SPAN style="COLOR: #7f0055">class</SPAN></STRONG> <SPAN style="COLOR: black">ConnectionPool</SPAN> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left>&nbsp;</DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">private</SPAN></STRONG> <STRONG><SPAN style="COLOR: #7f0055">static</SPAN></STRONG> <SPAN style="COLOR: black">Vector</SPAN> <SPAN style="COLOR: black">pools;</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">private</SPAN></STRONG> <STRONG><SPAN style="COLOR: #7f0055">final</SPAN></STRONG> <STRONG><SPAN style="COLOR: #7f0055">int</SPAN></STRONG> <SPAN style="COLOR: black">POOL_MAXSIZE</SPAN> <SPAN style="COLOR: black">=</SPAN> <SPAN style="COLOR: black">25;</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: #3f5fbf">/**</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<SPAN style="COLOR: #3f5fbf">*</SPAN> </SPAN><SPAN style="BACKGROUND: white; COLOR: #3f5fbf">获取数据库连接</SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<SPAN style="COLOR: #3f5fbf">*</SPAN> </SPAN><SPAN style="BACKGROUND: white; COLOR: #3f5fbf">如果当前池中有可用连接，则将池中最后一个返回；若没有，则创建一个新的返回</SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<SPAN style="COLOR: #3f5fbf">*/</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">public</SPAN></STRONG> <STRONG><SPAN style="COLOR: #7f0055">synchronized</SPAN></STRONG> <SPAN style="COLOR: black">Connection</SPAN> <SPAN style="COLOR: black">getConnection()</SPAN> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">Connection</SPAN> <SPAN style="COLOR: black">conn</SPAN> <SPAN style="COLOR: black">=</SPAN> <STRONG><SPAN style="COLOR: #7f0055">null</SPAN></STRONG><SPAN style="COLOR: black">;</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">if</SPAN></STRONG> <SPAN style="COLOR: black">(pools</SPAN> <SPAN style="COLOR: black">==</SPAN> <STRONG><SPAN style="COLOR: #7f0055">null</SPAN></STRONG><SPAN style="COLOR: black">)</SPAN> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">pools</SPAN> <SPAN style="COLOR: black">=</SPAN> <STRONG><SPAN style="COLOR: #7f0055">new</SPAN></STRONG> <SPAN style="COLOR: black">Vector();</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN></SPAN></DIV>
<DIV align=left>&nbsp;</DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">if</SPAN></STRONG> <SPAN style="COLOR: black">(pools.isEmpty())</SPAN> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">conn</SPAN> <SPAN style="COLOR: black">=</SPAN> <SPAN style="COLOR: black">createConnection();</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN> <STRONG><SPAN style="COLOR: #7f0055">else</SPAN></STRONG> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">int</SPAN></STRONG> <SPAN style="COLOR: black">last_idx</SPAN> <SPAN style="COLOR: black">=</SPAN> <SPAN style="COLOR: black">pools.size()</SPAN> <SPAN style="COLOR: black">-</SPAN> <SPAN style="COLOR: black">1;</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">conn</SPAN> <SPAN style="COLOR: black">=</SPAN> <SPAN style="COLOR: black">(Connection)</SPAN> <SPAN style="COLOR: black">pools.get(last_idx);</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">pools.remove(last_idx);</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN></SPAN></DIV>
<DIV align=left>&nbsp;</DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">return</SPAN></STRONG> <SPAN style="COLOR: black">conn;</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN></SPAN></DIV>
<DIV align=left>&nbsp;</DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: #3f5fbf">/**</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<SPAN style="COLOR: #3f5fbf">*</SPAN> </SPAN><SPAN style="BACKGROUND: white; COLOR: #3f5fbf">将使用完毕的数据库连接放回池中</SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<SPAN style="COLOR: #3f5fbf">*</SPAN> </SPAN><SPAN style="BACKGROUND: white; COLOR: #3f5fbf">若池中连接已经超过阈值，则关闭该连接；否则放回池中下次再使用</SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<SPAN style="COLOR: #3f5fbf">*/</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">public</SPAN></STRONG> <STRONG><SPAN style="COLOR: #7f0055">synchronized</SPAN></STRONG> <STRONG><SPAN style="COLOR: #7f0055">void</SPAN></STRONG> <SPAN style="COLOR: black">releaseConnection(Connection</SPAN> <SPAN style="COLOR: black">conn)</SPAN> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">if</SPAN></STRONG> <SPAN style="COLOR: black">(pools.size()</SPAN> <SPAN style="COLOR: black">&gt;=</SPAN> <SPAN style="COLOR: black">POOL_MAXSIZE)</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">try</SPAN></STRONG> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&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; <SPAN style="COLOR: black">conn.close();</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN> <STRONG><SPAN style="COLOR: #7f0055">catch</SPAN></STRONG> <SPAN style="COLOR: black">(SQLException</SPAN> <SPAN style="COLOR: black">e)</SPAN> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&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; <SPAN style="COLOR: #3f7f5f">// </SPAN><STRONG><SPAN style="COLOR: #7f9fbf">TODO</SPAN></STRONG></SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f">自动生成</SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f"> catch </SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f">块</SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&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; <SPAN style="COLOR: black">e.printStackTrace();</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN> <STRONG><SPAN style="COLOR: #7f0055">else</SPAN></STRONG></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">pools.add(conn);</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN></SPAN></DIV>
<DIV align=left>&nbsp;</DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">public</SPAN></STRONG> <STRONG><SPAN style="COLOR: #7f0055">static</SPAN></STRONG> <SPAN style="COLOR: black">Connection</SPAN> <SPAN style="COLOR: black">createConnection()</SPAN> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">Connection</SPAN> <SPAN style="COLOR: black">conn</SPAN> <SPAN style="COLOR: black">=</SPAN> <STRONG><SPAN style="COLOR: #7f0055">null</SPAN></STRONG><SPAN style="COLOR: black">;</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">try</SPAN></STRONG> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">Class.forName(</SPAN><SPAN style="COLOR: #2a00ff">"oracle.jdbc.driver.OracleDriver"</SPAN><SPAN style="COLOR: black">).newInstance();</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">String</SPAN> <SPAN style="COLOR: black">url</SPAN> <SPAN style="COLOR: black">=</SPAN> <SPAN style="COLOR: #2a00ff">"jdbc:oracle:thin:@localhost:1521:orcl"</SPAN><SPAN style="COLOR: black">;</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">String</SPAN> <SPAN style="COLOR: black">user</SPAN> <SPAN style="COLOR: black">=</SPAN> <SPAN style="COLOR: #2a00ff">"scott"</SPAN><SPAN style="COLOR: black">;</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">String</SPAN> <SPAN style="COLOR: black">password</SPAN> <SPAN style="COLOR: black">=</SPAN> <SPAN style="COLOR: #2a00ff">"tiger"</SPAN><SPAN style="COLOR: black">;</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">conn</SPAN> <SPAN style="COLOR: black">=</SPAN> <SPAN style="COLOR: black">DriverManager.getConnection(url,</SPAN> <SPAN style="COLOR: black">user,</SPAN> <SPAN style="COLOR: black">password);</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN> <STRONG><SPAN style="COLOR: #7f0055">catch</SPAN></STRONG> <SPAN style="COLOR: black">(InstantiationException</SPAN> <SPAN style="COLOR: black">e)</SPAN> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: #3f7f5f">// </SPAN><STRONG><SPAN style="COLOR: #7f9fbf">TODO</SPAN></STRONG></SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f">自动生成</SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f"> catch </SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f">块</SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">e.printStackTrace();</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN> <STRONG><SPAN style="COLOR: #7f0055">catch</SPAN></STRONG> <SPAN style="COLOR: black">(IllegalAccessException</SPAN> <SPAN style="COLOR: black">e)</SPAN> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: #3f7f5f">// </SPAN><STRONG><SPAN style="COLOR: #7f9fbf">TODO</SPAN></STRONG></SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f">自动生成</SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f"> catch </SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f">块</SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">e.printStackTrace();</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN> <STRONG><SPAN style="COLOR: #7f0055">catch</SPAN></STRONG> <SPAN style="COLOR: black">(ClassNotFoundException</SPAN> <SPAN style="COLOR: black">e)</SPAN> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: #3f7f5f">// </SPAN><STRONG><SPAN style="COLOR: #7f9fbf">TODO</SPAN></STRONG></SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f">自动生成</SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f"> catch </SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f">块</SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">e.printStackTrace();</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN> <STRONG><SPAN style="COLOR: #7f0055">catch</SPAN></STRONG> <SPAN style="COLOR: black">(SQLException</SPAN> <SPAN style="COLOR: black">e)</SPAN> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: #3f7f5f">// </SPAN><STRONG><SPAN style="COLOR: #7f9fbf">TODO</SPAN></STRONG></SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f">自动生成</SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f"> catch </SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f">块</SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">e.printStackTrace();</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">return</SPAN></STRONG> <SPAN style="COLOR: black">conn;</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN></SPAN></DIV>
<DIV><SPAN style="FONT-SIZE: 10.5pt; BACKGROUND: white; COLOR: black">}</SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><STRONG><SPAN style="BACKGROUND: white; COLOR: black">注意</SPAN></STRONG><SPAN style="BACKGROUND: white; COLOR: black">：利用getConnection</SPAN><SPAN style="COLOR: black">()方法得到的Connection，程序员很习惯地调用conn.close()方法关闭了数据库连接，那么上述的数据库连接机制便形同虚设。&nbsp;&nbsp; <SPAN style="BACKGROUND: #d9d9d9">在调用conn.close()方法方法时如何调用<SPAN style="BACKGROUND: white">releaseConnection</SPAN>()方法？这是关键。这里，我们使用Proxy模式和java反射机制。<BR></SPAN></SPAN><STRONG><SPAN style="BACKGROUND: white; COLOR: #7f0055">public</SPAN></STRONG><SPAN style="BACKGROUND: white"> <STRONG><SPAN style="COLOR: #7f0055">synchronized</SPAN></STRONG> <SPAN style="COLOR: black">Connection</SPAN> <SPAN style="COLOR: black">getConnection()</SPAN> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">Connection</SPAN> <SPAN style="COLOR: black">conn</SPAN> <SPAN style="COLOR: black">=</SPAN> <STRONG><SPAN style="COLOR: #7f0055">null</SPAN></STRONG><SPAN style="COLOR: black">;</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">if</SPAN></STRONG> <SPAN style="COLOR: black">(pools</SPAN> <SPAN style="COLOR: black">==</SPAN> <STRONG><SPAN style="COLOR: #7f0055">null</SPAN></STRONG><SPAN style="COLOR: black">)</SPAN> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">pools</SPAN> <SPAN style="COLOR: black">=</SPAN> <STRONG><SPAN style="COLOR: #7f0055">new</SPAN></STRONG> <SPAN style="COLOR: black">Vector();</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN></SPAN></DIV>
<DIV align=left>&nbsp;</DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">if</SPAN></STRONG> <SPAN style="COLOR: black">(pools.isEmpty())</SPAN> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">conn</SPAN> <SPAN style="COLOR: black">=</SPAN> <SPAN style="COLOR: black">createConnection();</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN> <STRONG><SPAN style="COLOR: #7f0055">else</SPAN></STRONG> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">int</SPAN></STRONG> <SPAN style="COLOR: black">last_idx</SPAN> <SPAN style="COLOR: black">=</SPAN> <SPAN style="COLOR: black">pools.size()</SPAN> <SPAN style="COLOR: black">-</SPAN> <SPAN style="COLOR: black">1;</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">conn</SPAN> <SPAN style="COLOR: black">=</SPAN> <SPAN style="COLOR: black">(Connection)</SPAN> <SPAN style="COLOR: black">pools.get(last_idx);</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">pools.remove(last_idx);</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN></SPAN></DIV>
<DIV align=left><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></DIV>
<DIV align=left><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ConnectionHandler handler=new ConnectionHandler(this);</SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">return</SPAN></STRONG> </SPAN>handler.bind(con)<SPAN style="BACKGROUND: white; COLOR: black">;</SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN></SPAN></DIV>
<DIV align=left>&nbsp;</DIV>
<DIV align=left><STRONG><SPAN style="BACKGROUND: white; COLOR: #7f0055">public</SPAN></STRONG><SPAN style="BACKGROUND: white"> <STRONG><SPAN style="COLOR: #7f0055">class</SPAN></STRONG> <SPAN style="COLOR: black">ConnectionHandler</SPAN> <STRONG><SPAN style="COLOR: #7f0055">implements</SPAN></STRONG> <SPAN style="COLOR: black">InvocationHandler</SPAN> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">private</SPAN></STRONG> <SPAN style="COLOR: black">Connection</SPAN> <SPAN style="COLOR: black">conn;</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">private</SPAN></STRONG> <SPAN style="COLOR: black">ConnectionPool</SPAN> <SPAN style="COLOR: black">pool;</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp; &nbsp;<STRONG><SPAN style="COLOR: #7f0055">public</SPAN></STRONG> <SPAN style="COLOR: black">ConnectionHandler(ConnectionPool</SPAN> <SPAN style="COLOR: black">pool){</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">this</SPAN></STRONG><SPAN style="COLOR: black">.pool=pool;</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: #3f5fbf">/**</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: #3f5fbf">*</SPAN> </SPAN><SPAN style="BACKGROUND: white; COLOR: #3f5fbf">将动态代理绑定到指定</SPAN><SPAN style="BACKGROUND: white; COLOR: #3f5fbf">Connection</SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: #3f5fbf">*</SPAN> <STRONG><SPAN style="COLOR: #7f9fbf">@param</SPAN></STRONG> <SPAN style="COLOR: #3f5fbf">conn</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: #3f5fbf">*</SPAN> <STRONG><SPAN style="COLOR: #7f9fbf">@return</SPAN></STRONG></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: #3f5fbf">*/</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">public</SPAN></STRONG> <SPAN style="COLOR: black">Connection</SPAN> <SPAN style="COLOR: black">bind(Connection</SPAN> <SPAN style="COLOR: black">conn){</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">this</SPAN></STRONG><SPAN style="COLOR: black">.conn=conn;</SPAN></SPAN></DIV>
<DIV style="TEXT-INDENT: 42pt" align=left><SPAN style="BACKGROUND: white; COLOR: black">Connection</SPAN><SPAN style="BACKGROUND: white"> <SPAN style="COLOR: black">proxyConn=(Connection)Proxy.newProxyInstance(</SPAN></SPAN></DIV>
<DIV style="TEXT-INDENT: 73.5pt" align=left><SPAN style="BACKGROUND: white; COLOR: black">conn.getClass().getClassLoader(),</SPAN><SPAN style="BACKGROUND: white"> <SPAN style="COLOR: black">conn.getClass().getInterfaces(),</SPAN><STRONG><SPAN style="COLOR: #7f0055">this</SPAN></STRONG><SPAN style="COLOR: black">);</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">return</SPAN></STRONG> <SPAN style="COLOR: black">proxyConn;</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: #3f7f5f">/* </SPAN></SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f">（非</SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f"> Javadoc</SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f">）</SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white; COLOR: #3f7f5f">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])</SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white; COLOR: #3f7f5f">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;*/</SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">public</SPAN></STRONG> <SPAN style="COLOR: black">Object</SPAN> <SPAN style="COLOR: black">invoke(Object</SPAN> <SPAN style="COLOR: black">proxy,</SPAN> <SPAN style="COLOR: black">Method</SPAN> <SPAN style="COLOR: black">method,</SPAN> <SPAN style="COLOR: black">Object[]</SPAN> <SPAN style="COLOR: black">args)</SPAN> <STRONG><SPAN style="COLOR: #7f0055">throws</SPAN></STRONG> <SPAN style="COLOR: black">Throwable</SPAN> <SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: #3f7f5f">// </SPAN><STRONG><SPAN style="COLOR: #7f9fbf">TODO</SPAN></STRONG></SPAN><SPAN style="BACKGROUND: white; COLOR: #3f7f5f">自动生成方法存根</SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">Object</SPAN> <SPAN style="COLOR: black">obj=</SPAN><STRONG><SPAN style="COLOR: #7f0055">null</SPAN></STRONG><SPAN style="COLOR: black">;</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">if</SPAN></STRONG><SPAN style="COLOR: black">(</SPAN><SPAN style="COLOR: #2a00ff">"close"</SPAN><SPAN style="COLOR: black">.equals(method.getName())){</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">this</SPAN></STRONG><SPAN style="COLOR: black">.pool.releaseConnection(</SPAN><STRONG><SPAN style="COLOR: #7f0055">this</SPAN></STRONG><SPAN style="COLOR: black">.conn);</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">else</SPAN></STRONG><SPAN style="COLOR: black">{</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">obj=method.invoke(</SPAN><STRONG><SPAN style="COLOR: #7f0055">this</SPAN></STRONG><SPAN style="COLOR: black">.conn,</SPAN> <SPAN style="COLOR: black">args);</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><SPAN style="COLOR: #7f0055">return</SPAN></STRONG> <SPAN style="COLOR: black">obj;</SPAN></SPAN></DIV>
<DIV align=left><SPAN style="BACKGROUND: white">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: black">}</SPAN></SPAN></DIV>
<DIV><SPAN style="FONT-SIZE: 10.5pt; BACKGROUND: white; COLOR: black">}</SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在实际项目中，并不需要你来从头开始来设计数据库连接池机制，现在成熟的开源项目，如C3P0,dbcp,Proxool等提供了良好的实现。一般推荐使用Apache dbcp，基本使用实例：</DIV>
<DIV></DIV>
<DIV></DIV>
<DIV>DataSource ds = null;<BR>&nbsp;&nbsp; try{<BR>&nbsp;&nbsp;&nbsp;&nbsp; Context initCtx = new InitialContext();<BR>&nbsp;&nbsp;&nbsp;&nbsp; Context envCtx = (Context) initCtx.lookup("java:comp/env");<BR>&nbsp;&nbsp;&nbsp;&nbsp; ds = (DataSource)envCtx.lookup("jdbc/myoracle");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(ds!=null){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println("Connection is OK!");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection cn=ds.getConnection();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(cn!=null){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println("cn is Ok!");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Statement stmt = cn.createStatement();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ResultSet rst = stmt.executeQuery("select * from BOOK");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println("&lt;p&gt;rst is Ok!" + rst.next());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(rst.next()){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;out.println("&lt;P&gt;BOOK_CODE:" + rst.getString(1));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cn.close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}else{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println("rst Fail!");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println("Fail!");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }catch(Exception ne){ out.println(ne);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</DIV>
<DIV><BR></DIV>
<DIV></DIV>
<DIV><STRONG>3.2 Statement Pool</STRONG></DIV>
<DIV>普通预编译代码：</DIV>
<DIV style="TEXT-INDENT: 21pt">String&nbsp;strSQL=”select name from items where id=?”;</DIV>
<DIV style="TEXT-INDENT: 21pt">PreparedStatement&nbsp;ps=conn.prepareStatement(strSQL);</DIV>
<DIV style="TEXT-INDENT: 21pt">ps.setString(1, “2”);</DIV>
<DIV style="TEXT-INDENT: 21pt">ResultSet&nbsp;rs=ps.executeQuery();</DIV>
<DIV style="TEXT-INDENT: 21pt">&nbsp;</DIV>
<DIV style="TEXT-INDENT: 21pt">但是PreparedStatement&nbsp;是与特定的Connection关联的，一旦Connection关闭，则相关的PreparedStatement&nbsp;也会关闭。</DIV>
<DIV style="TEXT-INDENT: 21pt">为了创建PreparedStatement 缓冲池，可以在invoke方法中通过sql语句判断池中还有没有可用实例。</DIV>
<DIV>&nbsp;</DIV>
<DIV><STRONG>4. 持久层设计与O/R mapping 技术</STRONG></DIV>
<DIV style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt">1）&nbsp;<SPAN style="BACKGROUND: #d9d9d9">Hernate</SPAN><SPAN style="BACKGROUND: #d9d9d9">：适合对新产品的开发，进行封闭化的设计</SPAN></DIV>
<DIV style="TEXT-INDENT: 21pt">Hibernate&nbsp;2003年被Jboss接管，<SPAN style="FONT-SIZE: 10pt">通过把</SPAN><SPAN style="FONT-SIZE: 10pt">java pojo</SPAN><SPAN style="FONT-SIZE: 10pt">对象</SPAN><SPAN style="FONT-SIZE: 10pt">映射到数据库的</SPAN><SPAN style="FONT-SIZE: 10pt">table</SPAN><SPAN style="FONT-SIZE: 10pt">中，采用了</SPAN><SPAN style="FONT-SIZE: 10pt">xml</SPAN><SPAN style="FONT-SIZE: 10pt">/</SPAN><SPAN style="FONT-SIZE: 10pt">javareflection</SPAN><SPAN style="FONT-SIZE: 10pt">技术等。</SPAN><SPAN style="FONT-SIZE: 10pt">3.0</SPAN><SPAN style="FONT-SIZE: 10pt">提供了对存储过程和手写</SPAN><SPAN style="FONT-SIZE: 10pt">sql</SPAN><SPAN style="FONT-SIZE: 10pt">的支持，本身提供了</SPAN><SPAN style="FONT-SIZE: 10pt">hql</SPAN><SPAN style="FONT-SIZE: 10pt">语言。</SPAN></DIV>
<DIV style="TEXT-INDENT: 20pt"><SPAN style="FONT-SIZE: 10pt">开发所需要的文件：</SPAN></DIV>
<DIV><SPAN style="FONT-SIZE: 10pt">hibernate</SPAN><SPAN style="FONT-SIZE: 10pt">配置文件：</SPAN><SPAN style="FONT-SIZE: 10pt"> hibernate.cfg.xml </SPAN><SPAN style="FONT-SIZE: 10pt">或</SPAN><SPAN style="FONT-SIZE: 10pt"> hibernate.properties</SPAN></DIV>
<DIV><SPAN style="FONT-SIZE: 10pt">hibernate </SPAN><SPAN style="FONT-SIZE: 10pt">映射文件：</SPAN><SPAN style="FONT-SIZE: 10pt"> a.hbm.xml</SPAN></DIV>
<DIV><SPAN style="FONT-SIZE: 10pt">pojo</SPAN><SPAN style="FONT-SIZE: 10pt">类源文件：</SPAN><SPAN style="FONT-SIZE: 10pt"> a.java</SPAN><SPAN style="FONT-SIZE: 10pt">　　</SPAN></DIV>
<DIV style="TEXT-INDENT: 21pt">&nbsp;</DIV>
<DIV><SPAN style="FONT-SIZE: 10pt">导出表与表之间的关系：</SPAN></DIV>
<DIV><SPAN style="FONT-SIZE: 10pt">a. </SPAN><SPAN style="FONT-SIZE: 10pt">从</SPAN><SPAN style="FONT-SIZE: 10pt">java</SPAN><SPAN style="FONT-SIZE: 10pt">对象到</SPAN><SPAN style="FONT-SIZE: 10pt">hbm</SPAN><SPAN style="FONT-SIZE: 10pt">文件：</SPAN><SPAN style="FONT-SIZE: 10pt">xdoclet </SPAN></DIV>
<DIV><SPAN style="FONT-SIZE: 10pt">b. </SPAN><SPAN style="FONT-SIZE: 10pt">从</SPAN><SPAN style="FONT-SIZE: 10pt">hbm</SPAN><SPAN style="FONT-SIZE: 10pt">文件到</SPAN><SPAN style="FONT-SIZE: 10pt">java</SPAN><SPAN style="FONT-SIZE: 10pt">对象：</SPAN><SPAN style="FONT-SIZE: 10pt">hibernate extension </SPAN></DIV>
<DIV><SPAN style="FONT-SIZE: 10pt">c. </SPAN><SPAN style="FONT-SIZE: 10pt">从数据库到</SPAN><SPAN style="FONT-SIZE: 10pt">hbm</SPAN><SPAN style="FONT-SIZE: 10pt">文件：</SPAN><SPAN style="FONT-SIZE: 10pt">middlegen </SPAN></DIV>
<DIV><SPAN style="FONT-SIZE: 10pt">d. </SPAN><SPAN style="FONT-SIZE: 10pt">从</SPAN><SPAN style="FONT-SIZE: 10pt">hbm</SPAN><SPAN style="FONT-SIZE: 10pt">文件到数据库：</SPAN><SPAN style="FONT-SIZE: 10pt">SchemaExport</SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt">2）&nbsp;<SPAN style="BACKGROUND: #d9d9d9">Iatis </SPAN><SPAN style="BACKGROUND: #d9d9d9">：适合对遗留系统的改造和对既有数据库的复用，有很强的灵活性</SPAN></DIV>
<DIV style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt">3）&nbsp;<SPAN style="BACKGROUND: #d9d9d9">Apache OJB</SPAN><SPAN style="BACKGROUND: #d9d9d9">：优势在于对标准的全面支持</SPAN></DIV>
<DIV style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt"><STRONG>4）</STRONG><SPAN style="BACKGROUND: #d9d9d9">EJB</SPAN><SPAN style="BACKGROUND: #d9d9d9">：适合集群服务器，其性能也不象某些人所诟病的那么差劲</SPAN></DIV>
<DIV style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt">5）&nbsp;<SPAN style="BACKGROUND: #d9d9d9">JDO (java data object)</SPAN></DIV>
<DIV style="TEXT-INDENT: 21pt"><SPAN style="COLOR: #333333">设置一个Properties对象，从而获取一个JDO的PersistenceManagerFactory（相当于JDBC连接池中的DataSource），进而获得一个PersistenceManager对象（相当于JDBC中的Connection对象），之后，你可以用这个PersistenceManager对象来增加、更新、删除、查询对象。</SPAN></DIV>
<DIV style="TEXT-INDENT: 21pt"><SPAN style="COLOR: #333333">JDOQL是JDO的查询语言；它有点象SQL，但却是依照Java的语法的。</SPAN></DIV>
<DIV>&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; </DIV>
<DIV><STRONG>5. 基于开源框架的Struts+Spring+Hibernate实现方案</STRONG></DIV>
<DIV><STRONG></STRONG><STRONG></STRONG></DIV>
<DIV>
<DIV style="TEXT-INDENT: 20pt" align=left><SPAN style="FONT-SIZE: 10pt">示例：这是一个</SPAN><SPAN style="FONT-SIZE: 10pt">3</SPAN><SPAN style="FONT-SIZE: 10pt">层架构的</SPAN><SPAN style="FONT-SIZE: 10pt">web </SPAN><SPAN style="FONT-SIZE: 10pt">程序，通过一个</SPAN><SPAN style="FONT-SIZE: 10pt">Action </SPAN><SPAN style="FONT-SIZE: 10pt">来调用业务代理，再通过它来回调</SPAN><SPAN style="FONT-SIZE: 10pt"> DAO</SPAN><SPAN style="FONT-SIZE: 10pt">类。下面的流程图表示了</SPAN><SPAN style="FONT-SIZE: 10pt">MyUsers</SPAN><SPAN style="FONT-SIZE: 10pt">是如何工作的。数字表明了流程的先后顺序，从</SPAN><SPAN style="FONT-SIZE: 10pt">web</SPAN><SPAN style="FONT-SIZE: 10pt">层</SPAN><SPAN style="FONT-SIZE: 10pt">(UserAction)</SPAN><SPAN style="FONT-SIZE: 10pt">到中间层</SPAN><SPAN style="FONT-SIZE: 10pt">(UserManager)</SPAN><SPAN style="FONT-SIZE: 10pt">，再到数据层</SPAN><SPAN style="FONT-SIZE: 10pt">(UserDAO)</SPAN><SPAN style="FONT-SIZE: 10pt">，然后返回。</SPAN></DIV>
<DIV style="TEXT-INDENT: 20pt" align=left><SPAN style="FONT-SIZE: 10pt">Spring</SPAN><SPAN style="FONT-SIZE: 10pt">是</SPAN><SPAN style="FONT-SIZE: 10pt">AOP, UserManager</SPAN><SPAN style="FONT-SIZE: 10pt">和</SPAN><SPAN style="FONT-SIZE: 10pt">UserDAO</SPAN><SPAN style="FONT-SIZE: 10pt">都是接口</SPAN><SPAN style="FONT-SIZE: 10pt">.</SPAN></DIV>
<DIV style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left" align=left><SPAN style="FONT-SIZE: 10pt">1)<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-SIZE: 10pt">web</SPAN><SPAN style="FONT-SIZE: 10pt">层</SPAN><SPAN style="FONT-SIZE: 10pt">(UserAction) </SPAN><SPAN style="FONT-SIZE: 10pt">：调用中间层的接口方法，将</SPAN><SPAN style="FONT-SIZE: 10pt">UserManager</SPAN><SPAN style="FONT-SIZE: 10pt">作为属性注入。</SPAN></DIV>
<DIV style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left" align=left><SPAN style="FONT-SIZE: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 采用流行的Struts框架，虽然有很多人不屑一顾，但是这项技术在业界用的比较普遍，能满足基本的功能，可以减少培训学习成本。</SPAN></DIV>
<DIV style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left" align=left><SPAN style="FONT-SIZE: 10pt"></SPAN></DIV>
<DIV style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black">2)<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-SIZE: 10pt">中间层</SPAN><SPAN style="FONT-SIZE: 10pt">(UserManager)</SPAN><SPAN style="FONT-SIZE: 10pt">：将</SPAN><SPAN style="FONT-SIZE: 10pt">UserDAO</SPAN><SPAN style="FONT-SIZE: 10pt">作为属性注入，其实现主要是调用数据层接口的一些方法；</SPAN><SPAN style="FONT-SIZE: 10pt">它处于事务控制中。</SPAN></DIV>
<DIV style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left" align=left><SPAN style="FONT-SIZE: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 采用Spring框架实现，IOC与AOP是它的代名词，功能齐全，非常棒的一个架构。</SPAN></DIV>
<DIV style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left" align=left><SPAN style="FONT-SIZE: 10pt"></SPAN></DIV>
<DIV style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black">3)<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-SIZE: 10pt">数据层</SPAN><SPAN style="FONT-SIZE: 10pt">(UserDAO)</SPAN><SPAN style="FONT-SIZE: 10pt">：实现类继承</SPAN><SPAN style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black">HibernateDaoSupport</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black">类，在该类中可以调用</SPAN><SPAN style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black">getHibernateTemplate()</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black">的一些方法执行具体的数据操作。</SPAN></DIV>
<DIV style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left" align=left><SPAN style="FONT-SIZE: 10pt; COLOR: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 采用Hibernate做O/R mapping，从种种迹象可以看出，Hibernate就是EJB3.0的beta版。</SPAN></DIV></DIV></SPAN><img src ="http://www.blogjava.net/SIDNEY/aggbug/29200.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-01-25 15:00 <a href="http://www.blogjava.net/SIDNEY/archive/2006/01/25/29200.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Difference requestDispatcher.forward and response.sendRedirect</title><link>http://www.blogjava.net/SIDNEY/archive/2006/01/22/28958.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Sun, 22 Jan 2006 12:46:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/01/22/28958.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/28958.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/01/22/28958.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/28958.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/28958.html</trackback:ping><description><![CDATA[Difference request.forward() and response.sendRedirect .<BR>Posted by: Kapil Israni on August 24, 2000 in response to Message #2253 1<BR>replies in this thread<BR>i suppose u r talking bout requestDispatcher.forward() here.<BR><BR>well basically both method calls redirect u to new resource/page/servlet.<BR><BR>the difference between the two is that sendRedirect always sends a header<BR>back to the client/browser. this header then contains the<BR>resource(page/servlet) which u wanted to be redirected. the browser uses<BR>this header to make another fresh request. thus sendRedirect has a overhead<BR>as to the extra remort trip being incurred. its like any other Http request<BR>being generated by ur browser. the advantage is that u can point to any<BR>resource(whether on the same domain or some other domain). for eg if<BR>sendRedirect was called at www.mydomain.com then it can also be used to<BR>redirect a call to a resource on www.theserverside.com.<BR><BR>where as in case of forward() call, the above is not true. resources from<BR>the server, where the fwd. call was made, can only be requested for. but<BR>the major diff between the two is that forward just routes the request to<BR>the new resources which u specify in ur forward call. that means this route<BR>is made by the servlet engine at the server level only. no headers r sent<BR>to the browser which makes this very eficient. also the request and<BR>response objects remain the same both from where the forward call was made<BR>and the resource which was called.<BR><BR>i hope i have hit ur question right.<BR><BR><BR><BR>选择自 <A id=ArticleTitle1_ArticleTitle1_AuthorLink href="http://dev.csdn.net/user/Killvin">Killvin</A> 的 Blog <img src ="http://www.blogjava.net/SIDNEY/aggbug/28958.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-01-22 20:46 <a href="http://www.blogjava.net/SIDNEY/archive/2006/01/22/28958.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AJAX忧虑与启发：成也脚本，败也脚本</title><link>http://www.blogjava.net/SIDNEY/archive/2006/01/22/28957.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Sun, 22 Jan 2006 12:38:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/01/22/28957.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/28957.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/01/22/28957.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/28957.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/28957.html</trackback:ping><description><![CDATA[来自天极<BR><BR>对Ajax的研究有了一段时间了，从最初的远观，到近看，再到实际动手实现，认识越来越深，想法也越来越多。特别是曾经有一阵子跑去研究web2.0，更是体会到Ajax背后的伟大，暗自为其庆幸，也越来越看好Web。
<P>　　不过Ajax在我心中却有些怎么也摆脱不了的阴影。</P>
<P>　　忽如一夜春风来，Ajax就这么很突兀的就突然流行起来。同时流行的还有Web2.0，这些词汇现在都无比的有鼓动力，任何事物，只要沾上这两者的边，便变得神秘无比，无法遏制。</P>
<P>　　但也有人说Ajax是噱头，因为他是新瓶装旧酒。</P>
<P>　　其实Ajax之所以风行，就在于它新瓶装旧酒。Ajax所代表的3个概念，异步、Javascript、XML，应该说都不是新东西。</P>
<P>　　异步？在操作系统中我们早已经学过，那时的名字叫多线程。</P>
<P>　　Javascript？想当年的DHTML他就已经红遍大江南北。</P>
<P>　　XML？瞧瞧那些名词，SOAP、RSS、WAP等，这些名词哪个离开得了XML?</P>
<P>　　这些名词结合在一起之所以产生强大的力量，就在于他们的设计不同，而隐藏在设计背后的思想不同。</P>
<P>　　而这些名词之所以可以红火，就在于他们本身已经应用非常普遍，已经深入到世界中的每个角落。</P>
<P>　　即便是Ajax中稍微新鲜点的XMLHttpRequest，之前也不是没有替代品。IFrame时代我们就已经实现了同样的功能，只是XMLHttpRequest可以比我们做的更好，帮助我们做的更多而已。</P>
<P>　　Javascript是将Ajax所有技术糅合在一起的黏着剂。所谓的Ajax应用程序，其实就是一个运行在客户端浏览器环境中的应用程序。这个应用程序通过DOM操作HTML将信息展示给用户，通过事件机制相应用户操作，通过XMLHttpRequest与服务器沟通，使用的协议是HTTP，数据的载体是XML，而这个应用程序就是由Javascript构成的。</P>
<P>　　Javascript是一种非常强大的语言，换句术语，是通用语言(general language)。Javascript有很多方便的并且强大的特性，使得我们可以开发功能丰富的产品。不过Javascript是脚本，还是脚本，这是他永远逃不开的厄运。</P>
<P>　　脚本有很多的问题，比如本身不够严格，执行缓慢的特点等，这里只讨论一下代码重用问题。</P>
<P>　　当应用越来越复杂，代码越来越多时，代码重用就会变得很重要。最低级的代码重用就是源代码级的代码重用，灵活，但却代价很高。比较先进的平台，比如java和.net都已经提供了更高级的代码重用，中间代码级的，甚至目标代码级的。甚至，在.net平台，按照微软的伟大设想，不同语言的代码都可以统一起来，一起运行。可想而知，这会为.net平台带来多大的战斗力。不同语言，不同的平台的代码都可以在这里施展拳脚。整合是现在的主旋律，.net有着更美好的未来(按照设想)。</P>
<P>　　相比之下，作为脚本的Javascript这方面就要差距好多。在我们之前应用程序规模不大时，没有人会在意。但是，当我们实现大量的Ajax应用时，当我们逐渐丰富我们的客户端时，我们就会发现Javascript的硬伤，也就是脚本的硬伤。当然，我们可以改造Javascript，让他适应我们的需求，但是那时，你会突然发现，Javascript(如果那个时候还叫这个名字的话)已经不再是脚本了。</P>
<P>　　换句话说，脚本的特点就是灵活，所以它是用来处理一些灵活，但是开发成本低的情况。而传统的程序语言比较严格，开发成本高，但是他的运行和维护成本会低。 于是，当我们意识到Ajax背后是一种客户段能力的提高，服务器端相应功能向客户端转移之时，我们便不得不重新审视一下Javascript在其中的尴尬位置。Javascript之所以在Ajax应用中如此受宠，便在于它的灵活。灵活的Javascript获得大众的喜爱，逐渐成为标准。Ajax采用Javascript才能迅速的得以应用，成为今天的宠儿。反过来说，正式因为Javascript的灵活，决定它注定无法大型化，也就决定了Ajax的明天不会乐观。(如果他还依靠Javascript，还叫Ajax，而不是AC(#)ax的话。)</P>
<P>　　看看Ajax背后的竞争者，micromedia的flash，java的web start，甚至.net都有可能成为他的强大敌人。微软在宣传它下一代操作系统的时候，着重讲到了他的表现层。想象一下，当所有的IE都支持微软最新的表现层技术时，谁还用Javascript?谁还用Ajax?</P>
<P>　　不过即使Ajax倒下，不过不要紧，它本身就是一个过渡性技术。不过，Ajax所要做的，就是给我们洗脑：</P>
<P>　　Ajax告诉我们，重视脚本，因为他们灵活。</P>
<P>　　Ajax告诉我们，重视用户，因为他们掏钱。</P>
<P>　　Ajax告诉我们，重视交互，因为软件就是服务。</P>
<P>　　Ajax告诉我们，重视Web，因为方便比什么都重要。</P>
<P>　　Ajax告诉我们，摘下眼罩，换种方式思考问题吧。当你背过脸无视世界的变化时，是世界抛弃了你，而不是你以为的掩耳盗铃。</P><img src ="http://www.blogjava.net/SIDNEY/aggbug/28957.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-01-22 20:38 <a href="http://www.blogjava.net/SIDNEY/archive/2006/01/22/28957.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Log4j基本使用方法</title><link>http://www.blogjava.net/SIDNEY/archive/2006/01/18/28417.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Wed, 18 Jan 2006 01:23:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/01/18/28417.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/28417.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/01/18/28417.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/28417.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/28417.html</trackback:ping><description><![CDATA[<TABLE style="WORD-BREAK: break-all" cellSpacing=0 cellPadding=0 width=700 align=center border=0>
<TBODY>
<TR>
<TD align=middle height=25><FONT face=黑体 size=4></FONT></TD></TR>
<TR bgColor=#f9f9f9>
<TD id=fontzoom style="LINE-HEIGHT: 200%">
<P>　　Log4j由三个重要的组件构成：日志信息的优先级，日志信息的输出目的地，日志信息的输出格式。日志信息的优先级从高到低有ERROR、WARN、INFO、DEBUG，分别用来指定这条日志信息的重要程度；日志信息的输出目的地指定了日志将打印到控制台还是文件中；而输出格式则控制了日志信息的显示内容。</P>
<P>　　<STRONG>一、定义配置文件</STRONG></P>
<P>　　其实您也可以完全不使用配置文件，而是在代码中配置Log4j环境。但是，使用配置文件将使您的应用程序更加灵活。Log4j支持两种配置文件格式，一种是XML格式的文件，一种是Java特性文件（键=值）。下面我们介绍使用Java特性文件做为配置文件的方法：</P>
<P>　　1.配置根Logger，其语法为：</P>
<P>　　log4j.rootLogger = [ level ] , appenderName, appenderName, … </P>
<P>　　其中，level 是日志记录的优先级，分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。Log4j建议只使用四个级别，优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别，您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定义了INFO级别，则应用程序中所有DEBUG级别的日志信息将不被打印出来。 appenderName就是指定日志信息输出到哪个地方。您可以同时指定多个输出目的地。 </P>
<P>　　2.配置日志信息输出目的地Appender，其语法为：</P>
<P>　　log4j.appender.appenderName = fully.qualified.name.of.appender.class <BR>　　log4j.appender.appenderName.option1 = value1 <BR>　　… <BR>　　log4j.appender.appenderName.option = valueN </P>
<P>　　其中，Log4j提供的appender有以下几种： <BR>　　org.apache.log4j.ConsoleAppender（控制台）， <BR>　　org.apache.log4j.FileAppender（文件）， <BR>　　org.apache.log4j.DailyRollingFileAppender（每天产生一个日志文件），<BR>　　org.apache.log4j.RollingFileAppender（文件大小到达指定尺寸的时候产生一个新的文件）， <BR>　　org.apache.log4j.WriterAppender（将日志信息以流格式发送到任意指定的地方） </P>
<P>　　3.配置日志信息的格式（布局），其语法为：</P>
<P>　　log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class <BR>　　log4j.appender.appenderName.layout.option1 = value1 <BR>　　… <BR>　　log4j.appender.appenderName.layout.option = valueN </P>
<P>　　其中，Log4j提供的layout有以下几种： <BR>　　org.apache.log4j.HTMLLayout（以HTML表格形式布局）， <BR>　　org.apache.log4j.PatternLayout（可以灵活地指定布局模式）， <BR>　　org.apache.log4j.SimpleLayout（包含日志信息的级别和信息字符串）， <BR>　　org.apache.log4j.TTCCLayout（包含日志产生的时间、线程、类别等等信息） </P>
<P>　　Log4J采用类似C语言中的printf函数的打印格式格式化日志信息，打印参数如下： %m 输出代码中指定的消息</P>
<P>　　%p 输出优先级，即DEBUG，INFO，WARN，ERROR，FATAL <BR>　　%r 输出自应用启动到输出该log信息耗费的毫秒数 <BR>　　%c 输出所属的类目，通常就是所在类的全名 <BR>　　%t 输出产生该日志事件的线程名 <BR>　　%n 输出一个回车换行符，Windows平台为“\r\n”，Unix平台为“\n” <BR>　　%d 输出日志时间点的日期或时间，默认格式为ISO8601，也可以在其后指定格式，比如：%d{yyy MMM dd HH:mm:ss,SSS}，输出类似：2002年10月18日 22：10：28，921 <BR>　　%l 输出日志事件的发生位置，包括类目名、发生的线程，以及在代码中的行数。举例：Testlog4.main(TestLog4.java:10) </P>
<P>　　<STRONG>二、在代码中使用Log4j</STRONG> </P>
<P>　　1.得到记录器</P>
<P>　　使用Log4j，第一步就是获取日志记录器，这个记录器将负责控制日志信息。其语法为： </P>
<P>　　public static Logger getLogger( String name) </P>
<P>　　通过指定的名字获得记录器，如果必要的话，则为这个名字创建一个新的记录器。Name一般取本类的名字，比如： </P>
<P>　　static Logger logger = Logger.getLogger ( ServerWithLog4j.class.getName () )</P>
<P>　　2.读取配置文件 </P>
<P>　　当获得了日志记录器之后，第二步将配置Log4j环境，其语法为：</P>
<P>　　BasicConfigurator.configure ()： 自动快速地使用缺省Log4j环境。<BR>　　PropertyConfigurator.configure ( String configFilename) ：读取使用Java的特性文件编写的配置文件。<BR>　　DOMConfigurator.configure ( String filename ) ：读取XML形式的配置文件。</P>
<P>　　3.插入记录信息（格式化日志信息）</P>
<P>　　当上两个必要步骤执行完毕，您就可以轻松地使用不同优先级别的日志记录语句插入到您想记录日志的任何地方，其语法如下：</P>
<P>　　Logger.debug ( Object message ) ;<BR>　　Logger.info ( Object message ) ;<BR>　　Logger.warn ( Object message ) ;<BR>　　Logger.error ( Object message ) ;</P></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/SIDNEY/aggbug/28417.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-01-18 09:23 <a href="http://www.blogjava.net/SIDNEY/archive/2006/01/18/28417.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>HttpSessionBindingListener</title><link>http://www.blogjava.net/SIDNEY/archive/2006/01/16/28159.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Mon, 16 Jan 2006 01:49:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/01/16/28159.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/28159.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/01/16/28159.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/28159.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/28159.html</trackback:ping><description><![CDATA[<P>HttpSessionBindingListener接口有两方需要实现的方法:<BR>public synchronized void valueBound(HttpSessionBindingEvent httpsessionbindingevent)<BR>public synchronized void valueUnbound(HttpSessionBindingEvent httpsessionbindingevent)</P>
<P>Session创建的时候Servlet容器将会调用valueBound方法;Session删除的时候则调用valueUnbound方法.</P>
<P>具体应用可以跟踪每个在登录用户,记录相关的信息,以及在其超时的时候及时的删除相关的信息.</P>
<P>实例代码如下:<BR>import org.apache.commons.logging.Log;<BR>import org.apache.commons.logging.LogFactory;<BR>....<BR>....<BR>public synchronized void valueBound(HttpSessionBindingEvent httpsessionbindingevent){<BR>//检查是否有效<BR>if(!Valid()) return;<BR>//检查信息是否已经存在.不存在则添加.</P>
<P>if(Info.online.containsKey(m_userId))<BR>{<BR>//记录日志信息<BR>log.info("initial user context....");<BR>UserOnlineStruct UOS = (UserOnlineStruct)Info.online.get(m_userId);<BR>UOS.loginIp = uos.loginIp;<BR>UOS.loginTime = uos.loginTime;<BR>UOS.sessionId = uos.sessionId;<BR>}<BR>else{<BR>Info.online.put(m_userId, uos);<BR>}<BR>}<BR><BR>public synchronized void valueUnbound(HttpSessionBindingEvent httpsessionbindingevent){<BR>//检查是否有效<BR>if(!Valid()) return;<BR>//删除用户相关信息<BR>//记录日志信息<BR>log.info("destory user context....");<BR>Info.online.remove(m_userId);<BR>}</P><img src ="http://www.blogjava.net/SIDNEY/aggbug/28159.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-01-16 09:49 <a href="http://www.blogjava.net/SIDNEY/archive/2006/01/16/28159.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OScache的安装与配置 </title><link>http://www.blogjava.net/SIDNEY/archive/2006/01/12/27785.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Thu, 12 Jan 2006 08:52:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/01/12/27785.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/27785.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/01/12/27785.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/27785.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/27785.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1 环境要求&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OSCache2.2要求JDK1.4和 Servlet 2.3。2 安装&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （1）从http://www.opensymphony.com/oscache/下载合适的OSCache版本，当前是oscache-2.0.2-...&nbsp;&nbsp;<a href='http://www.blogjava.net/SIDNEY/archive/2006/01/12/27785.html'>阅读全文</a><img src ="http://www.blogjava.net/SIDNEY/aggbug/27785.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-01-12 16:52 <a href="http://www.blogjava.net/SIDNEY/archive/2006/01/12/27785.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于OSCache的页面缓存</title><link>http://www.blogjava.net/SIDNEY/archive/2006/01/12/27783.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Thu, 12 Jan 2006 08:50:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2006/01/12/27783.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/27783.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2006/01/12/27783.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/27783.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/27783.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;一、缓存整个页面&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在OSCache组件中提供了一个CacheFilter用于实现页面级的缓存，主要用于对web应用中的某些动态页面进行缓存，尤其是那些需要生成PDF格式文件/报表、图片文件等的页面，不仅减少了数据库的交互、减少数据库服务器的压力，而且对于减少web服务器的性能消耗有很显著的效果。这种...&nbsp;&nbsp;<a href='http://www.blogjava.net/SIDNEY/archive/2006/01/12/27783.html'>阅读全文</a><img src ="http://www.blogjava.net/SIDNEY/aggbug/27783.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2006-01-12 16:50 <a href="http://www.blogjava.net/SIDNEY/archive/2006/01/12/27783.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据导出成EXCEL</title><link>http://www.blogjava.net/SIDNEY/archive/2005/12/29/25890.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Thu, 29 Dec 2005 07:40:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2005/12/29/25890.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/25890.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2005/12/29/25890.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/25890.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/25890.html</trackback:ping><description><![CDATA[调用：<BR>//写入EXCEL表格<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String fileName = "";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fileName=dtPart+".xls";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File fs = new File("E:\\ITFI_SELSTK\\app\\webapp\\excel\\");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String[] fns=fs.list();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean exist = false;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(fns!=null&amp;&amp;fns.length&gt;0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;fns.length;i++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(fns[i].equals(fileName))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exist = true;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(exist==false||fns.length&lt;=0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //取出股票策略<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String sql = "select a.sec_cd,b.sel_snm from (select distinct sec_cd,ind_id from cd_10_ind.dbo.ind_s_model_sel where pub_dt=convert(char(10),getdate(),120)) as a,AUTO_SEL_CLS b where a.ind_id=b.sel_cd ";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DatabaseOperate opcl = new DatabaseOperate("jdbc_sel_stk", DatabaseOperate.OP_QUERY, sql, request);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String[][] indnms = opcl.execute();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int m=0;m&lt;totalb1Stks.length;m++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int n=0;n&lt;indnms.length;n++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(totalb1Stks[m][0].trim().equals(indnms[n][0].trim()))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; totalb1Stks[m][28]+=indnms[n][1]+",";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File f = new File("E:\\ITFI_SELSTK\\app\\webapp\\excel\\"+fileName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f.createNewFile();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeExcel(new FileOutputStream(f),totalb1Stks);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; //end write excel ===========<BR>----------------------------------------------------------------------------------------<BR>public static void writeExcel(OutputStream os,String[][] smsInfo) throws Exception {<BR>&nbsp;&nbsp;jxl.write.WritableWorkbook wwb = Workbook.createWorkbook(os);<BR>&nbsp;&nbsp;jxl.write.WritableSheet ws = wwb.createSheet("Sheet1", 0);<BR>&nbsp;&nbsp;//控制显示格式<BR>&nbsp;&nbsp;jxl.write.WritableFont wfc =<BR>&nbsp;&nbsp;&nbsp;new jxl.write.WritableFont(<BR>&nbsp;&nbsp;&nbsp;&nbsp;WritableFont.ARIAL,<BR>&nbsp;&nbsp;&nbsp;&nbsp;10,<BR>&nbsp;&nbsp;&nbsp;&nbsp;WritableFont.BOLD,<BR>&nbsp;&nbsp;&nbsp;&nbsp;false,<BR>&nbsp;&nbsp;&nbsp;&nbsp;UnderlineStyle.NO_UNDERLINE,<BR>&nbsp;&nbsp;&nbsp;&nbsp;jxl.format.Colour.GREEN);<BR>&nbsp;&nbsp;//jxl.write.WritableCellFormat wcfFC = //格式控制<BR>&nbsp;&nbsp;//&nbsp;new jxl.write.WritableCellFormat(wfc);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String[] title = new String[16];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; title[0] = "股票代码";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; title[1] = "股票简称";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; title[2] = "昨收盘";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; title[3] = "EPS05";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; title[4] = "EPS06e";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; title[5] = "评级人数";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; title[6] = "评级系数";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; title[7] = "PE";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; title[8] = "PB";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; title[9] = "PS";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; title[10] = "PE/G";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; title[11] = "ROE";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; title[12] = "毛利率";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; title[13] = "行业";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; title[14] = "策略";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; title[15] = "录入人员";<BR>&nbsp;&nbsp;if(smsInfo!=null)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;int len = smsInfo.length;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //先写入excel表格标题<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jxl.write.Label labelC = new jxl.write.Label(0, 0, title[0]);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ws.addCell(labelC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pjxs="N/A";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int j=1;j&lt;title.length;j++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; labelC = new jxl.write.Label(j, 0, title[j]);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ws.addCell(labelC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;for(int i=0;i&lt;len;i++)<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;labelC = new jxl.write.Label(0, i+1, smsInfo[i][0]);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ws.addCell(labelC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; labelC = new jxl.write.Label(1, i+1, smsInfo[i][1]);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ws.addCell(labelC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; labelC = new jxl.write.Label(2, i+1, StringUtil.getDouble(smsInfo[i][9],2));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ws.addCell(labelC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; labelC = new jxl.write.Label(3, i+1, smsInfo[i][7]);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ws.addCell(labelC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; labelC = new jxl.write.Label(4, i+1, StringUtil.getDouble(smsInfo[i][8],2));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ws.addCell(labelC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; labelC = new jxl.write.Label(5, i+1, smsInfo[i][11]);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ws.addCell(labelC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!StringUtil.getDouble(smsInfo[i][10],2).equals("9.00"))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pjxs = StringUtil.getDouble(smsInfo[i][10],2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; labelC = new jxl.write.Label(6, i+1, pjxs);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ws.addCell(labelC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; labelC = new jxl.write.Label(7, i+1, StringUtil.getDouble(smsInfo[i][23],2));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ws.addCell(labelC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; labelC = new jxl.write.Label(8, i+1, StringUtil.getDouble(smsInfo[i][21],2));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ws.addCell(labelC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; labelC = new jxl.write.Label(9, i+1, smsInfo[i][22]);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ws.addCell(labelC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; labelC = new jxl.write.Label(10, i+1, StringUtil.getDouble(smsInfo[i][25],2));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ws.addCell(labelC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; labelC = new jxl.write.Label(11, i+1, StringUtil.getDouble(smsInfo[i][26],2));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ws.addCell(labelC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; labelC = new jxl.write.Label(12, i+1, StringUtil.getDouble(smsInfo[i][27],2));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ws.addCell(labelC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; labelC = new jxl.write.Label(13, i+1, smsInfo[i][24]);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ws.addCell(labelC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; labelC = new jxl.write.Label(14, i+1, smsInfo[i][28]);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ws.addCell(labelC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; labelC = new jxl.write.Label(15, i+1, smsInfo[i][18]);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ws.addCell(labelC);<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;//写入Exel工作表<BR>&nbsp;&nbsp;wwb.write();<BR>&nbsp;&nbsp;//关闭Excel工作薄对象<BR>&nbsp;&nbsp;wwb.close();<BR>&nbsp;}<BR><BR><BR>参考资料：<BR><A href="http://www-128.ibm.com/developerworks/cn/java/l-javaExcel/index.html">http://www-128.ibm.com/developerworks/cn/java/l-javaExcel/index.html</A><BR><img src ="http://www.blogjava.net/SIDNEY/aggbug/25890.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2005-12-29 15:40 <a href="http://www.blogjava.net/SIDNEY/archive/2005/12/29/25890.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>tomcat 缓存设置</title><link>http://www.blogjava.net/SIDNEY/archive/2005/12/28/25738.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Wed, 28 Dec 2005 08:27:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2005/12/28/25738.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/25738.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2005/12/28/25738.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/25738.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/25738.html</trackback:ping><description><![CDATA[e.g<BR>update file :<BR>\tomcat\bin\catalina.bat<BR>update the line <BR>set JAVA_OPTS=-Xmx256M -Xms64M <BR>means max cache &amp; min cache <img src ="http://www.blogjava.net/SIDNEY/aggbug/25738.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2005-12-28 16:27 <a href="http://www.blogjava.net/SIDNEY/archive/2005/12/28/25738.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>draw pic</title><link>http://www.blogjava.net/SIDNEY/archive/2005/12/28/25734.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Wed, 28 Dec 2005 07:54:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2005/12/28/25734.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/25734.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2005/12/28/25734.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/25734.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/25734.html</trackback:ping><description><![CDATA[<P>public BufferedImage draw()<BR>&nbsp;{<BR>&nbsp;&nbsp;float maxValue = 0;<BR>&nbsp;&nbsp;float minValue = 0;<BR>&nbsp;&nbsp;long maxColumn = 0;<BR>&nbsp;&nbsp;int gridWidth&nbsp; = 0;<BR>&nbsp;&nbsp;int gridHeight = 0;<BR>&nbsp;&nbsp;int beginWidth = 0 ;<BR>&nbsp;&nbsp;String begindate = "" ;</P>
<P>&nbsp;&nbsp;BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);<BR>&nbsp;&nbsp;Graphics2D g = (Graphics2D)bufferedImage.getGraphics();<BR>&nbsp;&nbsp;g.setColor(Color.white);<BR>&nbsp;&nbsp;g.fillRect(0, 0, width, height);<BR>&nbsp;&nbsp;g.setColor(Color.gray);<BR>&nbsp;&nbsp;g.drawRect(0, 0, width-1, height-1);<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;//写出无数据说明文字<BR>&nbsp;&nbsp;ArrayList tempDoc = new ArrayList();&nbsp;<BR>&nbsp; String hText1 = "查询无相关数据,请重新选择查询条件!";<BR>&nbsp; tempDoc.add(hText1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;<BR>&nbsp;&nbsp;//画出提示文字<BR>&nbsp;&nbsp;g.drawString((String)tempDoc.get(0), width - 375&nbsp; , 40 + gridHeight);&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;return bufferedImage;<BR>&nbsp;}</P><img src ="http://www.blogjava.net/SIDNEY/aggbug/25734.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2005-12-28 15:54 <a href="http://www.blogjava.net/SIDNEY/archive/2005/12/28/25734.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java send mail </title><link>http://www.blogjava.net/SIDNEY/archive/2005/12/28/25733.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Wed, 28 Dec 2005 07:49:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2005/12/28/25733.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/25733.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2005/12/28/25733.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/25733.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/25733.html</trackback:ping><description><![CDATA[<P>&lt;%@ page import="java.sql.*" %&gt;<BR>&lt;%@ page import="java.util.*" %&gt;<BR>&lt;%@ page import="com.investoday.database.Database" %&gt;<BR>&lt;%@ page import="com.investoday.util.StringUtil" %&gt;<BR>&lt;%@ page import="com.investoday.util.EmailBean" %&gt;<BR>&lt;%@ page import="java.util.Date" %&gt;<BR>&lt;%@ page import="com.investoday.util.SmtpMail"%&gt;<BR>&lt;%@ page import ="java.io.*"%&gt;<BR>&lt;%@ page import = "java.io.IOException"%&gt;</P>
<P>&lt;%<BR>String guids = request.getParameter("ids");<BR>String[] guid = guids.split(",");</P>
<P>String name = "";//用户姓名<BR>String to = ""; //收件人<BR>String content="";&nbsp; //信件内容<BR>String subject = "邮件主题";<BR>String path="";<BR>String qid = "";<BR>String qno = "";<BR>String month = "";<BR>String month_h = "";<BR>String jobcls = "";//职位分类</P>
<P>String strSql = "";<BR>String str = "";<BR>if(guid!=null&amp;&amp;guid.length&gt;0)<BR>{<BR>&nbsp;&nbsp;&nbsp; for(int i=1;i&lt;guid.length;i++) //批量发送<BR>&nbsp; {<BR>&nbsp;&nbsp;&nbsp; StringBuffer sb = new StringBuffer();<BR>&nbsp;try <BR>&nbsp;{&nbsp;&nbsp; <BR>&nbsp;&nbsp;path=application.getRealPath("sales\\return_wq.htm");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//邮件模版&nbsp; <BR>&nbsp;&nbsp;BufferedReader in = new BufferedReader(new FileReader(path));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;while ((str = in.readLine()) != null) <BR>&nbsp;&nbsp;{ <BR>&nbsp;&nbsp;&nbsp;sb.append(str);<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;content=new String(sb);<BR>&nbsp;&nbsp;in.close();<BR>&nbsp;} <BR>&nbsp;catch (IOException e) <BR>&nbsp;{<BR>&nbsp;&nbsp;e.printStackTrace() ;<BR>&nbsp;}<BR>&nbsp;<BR>&nbsp;content = StringUtil.replace(content,"rp004","替换内容");<BR>&nbsp;//String sFileName = "E:\\crm\\app\\webapp\\sales\\7monthReturn.pdf";//附件<BR>&nbsp;<BR>&nbsp;SmtpMail smtpmail = new SmtpMail();<BR>&nbsp;<BR>&nbsp;smtpmail.setTo(to);&nbsp; //对方地址<BR>&nbsp;smtpmail.setSubject(StringUtil.getGbcode(subject));<BR>&nbsp;smtpmail.setContent(content);//内容<BR>&nbsp;//smtpmail.setFile(sFileName);<BR>&nbsp;smtpmail.sendEmail();//调用方法发送邮件<BR>%&gt;<BR></P><img src ="http://www.blogjava.net/SIDNEY/aggbug/25733.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2005-12-28 15:49 <a href="http://www.blogjava.net/SIDNEY/archive/2005/12/28/25733.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java thread</title><link>http://www.blogjava.net/SIDNEY/archive/2005/12/28/25726.html</link><dc:creator>渠上月</dc:creator><author>渠上月</author><pubDate>Wed, 28 Dec 2005 07:09:00 GMT</pubDate><guid>http://www.blogjava.net/SIDNEY/archive/2005/12/28/25726.html</guid><wfw:comment>http://www.blogjava.net/SIDNEY/comments/25726.html</wfw:comment><comments>http://www.blogjava.net/SIDNEY/archive/2005/12/28/25726.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SIDNEY/comments/commentRss/25726.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SIDNEY/services/trackbacks/25726.html</trackback:ping><description><![CDATA[<P>web.xml </P>
<P>&lt;servlet&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;runthread&lt;/servlet-name&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;servlet-class&gt;com.investoday.servlet.RunThread&lt;/servlet-class&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;load-on-startup&gt;1&lt;/load-on-startup&gt; &lt;!--为1 表示服务启动就自动运行--&gt;<BR>&nbsp; &lt;/servlet&gt;<BR>&nbsp; &lt;servlet-mapping&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;runthread&lt;/servlet-name&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/runthread&lt;/url-pattern&gt;<BR>&nbsp;&lt;/servlet-mapping&gt;</P>
<P>TimeThread.java --线程类<BR>class TimeThread extends Thread<BR>---------------------------------------------------------<BR>public void run()<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;try<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(;;)//无限循环<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// some thing to do <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.sleep(sleepTime);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;} catch(Exception e)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<BR>&nbsp;&nbsp;}</P>
<P>&nbsp;}<BR>----------------------------------------------------------------------------<BR>RunThread.java&nbsp; --调用线程的类<BR>---------------------------------------<BR>package com.investoday.servlet;</P>
<P>import javax.servlet.*;<BR>import javax.servlet.http.*;<BR>import java.io.*;</P>
<P>public class RunThread extends HttpServlet<BR>{<BR>&nbsp;public void service(HttpServletRequest req, HttpServletResponse res) <BR>&nbsp;throws ServletException, IOException<BR>&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;try<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TimeThread td = new TimeThread(1000);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG> td.start(); <BR></STRONG>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;catch(Exception ex)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;ex.printStackTrace();<BR>&nbsp;&nbsp;}<BR>&nbsp;}</P>
<P>&nbsp;&nbsp;&nbsp; public void init(ServletConfig config) throws ServletException<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TimeThread td = new TimeThread(10000);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("to run thread.");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; td.start();//执行 run 方法<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>}</P><img src ="http://www.blogjava.net/SIDNEY/aggbug/25726.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SIDNEY/" target="_blank">渠上月</a> 2005-12-28 15:09 <a href="http://www.blogjava.net/SIDNEY/archive/2005/12/28/25726.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>