﻿<?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-SIMONE-随笔分类-JSP</title><link>http://www.blogjava.net/wangxinsh55/category/9224.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 31 Oct 2014 11:38:47 GMT</lastBuildDate><pubDate>Fri, 31 Oct 2014 11:38:47 GMT</pubDate><ttl>60</ttl><item><title>Spring MVC 教程,快速入门,深入分析</title><link>http://www.blogjava.net/wangxinsh55/archive/2014/10/31/419326.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Fri, 31 Oct 2014 02:33:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2014/10/31/419326.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/419326.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2014/10/31/419326.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/419326.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/419326.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 资源下载： Spring_MVC_教程_快速入门_深入分析V1.1.pdf  SpringMVC核心配置文件示例.rar   &nbsp; &nbsp; 作者：赵磊 博客：http://elf8848.iteye.com &nbsp; 目录    一、前言 二、spring mvc 核心类与接口 三、spring mvc&nbsp;核心流程图  四、spring mvc&nbsp;Dispatch...&nbsp;&nbsp;<a href='http://www.blogjava.net/wangxinsh55/archive/2014/10/31/419326.html'>阅读全文</a><img src ="http://www.blogjava.net/wangxinsh55/aggbug/419326.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2014-10-31 10:33 <a href="http://www.blogjava.net/wangxinsh55/archive/2014/10/31/419326.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Http缓存Last-Modified、ETag和Expires的Java终结解决之道</title><link>http://www.blogjava.net/wangxinsh55/archive/2013/09/26/404500.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Thu, 26 Sep 2013 09:35:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2013/09/26/404500.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/404500.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2013/09/26/404500.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/404500.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/404500.html</trackback:ping><description><![CDATA[<div>http://www.jdon.com/40381</div><br /><br />Last-Modified和Expires针对浏览器，而ETag则与客户端无关，所以可适合<a href="http://www.jdon.com/rest.html" class="hotkeys ajax_query=REST" id="id_http://www.jdon.com/rest.html"><strong>REST</strong></a>架构中。两者都应用在浏览器端的区别是：Expires日期到达前，浏览器不会再发出新的请求，除非用户按浏览器的刷新，所以，Last-Modified和Expires基本是降低浏览器向服务器发出请求的次数，而ETag更侧重客户端和服务器之间联系。<br />
<br />
先谈Last-Modified和Expires，最新的Tomcat 7 将<a href="http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html#Expires_Filter" class="body_href">ExpireFilter</a>加入其容器中，这样，Java WEB也可以象Apache的Mod_expire模块一样对Http头部进行统一设置了，不过它只对响应文档类型进行统一设置判断，如text/html或text/image 或/css等等，如果想对个别URL输出的jsp进行定制就不行，urlrewrite据说是可以，但是要把URL在其配置文件再配置一下，麻烦，一旦jsp改动影响面大，还有一个问题就是web.xml配置了Tomcat 7容器的ExpireFilter，与容器耦合，移植性差(移植到Resin就不行了)。<br />
<br />
所以，我在<a href="http://www.jdon.com/jdonframework/jivejdon3/index.html" class="hotkeys ajax_query=JiveJdon" id="id_http://www.jdon.com/jdonframework/jivejdon3/index.html"><strong>JiveJdon</strong></a> 4.2最新版本中，通过加入下面一段代码在服务器端对来自客户端的Last-Modified以及当前时间进行判断，如未过期，response.setStatus设为304，可以终止后面的各种Jsp界面计算，直接返回浏览器一个304的响应包，JSP页面也不会输出到客户端，将带宽节省给更加需要互动实时性的请求。<br />
<br />
再谈谈ETag，ETag定义：RFC2616(也就是HTTP/1.1)中没有说明ETag该是什么格式的，只要确保用双引号括起来就行了，所以你可以用文件的hash，甚至是直接用Last-Modified，以下是服务器端返回的格式： <br />
ETag: "50b1c1d4f775c61:df3" 客户端向服务端发出的请求：If-None-Match: W/"50b1c1d4f775c61:df3" 这样，在J2EE/JavaEE服务器端，我们判断如果ETag没改变也是返回状态304，起到类似Last-Modified和Expires效果。<br />
<br />
与Last-Modified和Expires区别是：如果过了Expires日期，服务器肯定会再次发出JSP完整响应；或者用户强按浏览器的刷新按钮，服务器也必须响应，apache等静态页面输出也是这样，但是这时动态页面就发挥了作用，如果JSP涉及的业务领域模型还是没有更新，和原来一样，那么就不必再将动态页面输出了(浏览器客户端已有一份)，从Etag中获取上次设置的领域模型对象修改日期，和现在内存中领域模型(In-memory Model)修改日期进行比较，如果修改日期一致，表示领域模型没有被更新过，那么返回响应包304，浏览器将继续用本地<a href="http://www.jdon.com/cache.html" class="hotkeys ajax_query=缓存" id="id_http://www.jdon.com/cache.html"><strong>缓存</strong></a>的该页面，再次节省了带宽传输。<br />
<br />
通过上述Expire和Etag两次<a href="http://www.jdon.com/cache.html" class="hotkeys ajax_query=缓存" id="id_http://www.jdon.com/cache.html"><strong>缓存</strong></a>，可以大大降低服务器的响应负载，如果你的应用不是状态集中并发修改和实时输出，而是分散修改然后分发，如个人空间 个人博客(每个人只是修改它们自己的状态，不影响全局)或QQ类似个人工具，那么采取这样的方法效果非常明显，实际就是一种动态页面静态化技术，但比通常事先进行页面静态化要灵活强大。<br />
<br />
InfoQ的那篇:<a href="http://www.infoq.com/articles/etags" class="body_href">http://www.infoq.com/articles/etags</a>还用MD5计算放入其中，Md5计算稍微复杂点，负载大了点，有的人结合Hibernate或数据库触发器来判断数据库数据是否更新，以决定Etag的更新，这将表现层和持久层耦合在一起，由于<a href="http://www.jdon.com/jdonframework/jivejdon3/index.html" class="hotkeys ajax_query=JiveJdon" id="id_http://www.jdon.com/jdonframework/jivejdon3/index.html"><strong>JiveJdon</strong></a>采取的是MDD/DDD模型驱动架构，表现层的Etag更新是根据中间业务层的模型对象修改日期来决定，不涉及数据库层，而且起到服务器<a href="http://www.jdon.com/cache.html" class="hotkeys ajax_query=缓存" id="id_http://www.jdon.com/cache.html"><strong>缓存</strong></a>的更新和http的Etag更新一致的效果，在松耦合设计和性能上取得综合平衡。<br />
<br />
代码如下:<br />
<table border="0" cellpadding="0" cellspacing="0" width="100%">
     <tbody>
         <tr>
             <td class="code-outline">
             <pre class="displaycode"><br />
             <strong>public</strong> <strong>static</strong> <strong>boolean</strong> checkHeaderCache(<strong>long</strong> adddays, <strong>long</strong> modelLastModifiedDate, HttpServletRequest request, HttpServletResponse response) {<br />
             <font color="#0000aa"><em>// com.jdon.jivejdon.presentation.filter.ExpiresFilter</em></font><font color="black"><br />
             request.setAttribute(</font><font color="#00bb00">"myExpire"</font><font color="black">, adddays);<br />
             <br />
             </font><font color="#0000aa"><em>// convert seconds to ms.</em></font><font color="black"><br />
             <strong>long</strong> adddaysM = adddays * 1000;<br />
             <strong>long</strong> header = request.getDateHeader(</font><font color="#00bb00">"If-Modified-Since"</font><font color="black">);<br />
             <strong>long</strong> now = System.currentTimeMillis();<br />
             <strong>if</strong> (header &gt; 0 &amp;&amp; adddaysM &gt; 0) {<br />
             <strong>if</strong> (modelLastMod<strong>if</strong>iedDate &gt; header) {<br />
             </font><font color="#0000aa"><em>// adddays = 0; // reset</em></font><font color="black"><br />
             response.setStatus(HttpServletResponse.SC_OK);<br />
             <strong>return</strong> <strong>true</strong>;<br />
             }<br />
             <strong>if</strong> (header + adddaysM &gt; now) {<br />
             </font><font color="#0000aa"><em>// during the period happend modified</em></font><font color="black"><br />
             response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);<br />
             <strong>return</strong> false;<br />
             }<br />
             }<br />
             <br />
             </font><font color="#0000aa"><em>// if over expire data, see the Etags;</em></font><font color="black"><br />
             </font><font color="#0000aa"><em>// ETags if ETags no any modified</em></font><font color="black"><br />
             String previousToken = request.getHeader(</font><font color="#00bb00">"If-None-Match"</font><font color="black">);<br />
             <strong>if</strong> (previousToken != <strong>null</strong> &amp;&amp; previousToken.equals(Long.toString(modelLastMod<strong>if</strong>iedDate))) {<br />
             </font><font color="#0000aa"><em>// not modified</em></font><font color="black"><br />
             response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);<br />
             <strong>return</strong> false;<br />
             }<br />
             </font><font color="#0000aa"><em>// if th model has modified , setup the new modified date</em></font><font color="black"><br />
             response.setHeader(</font><font color="#00bb00">"ETag"</font><font color="black">, Long.toString(modelLastModifiedDate));<br />
             setRespHeaderCache(adddays, request, response);<br />
             <strong>return</strong> <strong>true</strong>;<br />
             <br />
             }<br />
             <br />
             <strong>public</strong> <strong>static</strong> <strong>boolean</strong> setRespHeaderCache(<strong>long</strong> adddays, HttpServletRequest request, HttpServletResponse response) {<br />
             request.setAttribute(</font><font color="#00bb00">"myExpire"</font><font color="black">, adddays);<br />
             <br />
             <strong>long</strong> adddaysM = adddays * 1000;<br />
             String maxAgeDirective = </font><font color="#00bb00">"max-age="</font><font color="black"> + adddays;<br />
             response.setHeader(</font><font color="#00bb00">"Cache-Control"</font><font color="black">, maxAgeDirective);<br />
             response.setStatus(HttpServletResponse.SC_OK);<br />
             response.addDateHeader(</font><font color="#00bb00">"Last-Modified"</font><font color="black">, System.currentTimeMillis());<br />
             response.addDateHeader(</font><font color="#00bb00">"Expires"</font><font color="black">, System.currentTimeMillis() + adddaysM);<br />
             <strong>return</strong> <strong>true</strong>;<br />
             }<br />
             </font></pre>
             </td>
         </tr>
     </tbody>
</table>
<br />
<br />
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/404500.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2013-09-26 17:35 <a href="http://www.blogjava.net/wangxinsh55/archive/2013/09/26/404500.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring的注入方法小结</title><link>http://www.blogjava.net/wangxinsh55/archive/2011/10/17/361409.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Mon, 17 Oct 2011 03:28:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2011/10/17/361409.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/361409.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2011/10/17/361409.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/361409.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/361409.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1.setter注入: beans.xml: &nbsp; &lt;?xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"?&gt;  &lt;!-- &nbsp;&nbsp;-&nbsp;Application&nbsp;context&nbsp;definition&nbsp;for&nbsp;JPetStore's&nbsp;business&nbsp;l...&nbsp;&nbsp;<a href='http://www.blogjava.net/wangxinsh55/archive/2011/10/17/361409.html'>阅读全文</a><img src ="http://www.blogjava.net/wangxinsh55/aggbug/361409.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2011-10-17 11:28 <a href="http://www.blogjava.net/wangxinsh55/archive/2011/10/17/361409.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>根据静态类生成自定义JSTL标签TDL</title><link>http://www.blogjava.net/wangxinsh55/archive/2011/10/14/361283.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Fri, 14 Oct 2011 07:01:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2011/10/14/361283.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/361283.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2011/10/14/361283.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/361283.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/361283.html</trackback:ping><description><![CDATA[<div>public static String parseTLD(Class cls) {<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;StringBuilder sb = new StringBuilder();<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Method methods[] = cls.getMethods();<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for (Method m : methods) {<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if ("Object".equals(m.getDeclaringClass().getSimpleName())<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;|| (m.getModifiers() != (Modifier.PUBLIC | Modifier.STATIC))) {<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;continue;<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;String s = "&lt;function&gt;\r\n";<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;s += "\t&lt;name&gt;" + m.getName();<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Class[] cs = m.getParameterTypes();<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;String n = "", p = "";<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for (Class c : cs) {<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;String sn = c.getSimpleName();<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (sn.indexOf("[]") != -1) {<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;n += sn.toLowerCase().substring(0, 1) + "x";<br />&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;n += sn.toLowerCase().substring(0, 1);<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;p += c.getCanonicalName() + ",";<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (p.length() &gt; 1) {<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;n = "_" + n;<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;p = p.substring(0, p.length() - 1);<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;s += n + "&lt;/name&gt;\r\n";<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;s += "\t&lt;function-class&gt;" + m.getDeclaringClass().getName() + "&lt;/function-class&gt;\r\n";<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;s += "\t&lt;function-signature&gt;" + m.getReturnType().getCanonicalName() + " " + m.getName() + "(" + p + ")"<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;+ "&lt;/function-signature&gt;\r\n";<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;s += "&lt;/function&gt;";<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;sb.append(s);<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return sb.toString();<br />&nbsp;&nbsp; &nbsp;}</div><img src ="http://www.blogjava.net/wangxinsh55/aggbug/361283.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2011-10-14 15:01 <a href="http://www.blogjava.net/wangxinsh55/archive/2011/10/14/361283.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DBCP的配置参数</title><link>http://www.blogjava.net/wangxinsh55/archive/2011/04/14/348277.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Thu, 14 Apr 2011 02:58:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2011/04/14/348277.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/348277.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2011/04/14/348277.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/348277.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/348277.html</trackback:ping><description><![CDATA[<p>tomcatde DHCP的配置<br />
&lt;Resource driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver" <br />
logAbandoned="true" maxActive="20" maxIdle="2" maxWait="5000" name="system" <br />
removeAbandonedTimeout="60" removeAbandoned="true" <br />
password="xx" type="javax.sql.DataSource"<br />
url="jdbc:sqlserver://127.0.0.1:1433;DatabaseName=base" <br />
username="sa"/&gt;<br />
当中的<br />
logAbandoned="true"&nbsp; removeAbandoned="true" removeAbandonedTimeout="60"<br />
就是用来配置数据库断开后自动连接的。</p>
<p><br />
数据库连接池会在启动时就建立所需的若干连接，并一直保持连接状态，<br />
但是当数据库服务停止后，这些连接就被外部因素给中断了<br />
网上优化了的配置信息：<br />
&lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"&gt;&nbsp; <br />
&lt;property name="driverClassName" value="${db.driverClassName}"/&gt;&nbsp; <br />
&lt;property name="url" value="${db.url}"/&gt;&nbsp; <br />
&lt;property name="username" value="${db.username}"/&gt;&nbsp; <br />
&lt;property name="password" value="${db.password}"/&gt;&nbsp; <br />
&lt;!--initialSize: 初始化连接--&gt;&nbsp; <br />
&lt;property name="initialSize" value="5"/&gt;&nbsp; <br />
&lt;!--maxIdle: 最大空闲连接--&gt;&nbsp; <br />
&lt;property name="maxIdle" value="10"/&gt;&nbsp; <br />
&lt;!--minIdle: 最小空闲连接--&gt;&nbsp; <br />
&lt;property name="minIdle" value="5"/&gt;&nbsp; <br />
&lt;!--maxActive: 最大连接数量--&gt;&nbsp; <br />
&lt;property name="maxActive" value="15"/&gt;&nbsp; <br />
&lt;!--removeAbandoned: 是否自动回收超时连接--&gt;&nbsp; <br />
&lt;property name="removeAbandoned" value="true"/&gt;&nbsp; <br />
&lt;!--removeAbandonedTimeout: 超时时间(以秒数为单位)--&gt;&nbsp; <br />
&lt;property name="removeAbandonedTimeout" value="180"/&gt;&nbsp; <br />
&lt;!--maxWait: 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒--&gt;&nbsp; <br />
&lt;property name="maxWait" value="3000"/&gt;&nbsp; <br />
&lt;property name="validationQuery"&gt;&nbsp; <br />
&lt;value&gt;SELECT 1&lt;/value&gt;&nbsp; <br />
&lt;/property&gt;&nbsp; <br />
&lt;property name="testOnBorrow"&gt;&nbsp; <br />
&lt;value&gt;true&lt;/value&gt;&nbsp; <br />
&lt;/property&gt;&nbsp; <br />
&lt;/bean&gt;&nbsp;&nbsp; </p>
<p>dbcp配置中文版本，自apache 官方文档<br />
原文请见http://commons.apache.org/dbcp/configuration.html。</p>
<p>参数 &nbsp;描述<br />
username &nbsp;传递给JDBC驱动的用于建立连接的用户名<br />
password &nbsp;传递给JDBC驱动的用于建立连接的密码<br />
url &nbsp;传递给JDBC驱动的用于建立连接的URL<br />
driverClassName &nbsp;使用的JDBC驱动的完整有效的java 类名<br />
connectionProperties &nbsp;当建立新连接时被发送给JDBC驱动的连接参数，<br />
格式必须是 [propertyName=property;]*<br />
注意 ：参数user/password将被明确传递，所以不需要包括在这里。</p>
<p>参数 &nbsp;默认值 &nbsp;描述<br />
defaultAutoCommit &nbsp;true &nbsp;连接池创建的连接的默认的auto-commit状态<br />
defaultReadOnly &nbsp;driver default &nbsp;连接池创建的连接的默认的read-only状态. <br />
如果没有设置则setReadOnly方法将不会被调用. (某些驱动不支持只读模式,比如:Informix)<br />
defaultTransactionIsolation &nbsp;driver default &nbsp;连接池创建的连接的默认的TransactionIsolation状态. <br />
下面列表当中的某一个: (参考javadoc)</p>
<p>&nbsp;&nbsp;&nbsp; * NONE<br />
&nbsp;&nbsp;&nbsp; * READ_COMMITTED<br />
&nbsp;&nbsp;&nbsp; * READ_UNCOMMITTED<br />
&nbsp;&nbsp;&nbsp; * REPEATABLE_READ<br />
&nbsp;&nbsp;&nbsp; * SERIALIZABLE</p>
<p>defaultCatalog &nbsp;&nbsp;连接池创建的连接的默认的catalog</p>
<p>参数 &nbsp;默认值 &nbsp;描述<br />
initialSize &nbsp;0 &nbsp;初始化连接:连接池启动时创建的初始化连接数量,1.2版本后支持<br />
maxActive &nbsp;8 &nbsp;最大活动连接:连接池在同一时间能够分配的最大活动连接的数量, <br />
如果设置为非正数则表示不限制<br />
maxIdle &nbsp;8 &nbsp;最大空闲连接:连接池中容许保持空闲状态的最大连接数量,超过的空闲连接将被释放,<br />
如果设置为负数表示不限制<br />
minIdle &nbsp;0 &nbsp;最小空闲连接:连接池中容许保持空闲状态的最小连接数量,低于这个数量将创建新的连接,<br />
如果设置为0则不创建<br />
maxWait &nbsp;无限 &nbsp;最大等待时间:当没有可用连接时,连接池等待连接被归还的最大时间(以毫秒计数),<br />
超过时间则抛出异常,如果设置为-1表示无限等待</p>
<p>参数 &nbsp;默认值 &nbsp;描述<br />
validationQuery &nbsp;&nbsp;SQL查询,用来验证从连接池取出的连接,在将连接返回给调用者之前.如果指定,<br />
则查询必须是一个SQL SELECT并且必须返回至少一行记录<br />
testOnBorrow &nbsp;true &nbsp;指明是否在从池中取出连接前进行检验,如果检验失败,<br />
则从池中去除连接并尝试取出另一个.<br />
注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串<br />
testOnReturn &nbsp;false &nbsp;指明是否在归还到池中前进行检验<br />
注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串<br />
testWhileIdle &nbsp;false &nbsp;指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,<br />
则连接将被从池中去除.<br />
注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串<br />
timeBetweenEvictionRunsMillis &nbsp;-1 &nbsp;在空闲连接回收器线程运行期间休眠的时间值,以毫秒为单位.<br />
&nbsp;如果设置为非正数,则不运行空闲连接回收器线程<br />
numTestsPerEvictionRun &nbsp;3 &nbsp;在每次空闲连接回收器线程(如果有)运行时检查的连接数量<br />
minEvictableIdleTimeMillis &nbsp;1000 * 60 * 30 &nbsp;连接在池中保持空闲而不被空闲连接回收器线程<br />
(如果有)回收的最小时间值，单位毫秒</p>
<p>参数 &nbsp;默认值 &nbsp;描述<br />
poolPreparedStatements &nbsp;false &nbsp;开启池的prepared statement 池功能<br />
maxOpenPreparedStatements &nbsp;不限制 &nbsp;statement池能够同时分配的打开的statements的最大数量, <br />
如果设置为0表示不限制</p>
<p><br />
这里可以开启PreparedStatements池. 当开启时, 将为每个连接创建一个statement池,<br />
并且被下面方法创建的PreparedStatements将被缓存起来:<br />
&nbsp;&nbsp;&nbsp; * public PreparedStatement prepareStatement(String sql)<br />
&nbsp;&nbsp;&nbsp; * public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)<br />
注意: 确认连接还有剩余资源可以留给其他statement<br />
参数 &nbsp;默认值 &nbsp;描述<br />
accessToUnderlyingConnectionAllowed &nbsp;false &nbsp;控制PoolGuard是否容许获取底层连接</p>
<p><br />
如果容许则可以使用下面的方式来获取底层连接:<br />
&nbsp;&nbsp;&nbsp; Connection conn = ds.getConnection();<br />
&nbsp;&nbsp;&nbsp; Connection dconn = ((DelegatingConnection) conn).getInnermostDelegate();<br />
&nbsp;&nbsp;&nbsp; ...<br />
&nbsp;&nbsp;&nbsp; conn.close();</p>
<p>默认false不开启, 这是一个有潜在危险的功能, 不适当的编码会造成伤害.<br />
(关闭底层连接或者在守护连接已经关闭的情况下继续使用它).请谨慎使用,<br />
并且仅当需要直接访问驱动的特定功能时使用.<br />
注意: 不要关闭底层连接, 只能关闭前面的那个.<br />
参数 &nbsp;默认值 &nbsp;描述<br />
removeAbandoned &nbsp;false &nbsp;标记是否删除泄露的连接,如果他们超过了removeAbandonedTimout的限制.<br />
如果设置为true, 连接被认为是被泄露并且可以被删除,如果空闲时间超过removeAbandonedTimeout. <br />
设置为true可以为写法糟糕的没有关闭连接的程序修复数据库连接.<br />
removeAbandonedTimeout &nbsp;300 &nbsp;泄露的连接可以被删除的超时值, 单位秒<br />
logAbandoned &nbsp;false &nbsp;标记当Statement或连接被泄露时是否打印程序的stack traces日志。<br />
被泄露的Statements和连接的日志添加在每个连接打开或者生成新的Statement,<br />
因为需要生成stack trace。</p>
<p><br />
如果开启"removeAbandoned",那么连接在被认为泄露时可能被池回收. 这个机制在(getNumIdle() &lt; 2)<br />
&nbsp;and (getNumActive() &gt; getMaxActive() - 3)时被触发.<br />
举例当maxActive=20, 活动连接为18,空闲连接为1时可以触发"removeAbandoned".<br />
但是活动连接只有在没有被使用的时间超过"removeAbandonedTimeout"时才被删除,默认300秒.<br />
在resultset中游历不被计算为被使用.<br />
</p>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/348277.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2011-04-14 10:58 <a href="http://www.blogjava.net/wangxinsh55/archive/2011/04/14/348277.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用hibernate SQLQuery实现动态表</title><link>http://www.blogjava.net/wangxinsh55/archive/2010/08/25/329886.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Wed, 25 Aug 2010 06:41:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2010/08/25/329886.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/329886.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2010/08/25/329886.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/329886.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/329886.html</trackback:ping><description><![CDATA[<div class="blog_content">
<div style="margin: 15px" id="art">
<div>http://callan.javaeye.com/blog/156123<br />
<br />
我在实际的项目应用中，有时会设计出这样的一种数据表，每个时间段产生一个新表，例如是按年或月或日。相同类型的表中，所有的字段结构都是一样的。而 hibernate 提供的类与表的映射，是只能映射到一个具体表的，在程序的运行过程中，很难去动态修改一个 hbm 对应的表名。我在网上也有看到一实现，但是很复杂，并且不符合我的要求。</div>
<div>因此我就想到直接用 jdbc 去操作数据库，这样的做法是绕过 hibernate 了。方法是从 hibernate 的 session 中，直接取得数据库 connection ，然后就直接 jdbc 了。</div>
<div>后来在升级了 proxool 到 9.0RC3 后，发现居然出现了数据库连接无法释放的问题。为了解决这个问题，我查阅了 hibernate doc。我发现原来用 SQLQuery 可以更好的解决，并且可以重新用于 hibernate hbm 机制。以下举例说明。</div>
<div>例如我有一个 pojo 是 ReadInfo，用来记录阅读信息的。由于数据量宠大，所以我的思路是按月划分，每个月一张表。所以只是表名不同，而字段是完全相同的。</div>
<div>ReadInfo.java 是这样的，其中 userId, year, month, day 是联合主键：</div>
<table style="border-collapse: collapse" border="1" cellspacing="0" cellpadding="0" width="95%">
    <tbody>
        <tr>
            <td>
            <p style="line-height: 150%; margin: 5px"><span style="color: rgb(0,0,0)"><span style="font-family: Courier New">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,255)">private</span> <span style="color: rgb(255,0,0)">Integer</span> userId<span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,255)">private</span> <span style="color: rgb(255,0,0)">Integer</span> year<span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,255)">private</span> <span style="color: rgb(255,0,0)">Integer</span> month<span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,255)">private</span> <span style="color: rgb(255,0,0)">Integer</span> day<span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,255)">private</span> <span style="color: rgb(255,0,0)">Integer</span> <span style="color: rgb(255,0,0)">point</span><span style="color: rgb(0,0,204)">;</span></span></span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>那么相应的 ReadInfo.hbm.xml 的片段是</p>
<table style="border-collapse: collapse" border="1" cellspacing="0" cellpadding="0" width="95%">
    <tbody>
        <tr>
            <td>
            <p style="line-height: 150%; margin: 5px"><span style="color: rgb(0,0,0)"><span style="font-family: Courier New">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">&lt;</span>class name<span style="color: rgb(0,0,204)">=</span><span style="color: rgb(255,0,255)">"ReadInfo"</span> table<span style="color: rgb(0,0,204)">=</span><span style="color: rgb(255,0,255)">"<span style="color: rgb(0,0,255)"><strong>tblReadInfo</strong></span>"</span> <span style="color: rgb(255,0,0)"><strong>mutable</strong></span><span style="color: rgb(0,0,204)">=</span><span style="color: rgb(255,0,255)">"false"</span><span style="color: rgb(0,0,204)">&gt;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">&lt;</span>composite-id<span style="color: rgb(0,0,204)">&gt;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">&lt;</span>key-property name<span style="color: rgb(0,0,204)">=</span><span style="color: rgb(255,0,255)">"userId"</span> column<span style="color: rgb(0,0,204)">=</span><span style="color: rgb(255,0,255)">"userId"</span> type<span style="color: rgb(0,0,204)">=</span><span style="color: rgb(255,0,255)">"integer"</span><span style="color: rgb(0,0,204)">/</span><span style="color: rgb(0,0,204)">&gt;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">&lt;</span>key-property name<span style="color: rgb(0,0,204)">=</span><span style="color: rgb(255,0,255)">"year"</span> column<span style="color: rgb(0,0,204)">=</span><span style="color: rgb(255,0,255)">"year"</span> type<span style="color: rgb(0,0,204)">=</span><span style="color: rgb(255,0,255)">"integer"</span><span style="color: rgb(0,0,204)">/</span><span style="color: rgb(0,0,204)">&gt;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">&lt;</span>key-property name<span style="color: rgb(0,0,204)">=</span><span style="color: rgb(255,0,255)">"month"</span> column<span style="color: rgb(0,0,204)">=</span><span style="color: rgb(255,0,255)">"month"</span> type<span style="color: rgb(0,0,204)">=</span><span style="color: rgb(255,0,255)">"integer"</span><span style="color: rgb(0,0,204)">/</span><span style="color: rgb(0,0,204)">&gt;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">&lt;</span>key-property name<span style="color: rgb(0,0,204)">=</span><span style="color: rgb(255,0,255)">"day"</span> column<span style="color: rgb(0,0,204)">=</span><span style="color: rgb(255,0,255)">"day"</span> type<span style="color: rgb(0,0,204)">=</span><span style="color: rgb(255,0,255)">"integer"</span><span style="color: rgb(0,0,204)">/</span><span style="color: rgb(0,0,204)">&gt;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">&lt;</span><span style="color: rgb(0,0,204)">/</span>composite-id<span style="color: rgb(0,0,204)">&gt;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">&lt;</span>property name<span style="color: rgb(0,0,204)">=</span><span style="color: rgb(255,0,255)">"point"</span> column<span style="color: rgb(0,0,204)">=</span><span style="color: rgb(255,0,255)">"point"</span> type<span style="color: rgb(0,0,204)">=</span><span style="color: rgb(255,0,255)">"integer"</span><span style="color: rgb(0,0,204)">/</span><span style="color: rgb(0,0,204)">&gt;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">&lt;</span><span style="color: rgb(0,0,204)">/</span>class<span style="color: rgb(0,0,204)">&gt;</span></span></span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>上面的xml，注意 2 个细节</p>
<p>1. pojo 所映射的 table tblReadInfo 实际上是不存在的。实际的表是 tblRead200710 之类的；</p>
<p>2. mutable 要设置为&nbsp;false，即是说，关闭 hibernate 对这个 pojo 的任何持久化操作，以避免 hibernate 把数据写到 tblReadInfo 中（这个表是不存在的嘛）。因此，所有的持久化操作，都是需要自己通过 SQLQuery 来处理。</p>
<p>现在可以看一下 ado 中的操作了，先看一个 select 操作</p>
<table style="border-collapse: collapse" border="1" cellspacing="0" cellpadding="0" width="95%">
    <tbody>
        <tr>
            <td>
            <p style="line-height: 150%; margin: 5px"><span style="color: rgb(0,0,0)"><span style="font-family: Courier New"><span style="color: rgb(0,0,255)">public</span> ReadInfo selectReadInfo<span style="color: rgb(0,0,204)">(</span><span style="color: rgb(255,0,0)">Integer</span> userId<span style="color: rgb(0,0,204)">,</span> <span style="color: rgb(255,0,0)">Integer</span> year<span style="color: rgb(0,0,204)">,</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(255,0,0)">Integer</span> month<span style="color: rgb(0,0,204)">,</span> <span style="color: rgb(255,0,0)">Integer</span> day<span style="color: rgb(0,0,204)">)</span> <span style="color: rgb(0,0,255)">throws</span> HibernateException<br />
            &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">{</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ReadInfo readInfo <span style="color: rgb(0,0,204)">=</span> <span style="color: rgb(0,0,255)">null</span><span style="color: rgb(0,0,204)">;</span><br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Session session <span style="color: rgb(0,0,204)">=</span> <span style="color: rgb(255,0,0)">getSession</span><span style="color: rgb(0,0,204)">(</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(255,0,0)">Transaction</span> tx <span style="color: rgb(0,0,204)">=</span> session<span style="color: rgb(0,0,204)">.</span>beginTransaction<span style="color: rgb(0,0,204)">(</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,255)">try</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">{</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(255,0,0)">String</span> <span style="color: rgb(255,0,0)">sql</span> <span style="color: rgb(0,0,204)">=</span> <span style="color: rgb(255,0,255)">"select * from tblRead"</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">+</span> Misc<span style="color: rgb(0,0,204)">.</span>formatMoon<span style="color: rgb(0,0,204)">(</span>year<span style="color: rgb(0,0,204)">,</span> month<span style="color: rgb(0,0,204)">)</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">+</span> <span style="color: rgb(255,0,255)">" where userId=? and day=?"</span><span style="color: rgb(0,0,204)">;</span><br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SQLQuery <span style="color: rgb(255,0,0)">query</span> <span style="color: rgb(0,0,204)">=</span> session<span style="color: rgb(0,0,204)">.</span>createSQLQuery<span style="color: rgb(0,0,204)">(</span><span style="color: rgb(255,0,0)">sql</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(255,0,0)">query</span><span style="color: rgb(0,0,204)">.</span>addEntity<span style="color: rgb(0,0,204)">(</span>ReadInfo<span style="color: rgb(0,0,204)">.</span><span style="color: rgb(0,0,255)">class</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(255,0,0)">query</span><span style="color: rgb(0,0,204)">.</span><span style="color: rgb(255,0,0)">setLong</span><span style="color: rgb(0,0,204)">(</span>0<span style="color: rgb(0,0,204)">,</span> userId<span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(255,0,0)">query</span><span style="color: rgb(0,0,204)">.</span>setInteger<span style="color: rgb(0,0,204)">(</span>1<span style="color: rgb(0,0,204)">,</span> day<span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readInfo <span style="color: rgb(0,0,204)">=</span> <span style="color: rgb(0,0,204)">(</span>ReadInfo<span style="color: rgb(0,0,204)">)</span> <span style="color: rgb(255,0,0)">query</span><span style="color: rgb(0,0,204)">.</span>uniqueResult<span style="color: rgb(0,0,204)">(</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tx<span style="color: rgb(0,0,204)">.</span><span style="color: rgb(255,0,0)">commit</span><span style="color: rgb(0,0,204)">(</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">}</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,255)">catch</span> <span style="color: rgb(0,0,204)">(</span>HibernateException e<span style="color: rgb(0,0,204)">)</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">{</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(255,0,0)">log</span><span style="color: rgb(0,0,204)">.</span><span style="color: rgb(255,0,0)">error</span><span style="color: rgb(0,0,204)">(</span><span style="color: rgb(255,0,255)">"catch exception:"</span><span style="color: rgb(0,0,204)">,</span> e<span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,255)">if</span> <span style="color: rgb(0,0,204)">(</span>tx <span style="color: rgb(0,0,204)">!</span><span style="color: rgb(0,0,204)">=</span> <span style="color: rgb(0,0,255)">null</span><span style="color: rgb(0,0,204)">)</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">{</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tx<span style="color: rgb(0,0,204)">.</span><span style="color: rgb(255,0,0)">rollback</span><span style="color: rgb(0,0,204)">(</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">}</span><br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,255)">throw</span> e<span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">}</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,255)">return</span> readInfo<span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">}</span></span></span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>上面的代码，关键是以下几点：</p>
<p>1. 通过函数参数的 year, month 来确定要操作的表名，我自己写了一个 Misc.formatMoon(year, month) 来生成 "yyyyMM" 格式的字串；</p>
<p>2. 使用了 SQLQuery ，再通过 query.addEntity(ReadInfo.class); 建立与 ReadInfo 的映射关系；</p>
<p>3. query.setXxx() 与 PreparedStatement 的类似，不过索引是从 <strong><span style="color: rgb(255,0,0)">0</span></strong> 开始；</p>
<p>4. 其它的就跟一般的 Query 操作类似的了。</p>
<p>再看一个 insert 操作</p>
<table style="border-collapse: collapse" border="1" cellspacing="0" cellpadding="0" width="95%">
    <tbody>
        <tr>
            <td>
            <p style="line-height: 150%; margin: 5px"><span style="color: rgb(0,0,0)"><span style="font-family: Courier New">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(0,0,255)">void</span> insertReadInfo<span style="color: rgb(0,0,204)">(</span>ReadInfo readInfo<span style="color: rgb(0,0,204)">)</span> <span style="color: rgb(0,0,255)">throws</span> HibernateException<br />
            &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">{</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Session session <span style="color: rgb(0,0,204)">=</span> <span style="color: rgb(255,0,0)">getSession</span><span style="color: rgb(0,0,204)">(</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(255,0,0)">Transaction</span> tx <span style="color: rgb(0,0,204)">=</span> session<span style="color: rgb(0,0,204)">.</span>beginTransaction<span style="color: rgb(0,0,204)">(</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,255)">try</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">{</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(255,0,0)">String</span> <span style="color: rgb(255,0,0)">sql</span> <span style="color: rgb(0,0,204)">=</span> <span style="color: rgb(255,0,255)">"insert into tblRead"</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">+</span> Misc<span style="color: rgb(0,0,204)">.</span>formatMoon<span style="color: rgb(0,0,204)">(</span>readInfo<span style="color: rgb(0,0,204)">.</span><span style="color: rgb(255,0,0)">getYear</span><span style="color: rgb(0,0,204)">(</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">,</span> readInfo<span style="color: rgb(0,0,204)">.</span><span style="color: rgb(255,0,0)">getMonth</span><span style="color: rgb(0,0,204)">(</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">)</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">+</span> <span style="color: rgb(255,0,255)">" (userId, year, month, day, point) values (?, ?, ?, ?, ?)"</span><span style="color: rgb(0,0,204)">;</span><br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SQLQuery <span style="color: rgb(255,0,0)">query</span> <span style="color: rgb(0,0,204)">=</span> session<span style="color: rgb(0,0,204)">.</span>createSQLQuery<span style="color: rgb(0,0,204)">(</span><span style="color: rgb(255,0,0)">sql</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(255,0,0)">query</span><span style="color: rgb(0,0,204)">.</span><span style="color: rgb(255,0,0)">setLong</span><span style="color: rgb(0,0,204)">(</span>0<span style="color: rgb(0,0,204)">,</span> readInfo<span style="color: rgb(0,0,204)">.</span>getUserId<span style="color: rgb(0,0,204)">(</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(255,0,0)">query</span><span style="color: rgb(0,0,204)">.</span>setInteger<span style="color: rgb(0,0,204)">(</span>1<span style="color: rgb(0,0,204)">,</span> readInfo<span style="color: rgb(0,0,204)">.</span><span style="color: rgb(255,0,0)">getYear</span><span style="color: rgb(0,0,204)">(</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(255,0,0)">query</span><span style="color: rgb(0,0,204)">.</span>setInteger<span style="color: rgb(0,0,204)">(</span>2<span style="color: rgb(0,0,204)">,</span> readInfo<span style="color: rgb(0,0,204)">.</span><span style="color: rgb(255,0,0)">getMonth</span><span style="color: rgb(0,0,204)">(</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(255,0,0)">query</span><span style="color: rgb(0,0,204)">.</span>setInteger<span style="color: rgb(0,0,204)">(</span>3<span style="color: rgb(0,0,204)">,</span> readInfo<span style="color: rgb(0,0,204)">.</span><span style="color: rgb(255,0,0)">getDay</span><span style="color: rgb(0,0,204)">(</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(255,0,0)">query</span><span style="color: rgb(0,0,204)">.</span>setInteger<span style="color: rgb(0,0,204)">(</span>4<span style="color: rgb(0,0,204)">,</span> readInfo<span style="color: rgb(0,0,204)">.</span><span style="color: rgb(255,0,0)">getPoint</span><span style="color: rgb(0,0,204)">(</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(255,0,0)">query</span><span style="color: rgb(0,0,204)">.</span><span style="color: rgb(255,0,0)">executeUpdate</span><span style="color: rgb(0,0,204)">(</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tx<span style="color: rgb(0,0,204)">.</span><span style="color: rgb(255,0,0)">commit</span><span style="color: rgb(0,0,204)">(</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">}</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,255)">catch</span> <span style="color: rgb(0,0,204)">(</span>HibernateException e<span style="color: rgb(0,0,204)">)</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">{</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(255,0,0)">log</span><span style="color: rgb(0,0,204)">.</span><span style="color: rgb(255,0,0)">error</span><span style="color: rgb(0,0,204)">(</span><span style="color: rgb(255,0,255)">"catch exception:"</span><span style="color: rgb(0,0,204)">,</span> e<span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,255)">if</span> <span style="color: rgb(0,0,204)">(</span>tx <span style="color: rgb(0,0,204)">!</span><span style="color: rgb(0,0,204)">=</span> <span style="color: rgb(0,0,255)">null</span><span style="color: rgb(0,0,204)">)</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">{</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tx<span style="color: rgb(0,0,204)">.</span><span style="color: rgb(255,0,0)">rollback</span><span style="color: rgb(0,0,204)">(</span><span style="color: rgb(0,0,204)">)</span><span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">}</span><br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,255)">throw</span> e<span style="color: rgb(0,0,204)">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">}</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,0,204)">}</span></span></span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>同理，update, delete 等操作也是这样实现的。</p>
<p>hmm.. 这种处理方式的麻烦的地方是需要手工写 sql ，因此要尽量写通用的标准 sql，不然在数据库兼容方面会有问题。当然，有时是会出现无法兼容的情况，那么可以考虑把 sql 写到配置文件中，根据不同的数据库，装载相应的配置文件咯。</p>
</div>
</div>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/329886.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2010-08-25 14:41 <a href="http://www.blogjava.net/wangxinsh55/archive/2010/08/25/329886.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>J2SE API读取Properties文件的六种方法</title><link>http://www.blogjava.net/wangxinsh55/archive/2009/08/13/290961.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Thu, 13 Aug 2009 03:19:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2009/08/13/290961.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/290961.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2009/08/13/290961.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/290961.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/290961.html</trackback:ping><description><![CDATA[<p><strong>　　使用J2SE API读取Properties文件的六种方法：</strong></p>
<p><strong>　　1.使用Java.util.Properties类的load()方法</strong></p>
<p>　　示例： </p>
<p>
</p>
<table style="border: 1px dotted #cccccc; table-layout: fixed;" width="95%" align="center" border="0" cellpadding="6" cellspacing="0">
    <tbody>
        <tr>
            <td style="word-wrap: break-word;" bgcolor="#f3f3f3"><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputStream&nbsp;in&nbsp;=&nbsp;lnew&nbsp;BufferedInputStream(new&nbsp;FileInputStream(name)); <br />
            Properties&nbsp;p&nbsp;=&nbsp;new&nbsp;Properties(); <br />
            p.load(in);</td>
        </tr>
    </tbody>
</table>
<p><strong>　　2.使用java.util.ResourceBundle类的getBundle()方法</strong></p>
<p>
</p>
<table style="border: 1px dotted #cccccc; table-layout: fixed;" width="95%" align="center" border="0" cellpadding="6" cellspacing="0">
    <tbody>
        <tr>
            <td style="word-wrap: break-word;" bgcolor="#f3f3f3"><br />
            示例：&nbsp;ResourceBundle&nbsp;rb&nbsp;=&nbsp;ResourceBundle.getBundle(name,&nbsp;Locale.getDefault());</td>
        </tr>
    </tbody>
</table>
<p>　<strong>　3.使用java.util.PropertyResourceBundle类的构造函数</strong></p>
<p>
</p>
<table style="border: 1px dotted #cccccc; table-layout: fixed;" width="95%" align="center" border="0" cellpadding="6" cellspacing="0">
    <tbody>
        <tr>
            <td style="word-wrap: break-word;" bgcolor="#f3f3f3"><br />
            示例：&nbsp;InputStream&nbsp;in&nbsp;=&nbsp;new&nbsp;BufferedInputStream(new&nbsp;FileInputStream(name)); <br />
            ResourceBundle&nbsp;rb&nbsp;=&nbsp;new&nbsp;PropertyResourceBundle(in);</td>
        </tr>
    </tbody>
</table>
<p><strong>　　4.使用<a class="fllink" href="http://whatis.ctocio.com.cn/searchwhatis/213/5947213.shtml" target="_bank">class</a>变量的getResourceAsStream()方法</strong></p>
<p>
</p>
<table style="border: 1px dotted #cccccc; table-layout: fixed;" width="95%" align="center" border="0" cellpadding="6" cellspacing="0">
    <tbody>
        <tr>
            <td style="word-wrap: break-word;" bgcolor="#f3f3f3"><br />
            示例：&nbsp;InputStream&nbsp;in&nbsp;=&nbsp;JProperties.class.getResourceAsStream(name); <br />
            Properties&nbsp;p&nbsp;=&nbsp;new&nbsp;Properties(); <br />
            p.load(in);</td>
        </tr>
    </tbody>
</table>
<p><strong>　　5.使用class.getClassLoader()所得到的java.lang.ClassLoader的getResourceAsStream()方法</strong></p>
<p>
</p>
<table style="border: 1px dotted #cccccc; table-layout: fixed;" width="95%" align="center" border="0" cellpadding="6" cellspacing="0">
    <tbody>
        <tr>
            <td style="word-wrap: break-word;" bgcolor="#f3f3f3"><br />
            示例：&nbsp;InputStream&nbsp;in&nbsp;=&nbsp;JProperties.class.getClassLoader().getResourceAsStream(name); <br />
            Properties&nbsp;p&nbsp;=&nbsp;new&nbsp;Properties(); <br />
            p.load(in);</td>
        </tr>
    </tbody>
</table>
<p><strong>　　6.使用java.lang.ClassLoader类的getSystemResourceAsStream()静态方法</strong></p>
<p>
</p>
<table style="border: 1px dotted #cccccc; table-layout: fixed;" width="95%" align="center" border="0" cellpadding="6" cellspacing="0">
    <tbody>
        <tr>
            <td style="word-wrap: break-word;" bgcolor="#f3f3f3"><br />
            示例：&nbsp;InputStream&nbsp;in&nbsp;=&nbsp;ClassLoader.getSystemResourceAsStream(name); <br />
            Properties&nbsp;p&nbsp;=&nbsp;new&nbsp;Properties(); <br />
            p.load(in);</td>
        </tr>
    </tbody>
</table>
<p><strong>　　补充</strong></p>
<p>　　<a class="fllink" href="http://whatis.ctocio.com.cn/searchwhatis/17/5949017.shtml" target="_bank">Servlet</a>中可以使用javax.servlet.ServletContext的getResourceAsStream()方法</p>
<p>
</p>
<table style="border: 1px dotted #cccccc; table-layout: fixed;" width="95%" align="center" border="0" cellpadding="6" cellspacing="0">
    <tbody>
        <tr>
            <td style="word-wrap: break-word;" bgcolor="#f3f3f3"><br />
            示例：InputStream&nbsp;in&nbsp;=&nbsp;context.getResourceAsStream(<a class="fllink" href="http://whatis.ctocio.com.cn/searchwhatis/448/6025948.shtml" target="_bank">path</a>); <br />
            Properties&nbsp;p&nbsp;=&nbsp;new&nbsp;Properties(); <br />
            p.load(in);</td>
        </tr>
    </tbody>
</table>
<p>　<strong>　</strong></p>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/290961.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2009-08-13 11:19 <a href="http://www.blogjava.net/wangxinsh55/archive/2009/08/13/290961.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>通过正则表达式将URL串中的参数名-值进行分解（符合特殊字符的处理如&amp;?）</title><link>http://www.blogjava.net/wangxinsh55/archive/2009/07/28/288690.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Tue, 28 Jul 2009 02:16:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2009/07/28/288690.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/288690.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2009/07/28/288690.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/288690.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/288690.html</trackback:ping><description><![CDATA[<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;aid&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">http://127.0.0.1:8080/??sdf=s&amp;&amp;st=b=&amp;&amp;?sw?=%B9%FA+%BC%D2&amp;tb=&amp;st=9</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pattern&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;Pattern.compile(</span><span style="color: #000000;">"</span><span style="color: #000000;">(\\?|&amp;+)(.+?)=([^&amp;]*)</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Matcher&nbsp;m&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p.matcher(aid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(m.find())&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(m.group(</span><span style="color: #000000;">2</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;m.group(</span><span style="color: #000000;">3</span><span style="color: #000000;">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span></div>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/288690.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2009-07-28 10:16 <a href="http://www.blogjava.net/wangxinsh55/archive/2009/07/28/288690.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struts2+spring发送mail</title><link>http://www.blogjava.net/wangxinsh55/archive/2009/05/15/270872.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Fri, 15 May 2009 08:27:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2009/05/15/270872.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/270872.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2009/05/15/270872.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/270872.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/270872.html</trackback:ping><description><![CDATA[<div id="articleBody">
<p>&nbsp;<wbr>
spring中有集成了javamail，在使用框架的时候用spring来发送mail也是很方便的。下面是一个spring
mail的小例子。</p>
<p>&nbsp;<wbr>
在这个例子中，除了需要struts和spring的框架外，还需要mail.jar,activation.jar.</p>
<p>&nbsp;<wbr>&nbsp;<wbr>web.xml的代码：</p>
<p>&nbsp;<wbr> &lt;?xml version="1.0"
encoding="UTF-8"?&gt;<br />
&lt;web-app version="2.4"<br />
&nbsp;<wbr>xmlns="<a href="http://java.sun.com/xml/ns/j2ee">http://java.sun.com/xml/ns/j2ee</a>"<br />
&nbsp;<wbr>xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>"<br />
&nbsp;<wbr>xsi:schemaLocation="<a href="http://java.sun.com/xml/ns/j2ee">http://java.sun.com/xml/ns/j2ee</a><br />
&nbsp;<wbr><a href="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd</a>"&gt;<br />
&nbsp;<wbr>&lt;context-param&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&lt;param-value&gt;classpath*:spring/*.xml&lt;/param-value&gt;<br />
&nbsp;<wbr>&lt;/context-param&gt;</p>
<p>&nbsp;<wbr>&lt;listener&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;<br />
&nbsp;<wbr>&lt;/listener&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;!-- Spring refresh Introspector to prevent from out
of memory&nbsp;<wbr> --&gt;<br />
&nbsp;<wbr>&lt;listener&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&lt;listener-class&gt;org.springframework.web.util.IntrospectorCleanupListener&lt;/listener-class&gt;<br />
&nbsp;<wbr>&lt;/listener&gt;<br />
&nbsp;<wbr>&lt;!-- Support session scope, Spring
bean --&gt;<br />
&nbsp;<wbr>&lt;listener&gt;&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;listener-class&gt;org.springframework.web.context.request.RequestContextListener&lt;/listener-class&gt;<br />
&nbsp;<wbr>&lt;/listener&gt;<br />
&nbsp;<wbr>&lt;!-- Struts2 Action
Mapping--&gt;<br />
&nbsp;<wbr>&lt;filter&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;filter-name&gt;struts2&lt;/filter-name&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;filter-class&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
org.apache.struts2.dispatcher.FilterDispatcher<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;/filter-class&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;/filter&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;listener&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;/listener&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&lt;filter-mapping&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;filter-name&gt;struts2&lt;/filter-name&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;/filter-mapping&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&lt;!--
session time out --&gt;<br />
&nbsp;<wbr>&lt;session-config&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&lt;session-timeout&gt;30&lt;/session-timeout&gt;<br />
&nbsp;<wbr>&lt;/session-config&gt;<br />
&nbsp;<wbr>&lt;!-- default index
--&gt;<br />
&nbsp;<wbr>&lt;welcome-file-list&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&lt;welcome-file&gt;send.jsp&lt;/welcome-file&gt;<br />
&nbsp;<wbr>&lt;/welcome-file-list&gt;<br />
&lt;/web-app&gt;<br />
Java类MailAction.java:</p>
<p>package action;</p>
<p>import org.springframework.mail.SimpleMailMessage;<br />
import org.springframework.mail.javamail.JavaMailSenderImpl;</p>
<p>import com.opensymphony.xwork2.Action;<br />
import com.opensymphony.xwork2.ActionSupport;<br />
public class MailAction extends ActionSupport{<br />
&nbsp;<wbr>private JavaMailSenderImpl mailSender;<br />
&nbsp;<wbr>private SimpleMailMessage mailMessage;<br />
&nbsp;<wbr>&nbsp;<wbr>public String sendMail(){<br />
&nbsp;<wbr>&nbsp;<wbr>SimpleMailMessage msg = new
SimpleMailMessage(mailMessage);<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
msg.setText("Spring Mail Simple!");<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
mailSender.send(msg);<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
return Action.SUCCESS;<br />
&nbsp;<wbr>}<br />
&nbsp;<wbr>&nbsp;<wbr>public void
setMailMessage(SimpleMailMessage mailMessage) {<br />
&nbsp;<wbr>&nbsp;<wbr>this.mailMessage =
mailMessage;<br />
&nbsp;<wbr>}</p>
<p>&nbsp;<wbr>public void setMailSender(JavaMailSenderImpl
mailSender) {<br />
&nbsp;<wbr>&nbsp;<wbr>this.mailSender =
mailSender;<br />
&nbsp;<wbr>}</p>
<p>}<br />
spring配置文件applicationContext.xml:</p>
<p>&lt;?xml version="1.0"
encoding="UTF-8"?&gt;<br />
&lt;beans xmlns="<a href="http://www.springframework.org/schema/beans">http://www.springframework.org/schema/beans</a>"<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>"<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
xmlns:aop="<a href="http://www.springframework.org/schema/aop">http://www.springframework.org/schema/aop</a>"<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
xmlns:tx="<a href="http://www.springframework.org/schema/tx">http://www.springframework.org/schema/tx</a>"<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
xsi:schemaLocation="<a href="http://www.springframework.org/schema/beans">http://www.springframework.org/schema/beans</a>
<a href="http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">http://www.springframework.org/schema/beans/spring-beans-2.0.xsd</a><br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
<a href="http://www.springframework.org/schema/aop">http://www.springframework.org/schema/aop</a>
<a href="http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">http://www.springframework.org/schema/aop/spring-aop-2.0.xsd</a><br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
<a href="http://www.springframework.org/schema/tx">http://www.springframework.org/schema/tx</a>
<a href="http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">http://www.springframework.org/schema/tx/spring-tx-2.0.xsd</a>"<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
default-autowire="byName"
default-lazy-init="true"&gt;</p>
<p>&nbsp;<wbr>&lt;bean id="mailAction"
class="action.MailAction"&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&lt;property
name="mailSender" ref="mailSender"/&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&lt;property
name="mailMessage" ref="mailMessage"/&gt;<br />
&nbsp;<wbr>&lt;/bean&gt;<br />
&nbsp;<wbr><br />
&nbsp;<wbr>&lt;bean id="mailSender"<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
class="org.springframework.mail.javamail.JavaMailSenderImpl"&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;property name="host"
value="smtp.163.com"/&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;!-- mail&nbsp;<wbr>
account&nbsp;<wbr>&nbsp;<wbr>
--&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;property name="username"
value="shwwwx"/&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;property name="password"
value="wwx1226"/&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;property
name="javaMailProperties"&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;props&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;prop
key="mail.smtp.auth"&gt;true&lt;/prop&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;/props&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;/property&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;/bean&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;!-- mail template --&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;bean id="mailMessage"
class="org.springframework.mail.SimpleMailMessage"&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;property name="to" value="<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#115;&#104;&#119;&#119;&#119;&#120;&#64;&#49;&#54;&#51;&#46;&#99;&#111;&#109;&#44;&#110;&#97;&#98;&#101;&#108;&#117;&#110;&#64;&#49;&#54;&#51;&#46;&#99;&#111;&#109;">shwwwx@163.com,nabelun@163.com"/</a>&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;property name="from" value="<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#115;&#104;&#119;&#119;&#119;&#120;&#64;&#49;&#54;&#51;&#46;&#99;&#111;&#109;">shwwwx@163.com"/</a>&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;property name="subject" value="Mail
Simple"/&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;/bean&gt;<br />
&lt;/beans&gt;</p>
<p>struts2的配置文件struts.xml:</p>
<p>&lt;?xml version="1.0" encoding="UTF-8"
?&gt;<br />
&lt;!DOCTYPE struts PUBLIC<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> "-//Apache
Software Foundation//DTD Struts Configuration 2.0//EN"<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> "<a href="http://struts.apache.org/dtds/struts-2.0.dtd">http://struts.apache.org/dtds/struts-2.0.dtd</a>"&gt;<br />
&lt;struts&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;constant name="struts.objectFactory" value="spring"
/&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;constant name="struts.devMode" value="false"
/&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;constant name="struts.i18n.encoding" value="utf-8"
/&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;package
name="springtimer"&nbsp;<wbr>&nbsp;<wbr>
extends="struts-default"&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;action name="mailsend" class="mailAction"
method="sendMail"&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;result&gt;sendok.jsp&lt;/result&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;interceptor-ref
name="defaultStack"/&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;/action&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;/package&gt;<br />
&lt;/struts&gt;<br />
页面send.jsp:</p>
<p>&lt;%@ page language="java" import="java.util.*"
pageEncoding="UTF-8"%&gt;<br />
&lt;html&gt;<br />
&nbsp;<wbr> &lt;head&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;title&gt;My JSP 'send.jsp' starting
page&lt;/title&gt;<br />
&nbsp;<wbr> &lt;/head&gt;<br />
&nbsp;<wbr> &lt;body&gt;<br />
&nbsp;<wbr>&lt;form action="mailsend.action"
method="post"&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&lt;input
type="submit" value="邮件发送"&gt;<br />
&nbsp;<wbr>&lt;/form&gt;<br />
&nbsp;<wbr> &lt;/body&gt;<br />
&lt;/html&gt;</p>
<p>页面sendok.jsp:</p>
<p>&lt;%@ page language="java" import="java.util.*"
pageEncoding="UTF-8"%&gt;<br />
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN"&gt;<br />
&lt;html&gt;<br />
&nbsp;<wbr> &lt;head&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;title&gt;My JSP 'sendok.jsp' starting
page&lt;/title&gt;<br />
&nbsp;<wbr> &lt;/head&gt;<br />
&nbsp;<wbr> &lt;body&gt;<br />
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Send Mail
Success! &lt;br&gt;<br />
&nbsp;<wbr> &lt;/body&gt;<br />
&lt;/html&gt;<br />
运行send.jsp发送邮件，成功的话会跳转到sendok.jsp页面。</p>
</div>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/270872.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2009-05-15 16:27 <a href="http://www.blogjava.net/wangxinsh55/archive/2009/05/15/270872.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>怎样用Java来获取真实的IP地址</title><link>http://www.blogjava.net/wangxinsh55/archive/2009/01/07/250232.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Wed, 07 Jan 2009 02:10:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2009/01/07/250232.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/250232.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2009/01/07/250232.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/250232.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/250232.html</trackback:ping><description><![CDATA[<div style="text-indent: 2em;">在JSP里，获取客户端的IP地址的方法是：<strong>request.getRemoteAddr()</strong>，这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。</div>
<div style="text-indent: 2em;">如果使用了反向代理软件，将<span style="text-decoration: underline;"><a href="http://192.168.1.110:2046/"><span style="color: #678d02;">http://192.168.1.110:2046/</span></a></span> 的URL反向代理为 <a href="http://www.bt285.cn/"><span style="text-decoration: underline;">http://www.<u><font color="#000000">bt285.cn </font></u></span></a><span style="text-decoration: underline;">/</span> 的URL时，用<strong>request.getRemoteAddr()</strong>方法获取的IP地址是：127.0.0.1　或　<span style="text-decoration: underline;"><span style="color: #0000ff;">192.168.1.110</span></span>，而并不是客户端的真实ＩＰ。</div>
<div style="text-indent: 2em;">经过代理以后，由于在客户端和服务之间增加了中间层，因此服务器无法直接拿到客户端的
IP，服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中，增加了X－FORWARDED－FOR信息。用以跟踪
原有的客户端IP地址和原来客户端请求的服务器地址。当我们访问<span style="text-decoration: underline;"><a href="http://www.5q520.cn/">http://www.5q520.cn</a> /index.jsp/</span> 时，其实并不是我们浏览器真正访问到了服务器上的index.jsp文件，而是先由代理服务器去访问<span style="text-decoration: underline;">http://192.168.1.110:2046/index.jsp</span> ，代理服务器再将访问到的结果返回给我们的浏览器，因为是代理服务器去访问index.jsp的，所以index.jsp中通过<strong>request.getRemoteAddr()</strong>的方法获取的IP实际上是代理服务器的地址，并不是客户端的IP地址。</div>
<div style="text-indent: 2em;"><span style="font-family: 宋体;">于是可得出获得客户端真实IP地址的方法一：</span></div>
<div style="text-indent: 2em;">
<div class="dp-highlighter">
<ol class="dp-j">
    <li><span><span class="keyword">public</span><span>&nbsp;String&nbsp;getRemortIP(HttpServletRequest&nbsp;request)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(request.getHeader(</span><span class="string">"x-forwarded-for"</span><span>)&nbsp;==&nbsp;</span><span class="keyword">null</span><span>)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;request.getRemoteAddr(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;request.getHeader(</span><span class="string">"x-forwarded-for"</span><span>); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none;" name="code">public String getRemortIP(HttpServletRequest request) {
if (request.getHeader("x-forwarded-for") == null) {
return request.getRemoteAddr();
}
return request.getHeader("x-forwarded-for");
}
</pre>
&nbsp;
<p>可是当我访问<span style="text-decoration: underline;"><a href="http://www.5a520.cn/">http://www.5a520.cn</a> /index.jsp/</span> 时，返回的IP地址始终是unknown，也并不是如上所示的127.0.0.1　或　<span style="text-decoration: underline;"><span style="color: #0000ff;">192.168.1.110</span></span>了，而我访问<span style="text-decoration: underline;">http://192.168.1.110:2046/index.jsp</span>
时，则能返回客户端的真实IP地址，写了个方法去验证。原因出在了Squid上。squid.conf 的配制文件　forwarded_for
项默认是为on，如果 forwarded_for 设成了 off 　则：X-Forwarded-For: unknown</p>
<p>于是可得出获得客户端真实IP地址的方法二：</p>
<div class="dp-highlighter">
<ol class="dp-j">
    <li><span><span class="keyword">public</span><span>&nbsp;String&nbsp;getIpAddr(HttpServletRequest&nbsp;request)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;ip&nbsp;=&nbsp;request.getHeader(</span><span class="string">"x-forwarded-for"</span><span>); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(ip&nbsp;==&nbsp;</span><span class="keyword">null</span><span>&nbsp;||&nbsp;ip.length()&nbsp;==&nbsp;</span><span class="number">0</span><span>&nbsp;||&nbsp;</span><span class="string">"unknown"</span><span>.equalsIgnoreCase(ip))&nbsp;{ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip&nbsp;=&nbsp;request.getHeader(</span><span class="string">"Proxy-Client-IP"</span><span>); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(ip&nbsp;==&nbsp;</span><span class="keyword">null</span><span>&nbsp;||&nbsp;ip.length()&nbsp;==&nbsp;</span><span class="number">0</span><span>&nbsp;||&nbsp;</span><span class="string">"unknown"</span><span>.equalsIgnoreCase(ip))&nbsp;{ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip&nbsp;=&nbsp;request.getHeader(</span><span class="string">"WL-Proxy-Client-IP"</span><span>); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(ip&nbsp;==&nbsp;</span><span class="keyword">null</span><span>&nbsp;||&nbsp;ip.length()&nbsp;==&nbsp;</span><span class="number">0</span><span>&nbsp;||&nbsp;</span><span class="string">"unknown"</span><span>.equalsIgnoreCase(ip))&nbsp;{ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip&nbsp;=&nbsp;request.getRemoteAddr(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;ip; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none;" name="code">public String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}</pre>
<p>&nbsp;可是，如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串Ｉｐ值，究竟哪个才是真正的用户端的真实IP呢？</p>
<p>　　答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。</p>
<p>　　如：<br />
X-Forwarded-For：192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100<br />
用户真实IP为： 192.168.1.110</p>
</div>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/250232.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2009-01-07 10:10 <a href="http://www.blogjava.net/wangxinsh55/archive/2009/01/07/250232.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>跨域(cross-domain)访问 cookie （读取和设置）</title><link>http://www.blogjava.net/wangxinsh55/archive/2009/01/07/250227.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Wed, 07 Jan 2009 02:02:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2009/01/07/250227.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/250227.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2009/01/07/250227.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/250227.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/250227.html</trackback:ping><description><![CDATA[<div class="content">
<p>Passport 一方面意味着用一个帐号可以在不同服务里登录，另一方面就是在一个服务里面登录后可以无障碍的漫游到其他服务里面去。坦白说，目前 sohu passport 在这一点实现的很烂（不过俺的工作就是要把它做好啦，hehe）</p>
<p>搜狐的 SSO 需求比较麻烦，因为它旗下有好多域名：sohu.com、chinaren.com、sogou.com、focus.cn、17173.com、go2map.com，登录用户漫游的主要障碍也来自于此。</p>
<p>以前亿邮的邮件系统在和别的系统整合的时候是提供一个 URL，用户从第三方系统里面点击这个链接就可以生成访问邮件界面所需的 cookie，然后进入邮件。这个方式的确很有效，但问题是：<br />
1. 每个外部链接都必须用特殊的 URL 跳转，维护很麻烦<br />
2. 两个系统集成已经很麻烦了，若是集成的系统有好几个，彼此都需要跳转而缺乏一个中心机制就成了噩梦<br />
3. 根本无法处理用户直接在地址栏输入地址进行访问的情况</p>
<p>即使是跨域，上述的解决方法相对来说还是容易的。<br />
A. 首先是所有登录必须首先通过一个中央服务器进行认证，然后在它那里给浏览器种下 cookie（下面称之为 sso cookie）<br />
B. 当用户访问另外的域名 app 的时候，浏览器是无法直接发送 sso cookie 给服务器认证的。此时应该利用 javascript，动态创建一个隐藏的 iframe，让其访问 sso<br />
C. 这个 iframe 的请求是可以把 sso cookie 送给 sso server 的。sso server 验证 cookie 后，返回一个重定向页面到 app 的某个 URL，由该 URL 设置 app cookie<br />
D. 此时浏览器上可看见的页面容器实际上也是可以和重定向回来的内容交互的。比如可以用 js 控制发现重定向页面成功返回后，就刷新整个页面，让它看起来和用户登录后访问没有什么区别。</p>
<p><strong>下面是真正的技巧：怎样才能在 IE 里面跨域去设置 cookie</strong><br />
上述技术看起来是不是很好？但它的前提是所有的登录都 post 到 sso server 上，认证成功后再返回 app 页面。可我接受到的需求之一就是要支持页面无刷新登录。</p>
<p>哈！就是说本来在 chinaren.com 上提交登录表单的 action 应该是 passport.sohu.com 这个 sso
server。可是在 AJAX 大潮下，chinaren 计划采用 XMLHTTPRequest 提交，这个就麻烦了，因为是不能跨域来提交的。</p>
<p>那么解决方法就是跨域产生 cookie，即 js 发现口令校验成功后，再在 passport.sohu.com 上种上合法的 cookie.</p>
<p>套用上面的跨域读 cookie 的方案似乎很简单去推论：就是创建一个隐含的 iframe，让那个 iframe 去调用
passport.sohu.com 的 URL 来产生 cookie。很遗憾，此方法在 Fx 下工作的很好，但是不能在 IE 上应用。（在
IE 状态栏上显示 cookie 隐私警告，红色圆底白横杠）</p>
<p>我试了很多很多方法，包括创建 、 node，包括用 js 设置，但都一次次被 IE 无情的挡在了浏览器外。google 之，也没有任何真正可用的答案，中文网页要么介绍的方法是错的，要么说无解。</p>
<p>最后还是在 chinaren 一哥们的帮助下，翻出了他们所使用的，以和 alumni.sohu.com 交互的方法（不知道是哪位牛人发现的），<strong>只需要设置 P3P HTTP Header</strong>，在隐含 iframe 里面跨域设置 cookie 就可以成功。他们所用的内容是：</p>
<p>P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"</p>
<p>最后是我做的一个小小的演示：cookie 怎么在 vmx.cn 和 dup2.net 之间交互</p>
<p>1. <a href="http://qiuyingbo.test.vmx.cn/cookie.php">http://qiuyingbo.test.vmx.cn/cookie.php</a></p>
<p>2. 随便输入什么，点 reset cookie，就可以看到 vmx.cn 的 cookie 已经被设上了</p>
<p>3. 在该页面点连接到 http://www.dup2.net/vmx/cookie.html</p>
<p>4. 点"get corss-domain cookie" .. （此时 js 会去创建一个iframe，请求 qiuyingbo.test.vmx.cn ，返回页面把 cookie 值作为 GET 参数重定向回 dup2.net 的另外一个URL。）</p>
<p>5. 点 "display corss-domain cookie" .. 就可以看到 vmx.cn 的 cookie 了</p>
<p>6. 在该页面的输入框中输入其它的值，然后点 "set cross-domain cookie"，该行为将主动设置 vmx.cn 的 cookie</p>
<p>7. 点链接回到 http://qiuyingbo.test.vmx.cn/cookie.php ，就可以看到新的值了</p>
<p><br />
</p>
<p><br />
</p>
<p><br />
</p>
<p>网上看了别人介绍的<a href="http://www.dup2.org/node/384" target="_blank">一片文章</a>，说使用P3P可以完成跨域COOKIE操作，感觉很COOL，不过没有提供源代码，我胡乱写了一下，大家看看。</p>
<p>实际工作中，类似这样的要求很多，比如说，我们有两个域名，我们想实现在一个域名登录后，能自动完成另一个域名的登录，也就是PASSPORT的功能。</p>
<p>我只写一个大概，为了测试的方便，先编辑hosts文件，加入测试域名（C:\WINDOWS\system32\drivers\etc\hosts）</p>
<p>127.0.0.1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;www.a.com<br />
127.0.0.1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;www.b.com</p>
<p>首先：创建&nbsp;a_setcookie.php&nbsp;文件，内容如下：</p>
<p><span style="color: #000000;"><span style="color: #0000bb;"><font face="NSimsun"><strong>&lt;?php&nbsp;<br />
</strong></font></span><font face="NSimsun"><strong><span style="color: #ff8000;">//header('P3P:&nbsp;CP="CURa&nbsp;ADMa&nbsp;DEVa&nbsp;PSAo&nbsp;PSDo&nbsp;OUR&nbsp;BUS&nbsp;UNI&nbsp;PUR&nbsp;INT&nbsp;DEM&nbsp;STA&nbsp;PRE&nbsp;COM&nbsp;NAV&nbsp;OTC&nbsp;NOI&nbsp;DSP&nbsp;COR"');&nbsp;<br />
<br />
</span><span style="color: #0000bb;">setcookie</span><span style="color: #007700;">(</span><span style="color: #dd0000;">"test"</span></strong><span style="color: #007700;"><strong>,&nbsp;</strong><span style="color: #0000bb;">$_GET</span><span style="color: #007700;">[</span><span style="color: #dd0000;">'id'</span><span style="color: #007700;">],&nbsp;</span></span><strong><span style="color: #0000bb;">time</span><span style="color: #007700;">()+</span><span style="color: #0000bb;">3600</span><span style="color: #007700;">,&nbsp;</span><span style="color: #dd0000;">"/"</span><span style="color: #007700;">,&nbsp;</span><span style="color: #dd0000;">".a.com"</span></strong></font><font face="NSimsun"><strong><span style="color: #007700;">);&nbsp;<br />
</span><span style="color: #0000bb;">?&gt;</span></strong></font></span></p>
<p>然后：创建&nbsp;a_getcookie.php&nbsp;文件，内容如下：</p>
<p><span style="color: #000000;"><font face="NSimsun"><strong><span style="color: #0000bb;">&lt;?php&nbsp;<br />
var_dump</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$_COOKIE</span></strong></font><font face="NSimsun"><strong><span style="color: #007700;">);&nbsp;<br />
</span><span style="color: #0000bb;">?&gt;</span></strong>&nbsp;</font></span></p>
<p>最后：创建&nbsp;b_setcookie.php&nbsp;文件，内容如下：</p>
<p><font face="NSimsun"><span style="color: #000000;"><strong>&lt;script&nbsp;src="</strong><strong>http://www.a.com/a_setcookie.php?id=www.b.com"&gt;&lt;/script</strong><strong>&gt;</strong></span></font></p>
<p><font face="新宋体">－－－－－－－－－－－－－－－－－－－－－－－－－－－－</font></p>
<p><font face="新宋体">三个文件创建完毕后，我们通过浏览器依次访问：</font></p>
<p>http://www.b.com/b_setcookie.php<br />
http://www.a.com/a_getcookie.php</p>
<p>我们会发现，在访问b.com域的时候，我们并没有在a.com域设置上cookie值。</p>
<p>然后我们修改一下a_setcookie.php文件，去掉注释符号，a_setcookie.php即为：</p>
<p><span style="color: #000000;"><span style="color: #0000bb;"><span style="color: #000000;"><font face="NSimsun"><span style="color: #0000bb;">&lt;?php&nbsp;&nbsp;<br />
header</span><span style="color: #007700;">(</span><span style="color: #dd0000;">'P3P:&nbsp;CP="CURa&nbsp;ADMa&nbsp;DEVa&nbsp;PSAo&nbsp;PSDo&nbsp;OUR&nbsp;BUS&nbsp;UNI&nbsp;PUR&nbsp;INT&nbsp;DEM&nbsp;STA&nbsp;PRE&nbsp;COM&nbsp;NAV&nbsp;OTC&nbsp;NOI&nbsp;DSP&nbsp;COR"'</span></font><font face="NSimsun"><span style="color: #007700;">);&nbsp;&nbsp;<br />
<br />
</span><span style="color: #0000bb;">setcookie</span><span style="color: #007700;">(</span><span style="color: #dd0000;">"test"</span><span style="color: #007700;">,&nbsp;</span><span style="color: #0000bb;">$_GET</span><span style="color: #007700;">[</span><span style="color: #dd0000;">'id'</span><span style="color: #007700;">],&nbsp;</span><span style="color: #0000bb;">time</span><span style="color: #007700;">()+</span><span style="color: #0000bb;">3600</span><span style="color: #007700;">,&nbsp;</span><span style="color: #dd0000;">"/"</span><span style="color: #007700;">,&nbsp;</span><span style="color: #dd0000;">".a.com"</span></font><font face="NSimsun"><span style="color: #007700;">);&nbsp;&nbsp;<br />
</span><span style="color: #0000bb;">?&gt;</span>&nbsp;</font></span></span></span></p>
<p>再次通过浏览器依次访问：</p>
<p>http://www.b.com/b_setcookie.php<br />
http://www.a.com/a_getcookie.php</p>
<p>这次，你会发现在访问b.com域的时候，我们设置了a.com域的cookie值。</p>
<p>末了补充一句，似乎只有IE对跨域访问COOKIE限制比较严格，上述代码在FIREFOX下测试，即使不发送P3P头信息，也能成功。不过IE是老大啊。</p>
<p>参考文档：<a href="http://www.w3.org/P3P/" target="_blank">http://www.w3.org/P3P/</a></p>
</div>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/250227.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2009-01-07 10:02 <a href="http://www.blogjava.net/wangxinsh55/archive/2009/01/07/250227.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>FreeMarker概述</title><link>http://www.blogjava.net/wangxinsh55/archive/2008/08/26/224559.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Tue, 26 Aug 2008 13:11:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2008/08/26/224559.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/224559.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2008/08/26/224559.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/224559.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/224559.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FreeMarker是一个模板引擎，一个基于模板生成文本输出的通用工具，使用纯Java编写                                                                        l&nbsp;&nbsp;&nbsp;&nbsp;&n...&nbsp;&nbsp;<a href='http://www.blogjava.net/wangxinsh55/archive/2008/08/26/224559.html'>阅读全文</a><img src ="http://www.blogjava.net/wangxinsh55/aggbug/224559.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2008-08-26 21:11 <a href="http://www.blogjava.net/wangxinsh55/archive/2008/08/26/224559.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jsp中文件下载的实现</title><link>http://www.blogjava.net/wangxinsh55/archive/2008/01/17/176006.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Thu, 17 Jan 2008 09:10:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2008/01/17/176006.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/176006.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2008/01/17/176006.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/176006.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/176006.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jsp中实现文件下载的最简单的方式是在网页上做超级链接，如：&lt;a href="music/abc.mp3"&gt;点击下载&lt;/a&gt;。但是这样服务器上的目录资源会直接暴露给最终用户，会给网站带来一些不安全的因素。因此可以采用其它方式实现下载，可以采用：1、RequestDispatcher的方式进行；2、采用文件流输出的方式下载。</p>
<p>1、采用RequestDispatcher的方式进行</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jsp页面中添加如下代码：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;%<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.setContentType("application/x-download");//设置为下载application/x-download<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String filedownload = "/要下载的文件名";//即将下载的文件的相对路径<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String filedisplay = "最终要显示给用户的保存文件名";//下载文件时显示的文件保存名称<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; filenamedisplay = URLEncoder.encode(filedisplay,"UTF-8");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.addHeader("Content-Disposition","attachment;filename=" + filedisplay);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RequestDispatcher dis = application.getRequestDispatcher(filedownload);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(dis!= null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dis.forward(request,response);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.flushBuffer();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(Exception e)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; finally<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
%&gt;</p>
<p>2、采用文件流输出的方式下载</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;%@page language="java" contentType="application/x-msdownload"&nbsp;&nbsp;&nbsp; pageEncoding="gb2312"%&gt;&lt;%<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //关于文件下载时采用文件流输出的方式处理：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<span style="color: red">加上response.reset()，并且<strong><em>所有的％&gt;后面不要换行，包括最后一个</em></strong>；<br />
</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.reset();//可以加也可以不加<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.setContentType("application/x-download");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String filedownload = "想办法找到要提供下载的文件的物理路径＋文件名";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String filedisplay = "给用户提供的下载文件名";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; filedisplay = URLEncoder.encode(filedisplay,"UTF-8");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.addHeader("Content-Disposition","attachment;filename=" + filedisplay);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OutputStream outp = null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileInputStream in = null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outp = response.getOutputStream();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; in = new FileInputStream(filenamedownload);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte[] b = new byte[1024];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i = 0;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while((i = in.read(b)) &gt; 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outp.write(b, 0, i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outp.flush();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(Exception e)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Error!");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; finally<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(in != null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; in.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; in = null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(outp != null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outp.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outp = null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
%&gt;<br />
<br />
在wsad里面写JSP文件下载,总是出现这个异常,getOutputStream() has already been called for this response,输出流已经被调用了. </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;上网查半天终于明白一点,JSP早下载文件的时候用到了OutputStream,而在Application Server在处理编译jsp时对于％&gt;和&lt;％之间的内容一般是原样输出，而且默认是PrintWriter.</p>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/176006.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2008-01-17 17:10 <a href="http://www.blogjava.net/wangxinsh55/archive/2008/01/17/176006.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>应用HttpClient来对付各种顽固的WEB服务器</title><link>http://www.blogjava.net/wangxinsh55/archive/2007/10/09/151300.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Tue, 09 Oct 2007 03:12:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2007/10/09/151300.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/151300.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2007/10/09/151300.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/151300.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/151300.html</trackback:ping><description><![CDATA[一般的情况下我们都是使用IE或者Navigator浏览器来访问一个WEB服务器，用来浏览页面查看信息或者提交一些数据等等。所访问的这些页面有的仅仅是一些普通的页面，有的需要用户登录后方可使用，或者需要认证以及是一些通过加密方式传输，例如HTTPS。目前我们使用的浏览器处理这些情况都不会构成问题。不过你可能在某些时候需要通过程序来访问这样的一些页面，比如从别人的网页中&#8220;偷&#8221;一些数据；利用某些站点提供的页面来完成某种功能，例如说我们想知道某个手机号码的归属地而我们自己又没有这样的数据，因此只好借助其他公司已有的网站来完成这个功能，这个时候我们需要向网页提交手机号码并从返回的页面中解析出我们想要的数据来。如果对方仅仅是一个很简单的页面，那我们的程序会很简单，本文也就没有必要大张旗鼓的在这里浪费口舌。但是考虑到一些服务授权的问题，很多公司提供的页面往往并不是可以通过一个简单的URL就可以访问的，而必须经过注册然后登录后方可使用提供服务的页面，这个时候就涉及到 COOKIE问题的处理。我们知道目前流行的动态网页技术例如ASP、JSP无不是通过COOKIE来处理会话信息的。为了使我们的程序能使用别人所提供的服务页面，就要求程序首先登录后再访问服务页面，这过程就需要自行处理cookie，想想当你用java.net.HttpURLConnection 来完成这些功能时是多么恐怖的事情啊！况且这仅仅是我们所说的顽固的WEB服务器中的一个很常见的&#8220;顽固&#8221;！再有如通过HTTP来上传文件呢？不需要头疼，这些问题有了&#8220;它&#8221;就很容易解决了！
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>我们不可能列举所有可能的顽固，我们会针对几种最常见的问题进行处理。当然了，正如前面说到的，如果我们自己使用 java.net.HttpURLConnection来搞定这些问题是很恐怖的事情，因此在开始之前我们先要介绍一下一个开放源码的项目，这个项目就是 Apache开源组织中的httpclient，它隶属于Jakarta的commons项目，目前的版本是2.0RC2。commons下本来已经有一个net的子项目，但是又把httpclient单独提出来，可见http服务器的访问绝非易事。</p>
<p>Commons-httpclient项目就是专门设计来简化HTTP客户端与服务器进行各种通讯编程。通过它可以让原来很头疼的事情现在轻松的解决，例如你不再管是HTTP或者HTTPS的通讯方式，告诉它你想使用HTTPS方式，剩下的事情交给httpclient替你完成。本文会针对我们在编写HTTP客户端程序时经常碰到的几个问题进行分别介绍如何使用httpclient来解决它们，为了让读者更快的熟悉这个项目我们最开始先给出一个简单的例子来读取一个网页的内容，然后循序渐进解决掉前进中的所有问题。</p>
<p>1．&nbsp;读取网页(HTTP/HTTPS)内容</p>
<p>下面是我们给出的一个简单的例子用来访问某个页面</p>
<p align="left"><span lang="EN-US">/*</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span>* Created on 2003-12-14 by Liudong</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span>*/</span></p>
<p align="left"><strong><span lang="EN-US">package</span></strong><span lang="EN-US"> <span>http.demo;</span></p>
<p align="left"><span lang="EN-US">&nbsp;</span></p>
<p align="left"><strong><span lang="EN-US">import</span></strong><span lang="EN-US"> <span>java.io.IOException;</span></p>
<p align="left"><span lang="EN-US">&nbsp;</span></p>
<p align="left"><strong><span lang="EN-US">import</span></strong><span lang="EN-US"> <span>org.apache.commons.httpclient.*;</span></p>
<p align="left"><strong><span lang="EN-US">import</span></strong><span lang="EN-US"> <span>org.apache.commons.httpclient.methods.*;</span></p>
<p align="left"><span lang="EN-US">/**</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span><span>*</span> </span><span>最简单的</span><span lang="EN-US">HTTP</span><span>客户端</span><span lang="EN-US">,</span><span>用来演示通过</span><span lang="EN-US">GET</span><span>或者</span><span lang="EN-US">POST</span><span>方式访问某个页面</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span><span>*</span> <strong><span>@author</span></strong> <span>Liudong</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span><span>*/</span></p>
<p align="left"><strong><span lang="EN-US">public</span></strong><span lang="EN-US"> <strong><span>class</span></strong> <span>SimpleClient</span> <span>{</span></p>
<p align="left"><span lang="EN-US">&nbsp;</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><strong><span>public</span></strong> <strong><span>static</span></strong> <strong><span>void</span></strong> <span>main(String[]</span> <span>args)</span> <strong><span>throws</span></strong> <span>IOException</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>{</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>HttpClient</span> <span>client</span> <span>=</span> <strong><span>new</span></strong> <span>HttpClient();</span><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>//</span><span>设置代理服务器地址和端口</span><span lang="EN-US"><span>&nbsp;</span><span>&nbsp;&nbsp;&nbsp; </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //client.getHostConfiguration().setProxy("proxy_host_addr",proxy_port);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span>//</span><span>使用</span><span lang="EN-US">GET</span><span>方法</span><span>，如果服务器需要通过</span><span lang="EN-US">HTTPS</span><span>连接，那只需要将下面</span><span lang="EN-US">URL</span><span>中的</span><span lang="EN-US">http</span><span>换成</span><span lang="EN-US">https</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>HttpMethod</span> <span>method</span> <span>=</span> <strong><span>new</span></strong> <span>GetMethod(</span><span>"http://java.sun.com"</span><span>);</span><span lang="EN-US"> </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>//</span><span>使用</span><span lang="EN-US">POST</span><span>方法</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>//HttpMethod method = new PostMethod("http://java.sun.com");</span><span lang="EN-US"> </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>client.executeMethod(method);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>//</span><span>打印服务器返回的状态</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>System.out.println(method.getStatusLine());</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>//</span><span>打印返回的信息</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>System.out.println(method.getResponseBodyAsString());</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>//</span><span>释放连接</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>method.releaseConnection();</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>}<br />
</span><span lang="EN-US">}</span></p>
<p align="left">&nbsp;</p>
<p align="left"><span lang="EN-US">在这个例子中首先创建一个HTTP客户端(HttpClient)的实例，然后选择提交的方法是GET或者POST，最后在HttpClient实例上执行提交的方法，最后从所选择的提交方法中读取服务器反馈回来的结果。这就是使用HttpClient的基本流程。其实用一行代码也就可以搞定整个请求的过程，非常的简单！</span></p>
<span lang="EN-US">
<p align="left"><br />
2．&nbsp;以GET或者POST方式向网页提交参数<br />
<br />
其实前面一个最简单的示例中我们已经介绍了如何使用GET或者POST方式来请求一个页面，本小节与之不同的是多了提交时设定页面所需的参数，我们知道如果是GET的请求方式，那么所有参数都直接放到页面的URL后面用问号与页面地址隔开，每个参数用&amp;隔开，例如：<a href="http://java.sun.com/?name=liudong&amp;mobile=123456">http://java.sun.com?name=liudong&amp;mobile=123456</a>，但是当使用POST方法时就会稍微有一点点麻烦。本小节的例子演示向如何查询手机号码所在的城市，代码如下：</p>
<p align="left">&nbsp;</p>
<p align="left"><span lang="EN-US">/*</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span>* Created on 2003-12-7 by Liudong</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span>*/</span></p>
<p align="left"><strong><span lang="EN-US">package</span></strong><span lang="EN-US"> <span>http.demo;</span></p>
<p align="left"><span lang="EN-US">&nbsp;</span></p>
<p align="left"><strong><span lang="EN-US">import</span></strong><span lang="EN-US"> <span>java.io.IOException;</span></p>
<p align="left"><span lang="EN-US">&nbsp;</span></p>
<p align="left"><strong><span lang="EN-US">import</span></strong><span lang="EN-US"> <span>org.apache.commons.httpclient.*;</span></p>
<p align="left"><strong><span lang="EN-US">import</span></strong><span lang="EN-US"> <span>org.apache.commons.httpclient.methods.*;</span></p>
<p align="left"><span lang="EN-US">/**</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span><span>*</span> </span><span>提交参数演示</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span><span>*</span> </span><span>该程序连接到一个用于查询手机号码所属地的页面</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span><span>*</span> </span><span>以便查询号码段</span><span lang="EN-US">1330227</span><span>所在的省份以及城市</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span><span>*</span> <strong><span>@author</span></strong> <span>Liudong</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span><span>*/</span></p>
<p align="left"><strong><span lang="EN-US">public</span></strong><span lang="EN-US"> <strong><span>class</span></strong> <span>SimpleHttpClient</span> <span>{</span></p>
<p align="left"><span lang="EN-US">&nbsp;</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><strong><span>public</span></strong> <strong><span>static</span></strong> <strong><span>void</span></strong> <span>main(String[]</span> <span>args)</span> <strong><span>throws</span></strong> <span>IOException</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>{</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>HttpClient</span> <span>client</span> <span>=</span> <strong><span>new</span></strong> <span>HttpClient();</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>client.getHostConfiguration().setHost(</span><span>"www.imobile.com.cn"</span><span>,</span> <span>80,</span> <span>"http"</span><span>);</span></p>
<p align="left"><span lang="EN-US">&nbsp;</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>HttpMethod</span> <span>method</span> <span>=</span> <span>getPostMethod();</span><span>//</span><span>使用</span><span lang="EN-US">POST</span><span>方式提交数据</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>client.executeMethod(method);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>//</span><span>打印服务器返回的状态</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>System.out.println(method.getStatusLine());</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>//</span><span>打印</span><span>结果页面</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>String</span> <span>response</span> <span>=</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><strong><span>new</span></strong> <span>String(method.getResponseBodyAsString().getBytes(</span><span>"8859_1"</span><span>));</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>//</span><span>打印返回的信息</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>System.out.println(response);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>method.releaseConnection();</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>}</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>/**</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;</span><span>*</span> </span><span>使用</span><span lang="EN-US">GET</span><span>方式提交数据</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;</span><span>*</span> <strong><span>@return</span></strong></span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;</span><span>*/</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><strong><span>private</span></strong> <strong><span>static</span></strong> <span>HttpMethod</span> <span>getGetMethod(){</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><strong><span>return</span></strong> <strong><span>new</span></strong> <span>GetMethod(</span><span>"/simcard.php?simcard=1330227"</span><span>);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>}</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>/**</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;</span><span>*</span> </span><span>使用</span><span lang="EN-US">POST</span><span>方式提交数据</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;</span><span>*</span> <strong><span>@return</span></strong></span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;</span><span>*/</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><strong><span>private</span></strong> <strong><span>static</span></strong> <span>HttpMethod</span> <span>getPostMethod(){</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>PostMethod</span> <span>post</span> <span>=</span> <strong><span>new</span></strong> <span>PostMethod(</span><span>"/simcard.php"</span><span>);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>NameValuePair</span> <span>simcard</span> <span>=</span> <strong><span>new</span></strong> <span>NameValuePair(</span><span>"simcard"</span><span>,</span><span>"1330227"</span><span>);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>post.setRequestBody(</span><strong><span>new</span></strong> <span>NameValuePair[]</span> <span>{</span> <span>simcard});</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><strong><span>return</span></strong> <span>post;</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>}</span></p>
<p align="left"><span lang="EN-US">}</span></p>
<p><span lang="EN-US">在上面的例子中页面<a href="http://www.imobile.com.cn/simcard.php">http://www.imobile.com.cn/simcard.php</a>需要一个参数是simcard，这个参数值为手机号码段，即手机号码的前七位，服务器会返回提交的手机号码对应的省份、城市以及其他详细信息。GET的提交方法只需要在URL后加入参数信息，而POST则需要通过NameValuePair类来设置参数名称和它所对应的值</span></p>
<p><span lang="EN-US">3．&nbsp;处理页面重定向</span></p>
<p><span lang="EN-US">在JSP/Servlet 编程中response.sendRedirect方法就是使用HTTP协议中的重定向机制。它与JSP中的&lt;jsp:forward &#8230;&gt;的区别在于后者是在服务器中实现页面的跳转，也就是说应用容器加载了所要跳转的页面的内容并返回给客户端；而前者是返回一个状态码，这些状态码的可能值见下表，然后客户端读取需要跳转到的页面的URL并重新加载新的页面。就是这样一个过程，所以我们编程的时候就要通过 HttpMethod.getStatusCode()方法判断返回值是否为下表中的某个值来判断是否需要跳转。如果已经确认需要进行页面跳转了，那么可以通过读取HTTP头中的location属性来获取新的地址。</span></p>
<span lang="EN-US">
<p>
<table cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td valign="top" width="67">
            <p><span>状态码</span></p>
            </td>
            <td valign="top" width="216">
            <p><span>对应</span><span lang="EN-US"><font face="Times New Roman">HttpServletResponse</font></span><span>的常量</span></p>
            </td>
            <td valign="top" width="261">
            <p><span>详细描述</span></p>
            </td>
        </tr>
        <tr>
            <td valign="top" width="67">
            <p><span lang="EN-US"><font face="Times New Roman">301</font></span></p>
            </td>
            <td valign="top" width="216">
            <p><span lang="EN-US"><font face="Times New Roman">SC_MOVED_PERMANENTLY</font></span></p>
            </td>
            <td valign="top" width="261">
            <p><span>页面已经永久移到另外一个新地址</span></p>
            </td>
        </tr>
        <tr>
            <td valign="top" width="67">
            <p><span lang="EN-US"><font face="Times New Roman">302</font></span></p>
            </td>
            <td valign="top" width="216">
            <p><span lang="EN-US"><font face="Times New Roman">SC_MOVED_TEMPORARILY</font></span></p>
            </td>
            <td valign="top" width="261">
            <p><span>页面暂时移动到另外一个新的地址</span></p>
            </td>
        </tr>
        <tr>
            <td valign="top" width="67">
            <p><span lang="EN-US"><font face="Times New Roman">303</font></span></p>
            </td>
            <td valign="top" width="216">
            <p><span lang="EN-US"><font face="Times New Roman">SC_SEE_OTHER</font></span></p>
            </td>
            <td valign="top" width="261">
            <p><span>客户端请求的地址必须通过另外的</span><span lang="EN-US"><font face="Times New Roman">URL</font></span><span>来访问</span></p>
            </td>
        </tr>
        <tr>
            <td valign="top" width="67">
            <p><span lang="EN-US"><font face="Times New Roman">307</font></span></p>
            </td>
            <td valign="top" width="216">
            <p><span lang="EN-US"><font face="Times New Roman">SC_TEMPORARY_REDIRECT</font></span></p>
            </td>
            <td valign="top" width="261">
            <p><span>同</span><span lang="EN-US"><font face="Times New Roman">SC_MOVED_TEMPORARILY</font></span></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p>下面的代码片段演示如何处理页面的重定向</p>
<p align="left"><span lang="EN-US">client.executeMethod(post);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>System.out.println(post.getStatusLine().toString());</span> </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>post.releaseConnection();</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>//</span><span>检查是否重定向</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span>int</span></strong> <span>statuscode</span> <span>=</span> <span>post.getStatusCode();</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span>if</span></strong> <span>((statuscode</span> <span>==</span> <span>HttpStatus.SC_MOVED_TEMPORARILY)</span> <span>||</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>(statuscode</span> <span>==</span> <span>HttpStatus.SC_MOVED_PERMANENTLY)</span> <span>||</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>(statuscode</span> <span>==</span> <span>HttpStatus.SC_SEE_OTHER)</span> <span>||</span></p>
<p align="left"><span lang="EN-US">(statuscode</span><span lang="EN-US"> <span>==</span> <span>HttpStatus.SC_TEMPORARY_REDIRECT))</span> <span>{</span></p>
<p align="left"><span lang="EN-US">//</span><span>读取新的</span><span lang="EN-US">URL</span><span>地址</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>Header</span> <span>header</span> <span>=</span> <span>post.getResponseHeader(</span><span>"location"</span><span>);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span>if</span></strong> <span>(header</span> <span>!=</span> <strong><span>null</span></strong><span>)</span> <span>{</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>String</span> <span>newuri</span> <span>=</span> <span>header.getValue();</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span>if</span></strong> <span>((newuri</span> <span>==</span> <strong><span>null</span></strong><span>)</span> <span>||</span> <span>(newuri.equals(</span><span>""</span><span>)))</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>newuri</span> <span>=</span> <span>"/"</span><span>;</span> </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>GetMethod</span> <span>redirect</span> <span>=</span> <strong><span>new</span></strong> <span>GetMethod(newuri);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>client.executeMethod(redirect);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>System.out.println(</span><span>"Redirect:"</span><span>+</span> <span>redirect.getStatusLine().toString());</span> </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>redirect.releaseConnection();</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>}</span> <strong><span>else</span></strong> </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>System.out.println(</span><span>"Invalid redirect"</span><span>);</span></p>
<p><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>}</span></p>
<p>我们可以自行编写两个JSP页面，其中一个页面用response.sendRedirect方法重定向到另外一个页面用来测试上面的例子。</p>
<p>4．&nbsp;模拟输入用户名和口令进行登录</p>
<p>本小节应该说是HTTP客户端编程中最常碰见的问题，很多网站的内容都只是对注册用户可见的，这种情况下就必须要求使用正确的用户名和口令登录成功后，方可浏览到想要的页面。因为HTTP协议是无状态的，也就是连接的有效期只限于当前请求，请求内容结束后连接就关闭了。在这种情况下为了保存用户的登录信息必须使用到Cookie机制。以JSP/Servlet为例，当浏览器请求一个JSP或者是Servlet的页面时，应用服务器会返回一个参数，名为jsessionid（因不同应用服务器而异），值是一个较长的唯一字符串的Cookie，这个字符串值也就是当前访问该站点的会话标识。浏览器在每访问该站点的其他页面时候都要带上jsessionid这样的Cookie信息，应用服务器根据读取这个会话标识来获取对应的会话信息。</p>
<p>对于需要用户登录的网站，一般在用户登录成功后会将用户资料保存在服务器的会话中，这样当访问到其他的页面时候，应用服务器根据浏览器送上的 Cookie中读取当前请求对应的会话标识以获得对应的会话信息，然后就可以判断用户资料是否存在于会话信息中，如果存在则允许访问页面，否则跳转到登录页面中要求用户输入帐号和口令进行登录。这就是一般使用JSP开发网站在处理用户登录的比较通用的方法。</p>
<p>这样一来，对于HTTP的客户端来讲，如果要访问一个受保护的页面时就必须模拟浏览器所做的工作，首先就是请求登录页面，然后读取Cookie值；再次请求登录页面并加入登录页所需的每个参数；最后就是请求最终所需的页面。当然在除第一次请求外其他的请求都需要附带上Cookie信息以便服务器能判断当前请求是否已经通过验证。说了这么多，可是如果你使用httpclient的话，你甚至连一行代码都无需增加，你只需要先传递登录信息执行登录过程，然后直接访问想要的页面，跟访问一个普通的页面没有任何区别，因为类HttpClient已经帮你做了所有该做的事情了，太棒了！下面的例子实现了这样一个访问的过程。<br />
</p>
<p align="left"><span lang="EN-US">/*</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span>* Created on 2003-12-7 by Liudong</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span>*/</span></p>
<p align="left"><strong><span lang="EN-US">package</span></strong><span lang="EN-US"> <span>http.demo;</span></p>
<p align="left"><span lang="EN-US">&nbsp;</span></p>
<p align="left"><strong><span lang="EN-US">import</span></strong><span lang="EN-US"> <span>org.apache.commons.httpclient.*;</span></p>
<p align="left"><strong><span lang="EN-US">import</span></strong><span lang="EN-US"> <span>org.apache.commons.httpclient.cookie.*;</span></p>
<p align="left"><strong><span lang="EN-US">import</span></strong><span lang="EN-US"> <span>org.apache.commons.httpclient.methods.*;</span></p>
<p align="left"><span lang="EN-US">&nbsp;</span></p>
<p align="left"><span lang="EN-US">/**</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span><span>*</span> </span><span>用来演示登录表单的示例</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span><span>*</span> <strong><span>@author</span></strong> <span>Liudong</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span><span>*/</span></p>
<p align="left"><strong><span lang="EN-US">public</span></strong><span lang="EN-US"> <strong><span>class</span></strong> <span>FormLoginDemo</span> <span>{</span></p>
<p align="left"><span lang="EN-US">&nbsp;</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><strong><span>static</span></strong> <strong><span>final</span></strong> <span>String</span> <span>LOGON_SITE</span> <span>=</span> <span>"localhost"</span><span>;</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><strong><span>static</span></strong> <strong><span>final</span></strong> <strong><span>int</span></strong><span>&nbsp;&nbsp;&nbsp; </span><span>LOGON_PORT</span> <span>=</span> <span>8080;</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><strong><span>public</span></strong> <strong><span>static</span></strong> <strong><span>void</span></strong> <span>main(String[]</span> <span>args)</span> <strong><span>throws</span></strong> <span>Exception{</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>HttpClient</span> <span>client</span> <span>=</span> <strong><span>new</span></strong> <span>HttpClient();</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>client.getHostConfiguration().setHost(LOGON_SITE,</span> <span>LOGON_PORT);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>//</span><span>模拟登录页面</span><span lang="EN-US">login.jsp-&gt;main.jsp</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>PostMethod</span> <span>post</span> <span>=</span> <strong><span>new</span></strong> <span>PostMethod(</span><span>"/main.jsp"</span><span>);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>NameValuePair</span> <span>name</span> <span>=</span> <strong><span>new</span></strong> <span>NameValuePair(</span><span>"name"</span><span>,</span> <span>"ld"</span><span>);</span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>NameValuePair</span> <span>pass</span> <span>=</span> <strong><span>new</span></strong> <span>NameValuePair(</span><span>"password"</span><span>,</span> <span>"ld"</span><span>);</span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>post.setRequestBody(</span><strong><span>new</span></strong> <span>NameValuePair[]{name,pass});</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span>int</span></strong> <span>status</span> <span>=</span> <span>client.executeMethod(post);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>System.out.println(post.getResponseBodyAsString());</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>post.releaseConnection();</span><span>&nbsp; </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>//</span><span>查看</span><span lang="EN-US">cookie</span><span>信息</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>CookieSpec</span> <span>cookiespec</span> <span>=</span> <span>CookiePolicy.getDefaultSpec();</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>Cookie[]</span> <span>cookies</span> <span>=</span> <span>cookiespec.match(LOGON_SITE,</span> <span>LOGON_PORT,</span> <span>"/"</span><span>,</span> <strong><span>false</span></strong><span>,</span> <span>client.getState().getCookies());</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span>if</span></strong> <span>(cookies.length</span> <span>==</span> <span>0)</span> <span>{</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>System.out.println(</span><span>"None"</span><span>);</span><span>&nbsp;&nbsp;&nbsp; </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>}</span> <strong><span>else</span></strong> <span>{</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><strong><span>for</span></strong> <span>(</span><strong><span>int</span></strong> <span>i</span> <span>=</span> <span>0;</span> <span>i</span> <span>&lt;</span> <span>cookies.length;</span> <span>i++)</span> <span>{</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>System.out.println(cookies[i].toString());</span><span>&nbsp;&nbsp;&nbsp; </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>}</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>}</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>//</span><span>访问所需的页面</span><span lang="EN-US">main2.jsp</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>GetMethod</span> <span>get</span> <span>=</span> <strong><span>new</span></strong> <span>GetMethod(</span><span>"/main2.jsp"</span><span>);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>client.executeMethod(get);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>System.out.println(get.getResponseBodyAsString());</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span><span>get.releaseConnection();</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>}</span></p>
<p><span lang="EN-US">}</span></p>
<p><span lang="EN-US">5．&nbsp;提交XML格式参数</span></p>
<p><span lang="EN-US">提交XML格式的参数很简单，仅仅是一个提交时候的ContentType问题，下面的例子演示从文件文件中读取XML信息并提交给服务器的过程，该过程可以用来测试Web服务。</span></p>
<span lang="EN-US">
<p align="left"><strong><span lang="EN-US">import</span></strong><span lang="EN-US"> <span>java.io.File;</span></p>
<p align="left"><strong><span lang="EN-US">import</span></strong><span lang="EN-US"> <span>java.io.FileInputStream;</span></p>
<p align="left"><span lang="EN-US">&nbsp;</span></p>
<p align="left"><strong><span lang="EN-US">import</span></strong><span lang="EN-US"> <span>org.apache.commons.httpclient.HttpClient;</span></p>
<p align="left"><strong><span lang="EN-US">import</span></strong><span lang="EN-US"> <span>org.apache.commons.httpclient.methods.EntityEnclosingMethod;</span></p>
<p align="left"><strong><span lang="EN-US">import</span></strong><span lang="EN-US"> <span>org.apache.commons.httpclient.methods.PostMethod;</span></p>
<p align="left"><span lang="EN-US">&nbsp;</span></p>
<p align="left"><span lang="EN-US">/**</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span><span>*</span> </span><span>用来演示提交</span><span lang="EN-US">XML</span><span>格式数据的例子</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;</span><span>*/</span></p>
<p align="left"><strong><span lang="EN-US">public</span></strong><span lang="EN-US"> <strong><span>class</span></strong> <span>PostXMLClient</span> <span>{</span></p>
<p align="left"><span lang="EN-US">&nbsp;</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><strong><span>public</span></strong> <strong><span>static</span></strong> <strong><span>void</span></strong> <span>main(String[]</span> <span>args)</span> <strong><span>throws</span></strong> <span>Exception</span> <span>{</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>File</span> <span>input</span> <span>=</span> <strong><span>new</span></strong> <span>File(&#8220;test.xml&#8221;);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>PostMethod</span> <span>post</span> <span>=</span> <strong><span>new</span></strong> <span>PostMethod(&#8220;http://localhost:8080/httpclient/xml.jsp&#8221;);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>// </span><span>设置请求的内容直接从文件中读取</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>post.setRequestBody(</span><strong><span>new</span></strong> <span>FileInputStream(input));</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span>if</span></strong> <span>(input.length()</span> <span>&lt;</span> <span>Integer.MAX_VALUE)</span> </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>post.setRequestContentLength(input.length());</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span>else</span></strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>post.setRequestContentLength(EntityEnclosingMethod.CONTENT_LENGTH_CHUNKED);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>// </span><span>指定请求内容的类型</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span>post.setRequestHeader(</span><span>"Content-type"</span><span>,</span> <span>"text/xml; charset=GBK"</span><span>);</span></strong></span><strong></strong></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;</span><span>HttpClient</span> <span>httpclient</span> <span>=</span> <strong><span>new</span></strong> <span>HttpClient();</span> </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span>int</span></strong> <span>result</span> <span>=</span> <span>httpclient.executeMethod(post);</span> </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>System.out.println(</span><span>"Response status code: "</span> <span>+</span> <span>result);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>System.out.println(</span><span>"Response body: "</span><span>);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>System.out.println(post.getResponseBodyAsString());</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>post.releaseConnection();</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>}</span></p>
<p><span lang="EN-US">}</span></p>
<p><span lang="EN-US">6．&nbsp;通过HTTP上传文件</span></p>
<p><span lang="EN-US">httpclient使用了单独的一个HttpMethod子类来处理文件的上传，这个类就是MultipartPostMethod，该类已经封装了文件上传的细节，我们要做的仅仅是告诉它我们要上传文件的全路径即可，下面的代码片段演示如何使用这个类。</span></p>
<span lang="EN-US">
<p align="left"><span lang="EN-US">MultipartPostMethod</span><span lang="EN-US"> <span>filePost</span> <span>=</span> <strong><span>new</span></strong> <span>MultipartPostMethod(targetURL);</span></p>
<p align="left"><span lang="EN-US">filePost.addParameter(</span><span lang="EN-US">"fileName"</span><span lang="EN-US">,</span><span lang="EN-US"> <span>targetFilePath);</span></p>
<p align="left"><span lang="EN-US">HttpClient</span><span lang="EN-US"> <span>client</span> <span>=</span> <strong><span>new</span></strong> <span>HttpClient();</span></p>
<p align="left"><span lang="EN-US">//</span><span>由于要上传的文件可能比较大</span><span lang="EN-US">,</span><span>因此在此设置最大的连接超时时间</span></p>
<p align="left"><span lang="EN-US">client.getHttpConnectionManager().</span><span lang="EN-US"><span>getParams().setConnectionTimeout(5000);</span></p>
<p><strong><span lang="EN-US">int</span></strong><span lang="EN-US"> <span>status</span> <span>=</span> <span>client.executeMethod(filePost);</span><br />
</p>
</span>
<p>&nbsp;</p>
<p>上面代码中，targetFilePath即为要上传的文件所在的路径。</p>
<p>7．&nbsp;访问启用认证的页面</p>
<p>我们经常会碰到这样的页面，当访问它的时候会弹出一个浏览器的对话框要求输入用户名和密码后方可，这种用户认证的方式不同于我们在前面介绍的基于表单的用户身份验证。这是HTTP的认证策略，httpclient支持三种认证方式包括：基本、摘要以及NTLM认证。其中基本认证最简单、通用但也最不安全；摘要认证是在HTTP 1.1中加入的认证方式，而NTLM则是微软公司定义的而不是通用的规范，最新版本的NTLM是比摘要认证还要安全的一种方式。</p>
<p>下面例子是从httpclient的CVS服务器中下载的，它简单演示如何访问一个认证保护的页面：<br />
</p>
<p align="left"><strong><span lang="EN-US">import</span></strong><span lang="EN-US"> <span>org.apache.commons.httpclient.HttpClient;</span></p>
<p align="left"><strong><span lang="EN-US">import</span></strong><span lang="EN-US"> <span>org.apache.commons.httpclient.UsernamePasswordCredentials;</span></p>
<p align="left"><strong><span lang="EN-US">import</span></strong><span lang="EN-US"> <span>org.apache.commons.httpclient.methods.GetMethod;</span></p>
<p align="left"><span lang="EN-US">&nbsp;</span></p>
<p align="left"><strong><span lang="EN-US">public</span></strong><span lang="EN-US"> <strong><span>class</span></strong> <span>BasicAuthenticationExample</span> <span>{</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><strong><span>public</span></strong> <span>BasicAuthenticationExample()</span> <span>{</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>}</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp; </span><span>&nbsp;</span><strong><span>public</span></strong> <strong><span>static</span></strong> <strong><span>void</span></strong> <span>main(String[]</span> <span>args)</span> <strong><span>throws</span></strong> <span>Exception</span> <span>{</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>HttpClient</span> <span>client</span> <span>=</span> <strong><span>new</span></strong> <span>HttpClient();</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>client.getState().setCredentials(</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>"www.verisign.com"</span><span>,</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>"realm"</span><span>,</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span>new</span></strong> <span>UsernamePasswordCredentials(</span><span>"username"</span><span>,</span> <span>"password"</span><span>)</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>GetMethod</span> <span>get</span> <span>=</span> <strong><span>new</span></strong> <span>GetMethod(</span><span>"https://www.verisign.com/products/index.html"</span><span>);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>get.setDoAuthentication(</span> <strong><span>true</span></strong> <span>);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span>int</span></strong> <span>status</span> <span>=</span> <span>client.executeMethod(</span> <span>get</span> <span>);</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>System.out.println(status+</span><span>"\n"</span><span>+</span> <span>get.getResponseBodyAsString());</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>get.releaseConnection();</span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span><span>}</span></p>
<p><span lang="EN-US">}</span></p>
<p><span lang="EN-US">8．&nbsp;多线程模式下使用httpclient</span></p>
<p><span lang="EN-US">多线程同时访问httpclient，例如同时从一个站点上下载多个文件。对于同一个HttpConnection同一个时间只能有一个线程访问，为了保证多线程工作环境下不产生冲突，httpclient使用了一个多线程连接管理器的类： MultiThreadedHttpConnectionManager，要使用这个类很简单，只需要在构造HttpClient实例的时候传入即可，代码如下：</span></p>
<span lang="EN-US">
<p align="left"><span lang="EN-US">MultiThreadedHttpConnectionManager</span><span lang="EN-US"> <span>connectionManager</span> <span>=</span> </span></p>
<p align="left"><span lang="EN-US"><span>&nbsp;&nbsp; </span><strong><span>new</span></strong> <span>MultiThreadedHttpConnectionManager();</span></p>
<p><span lang="EN-US"><span>HttpClient</span> <span>client</span> <span>=</span> <strong><span>new</span></strong> <span>HttpClient(connectionManager);</span></p>
<p><span lang="EN-US"><span>以后尽管访问client实例即可。</span></p>
<p><span lang="EN-US"><span>参考资料：</span></p>
<p><span lang="EN-US"><span>httpclient首页：&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://jakarta.apache.org/commons/httpclient/">http://jakarta.apache.org/commons/httpclient/</a><br />
关于NTLM是如何工作：&nbsp;&nbsp;<a href="http://davenport.sourceforge.net/ntlm.html">http://davenport.sourceforge.net/ntlm.html</a> </span></p>
</span></span></td>
</tr>
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/151300.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2007-10-09 11:12 <a href="http://www.blogjava.net/wangxinsh55/archive/2007/10/09/151300.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> JSTL教程 </title><link>http://www.blogjava.net/wangxinsh55/archive/2007/08/10/135808.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Fri, 10 Aug 2007 06:01:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2007/08/10/135808.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/135808.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2007/08/10/135808.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/135808.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/135808.html</trackback:ping><description><![CDATA[JSP 标准标记库（JSP Standard Tag Library，JSTL）是一个实现 Web 应用程序中常见的通用功能的定制标记库集，这些功能包括迭代和条件判断、数据管理格式化、XML 操作以及数据库访问。在 developerWorks 上其新系列的第一篇文章中，软件工程师 Mark Kolb 向您展示了如何使用 JSTL 标记来避免在 JSP 页面中使用脚本编制元素。您还将了解如何通过从表示层删除源代码来简化软件维护。最后，您将了解 JSTL 经过简化的表达式语言，它允许在不必使用功能齐全的编程语言的情况下对 JSTL 操作指定动态属性值。 <br>
<div class=postText><br>　　 JavaServer Pages（JSP）是用于 J2EE 平台的标准表示层技术。JSP 技术提供了用于执行计算（这些计算用来动态地生成页面内容）的脚本编制元素和操作。脚本编制元素允许在 JSP 页面中包括程序源代码，在为响应用户请求而呈现页面时可以执行这些源代码。操作将计算操作封装到很象 HTML 或 XML 标记的标记中，JSP 页面的模板文本通常包含这些标记。JSP 规范只将几种操作定义成了标准，但从 JSP 1.1 开始，开发人员已经能够以定制标记库的方式创建其自己的操作了。 <br><br>　　 JSP 标准标记库（JSTL）是 JSP 1.2 定制标记库集，这些标记库实现大量服务器端 Java 应用程序常用的基本功能。通过为典型表示层任务（如数据格式化和迭代或条件内容）提供标准实现，JSTL 使 JSP 作者可以专注于特定于应用程序的开发需求，而不是为这些通用操作&#8220;另起炉灶&#8221;。 <br><br>　　 当然，您可以使用 JSP 脚本编制元素（scriptlet、表达式和声明）来实现此类任务。例如，可以使用三个 scriptlet 实现条件内容，清单 1 中着重显示了这三个 scriptlet。但是，因为脚本编制元素依赖于在页面中嵌入程序源代码（通常是 Java 代码），所以对于使用这些脚本编制元素的 JSP 页面，其软件维护任务的复杂度大大增加了。例如，清单 1 中的 scriptlet 示例严格地依赖于花括号的正确匹配。如果不经意间引入了一个语法错误，则条件内容中的嵌套其它 scriptlet 可能会造成严重破坏，并且在 JSP 容器编译该页面时，要使所产生的错误信息有意义可能会很困难。 <br><br><ccid_code></ccid_code>　　清单 1. 通过 scriptlet 实现条件内容 &lt;% if (user.getRole() == "member")) { %&gt; <br><br><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code></ccid_code>&lt;p&gt;Welcome, member!&lt;/p&gt;<br>&lt;% } else { %&gt;<br>    &lt;p&gt;Welcome, guest!&lt;/p&gt;<br>&lt;% } %&gt;</pre>
            </td>
        </tr>
    </tbody>
</table>
<br><br><ccid_code></ccid_code>　　修正此类问题通常需要相当丰富的编程经验。尽管通常会由十分精通页面布局和图形设计 的设计人员来开发和维护 JSP，但是同一页面中的脚本编制元素出现问题时，需要程序员的介入。这种状况将单个文件中代码的责任分担给多人，因而使得开发、调试和增强此类 JSP 页面成为很麻烦的任务。通过将常用功能包装到定制标记库的标准集合中，JSTL 使 JSP 作者可以减少对编制脚本元素的需求，甚至可以不需要它们，并避免了相关的维护成本。 <br><br>　　 <strong>JSTL 1.0</strong> <br><br><ccid_code></ccid_code>　 　JSTL 1.0 发布于 2002 年 6 月，由四个定制标记库（core、format、xml 和 sql）和一对通用标记库验证器（ScriptFreeTLV 和 PermittedTaglibsTLV）组成。core 标记库提供了定制操作，通过限制了作用域的变量管理数据，以及执行页面内容的迭代和条件操作。它还提供了用来生成和操作 URL 的标记。顾名思义，format 标记库定义了用来格式化数据（尤其是数字和日期）的操作。它还支持使用本地化资源束进行 JSP 页面的国际化。xml 库包含一些标记，这些标记用来操作通过 XML 表示的数据，而 sql 库定义了用来查询关系数据库的操作。 <br><br>　 　 两个 JSTL 标记库验证器允许开发人员在其 JSP 应用程序中强制使用编码标准。可以配置 ScriptFreeTLV 验证器以在 JSP 页面中禁用各种类型的 JSP 脚本元素 — scriptlet、表达式和声明。类似地，PermittedTaglibsTLV 验证器可以用来限制可能由应用程序的 JSP 页面访问的定制标记库集（包括 JSTL 标记库）。 <br><br>　　 尽管 JSTL 最终将会成为 J2EE 平台的必需组件，但目前只有少数应用程序服务器包括它。JSTL 1.0 的参考实现可作为 Apache 软件基金会（Apache Software Foundation）的 Jakarta Taglibs 项目（请参阅参考资料）的一部分而获得。可以将该参考实现中的定制标记库合并到任何支持 JSP 1.2 和 Servlet 2.3 规范的服务器，以添加对 JSTL 的支持。 <br><br>　　 <strong>表达式语言</strong> <br><br><ccid_code></ccid_code>　 　在 JSP 1.2 中，可以使用静态字符串或表达式（如果允许的话）指定 JSP 操作的属性。例如，在清单 2 中，对 &lt;jsp:setProperty&gt; 操作的 name 和 property 属性指定了静态值，而用表达式指定了其 value 属性。这个操作的效果是将请求参数的当前值赋予命名的 bean 特性。以这种形式使用的表达式被称为请求时属性值（request-time attribute value），这是构建到 JSP 规范中的用于动态指定属性值的唯一机制。 <br><br>　　 清单 2. 合并请求时属性值的 JSP 操作 <br><br><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code></ccid_code>&lt;jsp:setProperty name="user" property="timezonePref"<br>                 value='&lt;%= request.getParameter("timezone") %&gt;'/&gt;</pre>
            </td>
        </tr>
    </tbody>
</table>
<br><br><ccid_code></ccid_code>　　因为请求时属性值是用表达式指定的，所以它们往往有和其它脚本元素一样的软件维护问 题。因此，JSTL 定制标记支持另一种用于指定动态属性值的机制。可以用简化的表达式语言（EL）而不使用完整的 JSP 表达式来指定 JSTL 操作的属性值。EL 提供了一些标识符、存取器和运算符，用来检索和操作驻留在 JSP 容器中的数据。EL 在某种程度上以 EcmaScript（请参阅参考资料）和 XML 路径语言（XML Path Language，XPath）为基础，因此页面设计人员和程序员都应该熟悉它的语法。EL 擅长寻找对象及其特性，然后对它们执行简单操作；它不是编程语言，甚至不是脚本编制语言。但是，与 JSTL 标记一起使用时，它就能使用简单而又方便的符号来表示复杂的行为。EL 表达式的格式是这样的：用美元符号（$）定界，内容包括在花括号（{}）中，如清单 3 所示。 <br><br>　　 清单 3. 说明 EL 表达式定界符的 JSTL 操作 <br><br>　　 &lt;c:out value="${user.firstName}"/&gt; <br><br><ccid_code></ccid_code>　 　此外，您可以将多个表达式与静态文本组合在一起以通过字符串并置来构造动态属性值，如清单 4 所示。单独的表达式由标识符、存取器、文字和运算符组成。标识符用来引用存储在数据中心中的数据对象。EL 有 11 个保留标识符，对应于 11 个 EL 隐式对象。假定所有其它标识符都引用限制了作用域的变量。存取器用来检索对象的特性或集合的元素。文字表示固定的值 — 数字、字符、字符串、布尔型或空值。运算符允许对数据和文字进行组合以及比较。 <br><br>　　 清单 4. 组合静态文本和多个 EL 表达式以指定动态属性值 <br><br>　　 &lt;c:out value="Hello ${user.firstName} ${user.lastName}"/&gt; <br><br>　　 <strong>限制了作用域的变量</strong> <br><br><ccid_code></ccid_code>　 　JSP API 通过 &lt;jsp:useBean&gt; 操作允许从 JSP 容器内的四个不同作用域中存储和检索数据。JSTL 通过提供用于指定和除去这些作用域中的对象的附加操作来扩展这一能力。此外，EL 提供将这些对象作为限制了作用域的变量进行检索的内置支持。特别地，任何出现在 EL 表达式中但不对应于任何 EL 隐式对象的标识符，都被自动假定为引用存储在四个 JSP 作用域的其中某个中的对象，这四个作用域是： <br><br>　　 <strong>&#183;</strong>页面作用域 <br><br>　　 <strong>&#183;</strong>请求作用域 <br><br>　　 <strong>&#183;</strong>会话作用域 <br><br>　　 <strong>&#183;</strong>应用程序作用域 <br><br><ccid_code></ccid_code>　 　您可能还记得，只有在为特定请求处理页面期间才能检索存储在该页面作用域中的对象。如果对象是存储在请求作用域中的，可以在处理所有参与处理某请求的页 面期间检索这些对象（譬如在对某个请求的处理中遇到了一个或多个 &lt;jsp:include&gt; 或 &lt;jsp:forward&gt; 操作）。如果对象是存储在会话作用域中的，则在与 Web 应用程序的交互式会话期间，可以由用户访问的任何页面检索它（即，直到与该用户交互相关联的 HttpSession 对象无效为止）。可以由任何用户从任何页面访问存储在应用程序作用域中的对象，直到卸载 Web 应用程序本身为止（通常是由于关闭 JSP 容器所致）。 <br><br>　　 通过将字符串映射为期望作用域中的对象来将对象存储到该作用域。然后，就可以通过提供相同字符串来从该作用域检索该对象。在作用域的映射中查找字符串，并 返回被映射的对象。在 Servlet API 中，将此类对象称为相应作用域的属性。但是，在 EL 的上下文中，也将与属性相关联的字符串看作变量的名称，该变量通过属性映射的方式获得特定的值。 <br><br>　　 在 EL 中，与隐式对象无关联的标识符被认为是存储在四个 JSP 作用域中的名称对象。首先对页面作用域检查是否存在这样的标识符，其次对请求作用域、然后对会话作用域、最后对应用程序作用域依次进行这样的检查，然后测 试该标识符的名称是否与存储在该作用域中的某个对象的名称匹配。第一个这样的匹配作为 EL 标识符的值被返回。通过这种方法，可以将 EL 标识符看作引用限制了作用域的变量。 <br><br>　　 从更技术的方面来说，没有映射到隐式对象的标识符是用 PageContext 实例的 findAttribute() 方法求值的，该实例表示对页面的处理，在该页面上，当前正在处理用于请求的表达式。标识符的名称作为参数传递给这个方法，然后该方法依次在四个作用域中搜 索具有相同名称的属性。并将所找到的第一个匹配项作为 findAttribute() 方法的值返回。如果未在这四个作用域中找到这样的属性，则返回 null。 <br><br>　　 最终，限制了作用域的变量是四个 JSP 作用域的属性，这些属性具有可以用作 EL 标识符的名称。只要对限制了作用域的变量赋予由字母数字组成的名称，就可以通过 JSP 中提供的用于设置属性的任何机制来创建它们。这包括内置的 &lt;jsp:useBean&gt; 操作，以及由 Servlet API 中的几个类定义的 setAttribute() 方法。此外，四个 JSTL 库中定义的许多定制标记本身就能够设置作为限制了作用域的变量使用的属性值。 <br><br>　　 <strong>隐式对象</strong> <br><br>　　 表 1 中列出了 11 个 EL 隐式对象的标识符。不要将这些对象与 JSP 隐式对象（一共只有九个）混淆，其中只有一个对象是它们所共有的。 <br><br>　　 表 1. EL 隐式对象 <br><br>　　 类别 　　　标识符　　　　　　　　　　　　 描述 <br><br>　　 JSP 　　　pageContext 　　PageContext 实例对应于当前页面的处理 <br><br>　　 作用域　　pageScope 　　　 与页面作用域属性的名称和值相关联的 Map 类 <br><br>　　　　　　　 requestScope 　　与请求作用域属性的名称和值相关联的 Map 类 <br><br>　　　　　　　 sessionScope 　　与会话作用域属性的名称和值相关联的 Map 类 <br><br>　　　　　　　 applicationScope 与应用程序作用域属性的名称和值相关联的 Map 类 <br><br>　　 请求参数　param　　　　　 按名称存储请求参数的主要值的 Map 类 <br><br>　　　　　　　 paramValues　 将请求参数的所有值作为 String 数组存储的 Map 类 <br><br>　　 请求头 　header 　　　　按名称存储请求头主要值的 Map 类 <br><br>　　　　　　　 headerValues　将请求头的所有值作为 String 数组存储的 Map 类 <br><br>　　 Cookie 　cookie　　　　 按名称存储请求附带的 cookie 的 Map 类 <br><br>　　 初始化参数 initParam 　　按名称存储 Web 应用程序上下文初始化参数的 Map 类 <br><br>　　 <ccid_code></ccid_code>　 　尽管 JSP 和 EL 隐式对象中只有一个公共对象（pageContext），但通过 EL 也可以访问其它 JSP 隐式对象。原因是 pageContext 拥有访问所有其它八个 JSP 隐式对象的特性。实际上，这是将它包括在 EL 隐式对象中的主要理由。 <br><br>　　 其余所有 EL 隐式对象都是映射，可以用来查找对应于名称的对象。前四个映射表示先前讨论的各种属性作用域。可以用它们来查找特定作用域中的标识符，而不用依赖于 EL 在缺省情况下使用的顺序查找过程。 <br><br>　 　 接下来的四个映射用来获取请求参数和请求头的值。因为 HTTP 协议允许请求参数和请求头具有多个值，所以它们各有一对映射。每对中的第一个映射返回请求参数或头的主要值，通常是恰巧在实际请求中首先指定的那个值。每 对中第二个映射允许检索参数或头的所有值。这些映射中的键是参数或头的名称，但这些值是 String 对象的数组，其中的每个元素都是单一参数值或头值。 <br><br>　　 cookie 隐式对象提供了对由请求设置的 cookie 名称的访问。这个对象将所有与请求相关联的 cookie 名称映射到表示那些 cookie 特性的 Cookie 对象。 <br><br>　　 最后一个 EL 隐式对象 initParam 是一个映射，它储存与 Web 应用程序相关联的所有上下文的初始化参数的名称和值。初始化参数是通过 web.xml 部署描述符文件指定的，该文件位于应用程序的 WEB-INF 目录中。 <br><br>　　 <strong>存取器</strong> <br><br><ccid_code></ccid_code>　 　因为 EL 标识符是作为隐式对象或限制了作用域的变量（通过属性来实现）解析的，因此有必要将它们转换成 Java 对象。EL 可以自动包装和解包其相应的 Java 类中的基本类型（例如，可以在后台将 int 强制转换成 Integer 类，反之亦可），但大多数的标识符将成为指向完整的 Java 对象的指针。 <br><br>　　 结果是，对这些对象的特性或（在对象是数组和集合的情况下）对其元素的访问通常是令人满意的。就为了实现这种用途，EL 提供了两种不同的存取器（点运算符（.）和方括号运算符（[]）），也支持通过 EL 操作特性和元素。 <br><br>　 　 点运算符通常用于访问对象的特性。例如，在表达式 ${user.firstName} 中，使用点运算符来访问 user 标识符所引用对象的名为 firstName 的特性。EL 使用 Java bean 约定访问对象特性，因此必须定义这个特性的 getter 方法（通常是名为 getFirstName() 的方法），以便表达式正确求值。当被访问的特性本身是对象时，可以递归地应用点运算符。例如，如果我们虚构的 user 对象有一个实现为 Java 对象的 address 特性，那么也可以用点运算符来访问这个对象的特性。例如，表达式 ${user.address.city} 将会返回这个地址对象嵌套的 city 特性。 <br><br>　　 方括号运算符用来检索数组和集合的元素。在数组和有序集合（也即，实现了 java.util.List 接口的集合）的情况下，把要检索的元素的下标放在方括号中。例如，表达式 ${urls[3]} 返回 urls 标识符所引用的数组或集合的第四个元素（和 Java 语言以及 JavaScript 中一样，EL 中的下标是从零开始的）。 <br><br>　 　 对于实现 java.util.Map 接口的集合，方括号运算符使用关联的键查找存储在映射中的值。在方括号中指定键，并将相应的值作为表达式的值返回。例如，表达式 ${commands["dir"]} 返回与 commands 标识符所引用的 Map 中的 "dir" 键相关联的值。 <br><br>　　 对于上述两种情况，都可允许表达式出现在方括号中。对嵌套表达式求值的结果将被作为下标或键，用来检索集合或数组的适当元素。和点运算符一样，方括号运算 符也可以递归应用。这使得 EL 能够从多维数组、嵌套集合或两者的任意组合中检索元素。此外，点运算符和方括号运算符还可以互操作。例如，如果数组的元素本身是对象，则可以使用方括号运 算符来检索该数组的元素，并结合点运算符来检索该元素的一个特性（例如 ${urls[3].protocol}）。 <br><br>　　 假定 EL 充当指定动态属性值的简化语言，EL 存取器有一个有趣的功能（与 Java 语言的存取器不同），那就是它们在应用于 null 时不抛出异常。如果应用 EL 存取器的对象（例如，${foo.bar} 和 ${foo["bar"]} 中的 foo 标识符）是 null，那么应用存取器的结果也是 null。事实证明，在大多数情况下，这是一个相当有用的行为，不久您就会了解这一点。 <br><br>　　 最后，点运算符和方括号运算符可能实现某种程度的互换。例如，也可以使用 ${user["firstName"]} 来检索 user 对象的 firstName 特性，正如可以用 ${commands.dir} 获取与 commands 映射中的 "dir" 键相关联的值一样。 <br><br>　　 <strong>运算符</strong> <br><br><ccid_code></ccid_code>　　EL 还可以通过使用标识符和存取器，遍历包含应用程序数据（通过限制了作用域的变量公开）或关于环境的信息（通过 EL 隐式对象）的对象层次结构。但是，只是访问这些数据，通常不足以实现许多 JSP 应用程序所需的表示逻辑。 <br><br>　　 最终，EL 还包括了几个用来操作和比较 EL 表达式所访问数据的运算符。表 2 中汇总了这些运算符。 <br><br>　　 表 2. EL 运算符 <br><br>　　 类别 　　　　运算符 <br><br>　　 算术运算符　　+、-、*、/（或 div）和 %（或 mod） <br><br>　　 关系运算符 　==（或 eq）、!=（或 ne）、&lt;&lt;/code&gt;（或 lt）、&gt;（或 gt）、&lt;=（或 le）和 &gt;=（或 ge） <br><br>　　 逻辑运算符　　&amp;&amp;（或 and）、||（或 or）和 !（或 not） <br><br>　　 验证运算符 　empty <br><br>　 　 算术运算符支持数值的加法、减法、乘法和除法。还提供了一个求余运算符。注：除法和求余运算符都有替代的、非符号的名称（为的是与 XPath 保持一致）。清单 5 中显示了一个演示算术运算符用法的示例表达式。对几个 EL 表达式应用算术运算符的结果是将该算术运算符应用于这些表达式返回的数值所得的结果。 <br><br>　　 清单 5. 利用算术运算符的 EL 表达式 <br><br><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code></ccid_code>${item.price * (1 + taxRate[user.address.zipcode])}</pre>
            </td>
        </tr>
    </tbody>
</table>
<br><br>　　 关系运算符允许比较数字或文本数据。比较的结果作为布尔值返回。逻辑运算符允许合并布尔值，返回新的布尔值。因此，可以将 EL 逻辑运算符应用于嵌套的关系或逻辑运算符的结果，如清单 6 所示。 <br><br>　　 清单 6. 利用关系和逻辑运算符的 EL 表达式 <br><br><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code></ccid_code>${(x &gt;= min) &amp;&amp; (x &lt;= max)}</pre>
            </td>
        </tr>
    </tbody>
</table>
<br><br>　　 最后一种 EL 运算符是 empty，它对于验证数据特别有用。empty 运算符采用单个表达式作为其变量（也即，${empty input}），并返回一个布尔值，该布尔值表示对表达式求值的结果是不是&#8220;空&#8221;值。求值结果为 null 的表达式被认为是空，即无元素的集合或数组。如果参数是对长度为零的 String 求值所得的结果，则 empty 运算符也将返回 true。 <br><br>　　 表 3 显示了 EL 运算符的优先级。正如清单 5 和 6 所示，可以用圆括号对表达式分组，高于普通的优先级规则。 <br><br>　　 表 3. EL 运算符优先级（自顶到底，从左到右） <br><br><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code></ccid_code>[], . <br>() <br>unary -、not、!、empty <br>*、/、div、%、mod <br>+、binary - <br>() &lt;&lt;/code&gt;、&gt;、&lt;=、&gt;=、lt、gt、le、ge <br>==、!=、eq、ne <br>&amp;&amp;、and <br>||、or</pre>
            </td>
        </tr>
    </tbody>
</table>
<br><br>　　 <strong>文字</strong> <br><br>　　 在 EL 表达式中，数字、字符串、布尔值和 null 都可以被指定为文字值。字符串可以用单引号或双引号定界。布尔值被指定为 true 和 false。 <br><br>　　 <strong>Taglib 伪指令</strong> <br><br>　 　 正如我们先前讨论的，JSTL 1.0 包括四个定制标记库。为了演示 JSTL 标记和表达式语言的交互，我们将研究几个来自 JSTL core 库的标记。和使用任何 JSP 定制标记库一样，必须在您想要使用这个库标记的任何页面中包括 taglib 伪指令。清单 7 显示了用于这个特定库的伪指令。 <br><br>　　 清单 7. 用于 JSTL core 库 EL 版本的 taglib 伪指令 <br><br><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code></ccid_code>&lt;%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %&gt;</pre>
            </td>
        </tr>
    </tbody>
</table>
<br><br><ccid_code></ccid_code>　　实际上，对应于 JSTL core 库的 taglib 伪指令有两种，因为在 JSTL 1.0 中，EL 是可选的。所有四个 JSTL 1.0 定制标记库都有使用 JSP 表达式（而不是 EL）指定动态属性值的备用版本。因为这些备用库依赖于 JSP 的更传统的请求时属性值，所以它们被称为 RT 库，而那些使用表达式语言的则被称为 EL 库。开发人员用不同的 taglib 伪指令来区分每个库的这两个版本。清单 8 显示了使用 core 库的 RT 版本的伪指令。但是，由于现在我们讨论的重点是 EL，所以首先需要这些伪指令。 <br><br>　　 清单 8. 用于 JSTL core 库 RT 版本的 taglib 伪指令 <br><br><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code></ccid_code>&lt;%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c_rt" %&gt;</pre>
            </td>
        </tr>
    </tbody>
</table>
<br><br>　　 <strong>变量标记</strong> <br><br><ccid_code></ccid_code>　　我们首先要考 虑的 JSTL 定制标记是 &lt;c:set&gt; 操作。正如已经说明的，限制了作用域的变量在 JSTL 中起关键作用，&lt;c:set&gt; 操作提供基于标记的机制来创建和设置限制了作用域的变量。清单 9 中显示了该操作的语法，其中 var 属性指定了限制了作用域的变量的名称，scope 属性表明了该变量驻留在哪个作用域中，value 属性指定了分配给该变量的值。如果指定变量已经存在，则简单地将所指明的值赋给它。如果不存在，则创建新的限制了作用域的变量，并用该值初始化这个变量。 <br><br>　　 清单 9. &lt;c:set&gt; 操作的语法 <br><br><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code></ccid_code>&lt;c:set var="name" scope="scope" value="expression"/&gt;</pre>
            </td>
        </tr>
    </tbody>
</table>
<br><br><ccid_code></ccid_code>　　scope 属性是可选的，其缺省值是 page。 <br><br>　　 清单 10 中显示了 &lt;c:set&gt; 的两个示例。在第一个示例中，将会话作用域变量设置成 String 值。在第二个示例中，用表达式来设置数值：将页面作用域内名为 square 的变量赋值为名为 x 的请求参数的值的平方。 <br><br>　　 清单 10. &lt;c:set&gt; 操作示例 <br><br><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code></ccid_code>&lt;c:set var="timezone" scope="session" value="CST"/&gt;<br>&lt;c:set var="square" value="${param['x'] * param['x']}"/&gt;</pre>
            </td>
        </tr>
    </tbody>
</table>
<br><br><ccid_code></ccid_code>　　您还可以将限制了作用域的变量的值指定为 &lt;c:set&gt; 操作的主体内容，而不是使用属性。使用这种方法，您可以重新编写清单 10 中的第一个示例，如清单 11 所示。此外，正如我们马上可以看到的，&lt;c:set&gt; 标记的主体内容本身也可以使用定制标记。&lt;c:set&gt; 主体内生成的所有内容都将作为一个 String 值赋给指定变量。 <br><br>　　 清单 11. 通过主体内容指定 &lt;c:set&gt; 操作的值 <br><br><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code></ccid_code>&lt;c:set var="timezone" scope="session"&gt;CST&lt;/c:set&gt;</pre>
            </td>
        </tr>
    </tbody>
</table>
<br><br><ccid_code></ccid_code>　　JSTL core 库包含第二个用于管理限制了作用域的变量的标记 — &lt;c:remove&gt;。顾名思义，&lt;c:remove&gt; 操作是用来删除限制了作用域的变量的，它获取两个属性。var 属性指定待删除变量的名称，scope 属性是可选的，它表示待删除变量来自哪个作用域，缺省为 page，如清单 12 所示。 <br><br>　　 清单 12. &lt;c:remove&gt; 操作示例 <br><br><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code></ccid_code>&lt;c:remove var="timezone" scope="session"/&gt;</pre>
            </td>
        </tr>
    </tbody>
</table>
<br><br>　　 <strong>输出</strong> <br><br><ccid_code></ccid_code>　　尽管 &lt;c:set&gt; 操作允许将表达式结果赋给限制了作用域的变量，但开发人员通常会希望只显示表达式的值，而不存储它。JSTL &lt;c:out&gt; 定制标记承担这一任务，其语法如清单 13 所示。该标记对由其 value 属性指定的表达式进行求值，然后打印结果。如果指定了可选属性 default，那么，在对 value 属性的表达式求值所得结果为 null 或空 String 的情况下，&lt;c:out&gt; 将打印其值。 <br><br>　　 清单 13. &lt;c:out&gt; 操作的语法 <br><br><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code></ccid_code>&lt;c:out value="expression" default="expression" escapeXml="boolean"/&gt;</pre>
            </td>
        </tr>
    </tbody>
</table>
<br><br><ccid_code></ccid_code>　　escapeXml 属性也是可选的。它控制当用 &lt;c:out&gt; 标记输出诸如&#8220;&lt;&#8221;、&#8220;&gt;&#8221;和&#8220;&amp;&#8221;之类的字符（在 HTML 和 XML 中具有特殊意义）时是否应该进行转义。如果将 escapeXml 设置为 true，则会自动将这些字符转换成相应的 XML 实体（此处提到的字符分别转换成 &amp;lt;、&amp;gt; 和 &amp;amp;）。 <br><br>　　 例如，假定有一个名为 user 的会话作用域变量，它是一个类的实例，该类为用户定义了两个特性：username 和 company。每当用户访问站点时，这个对象被自动分配给会话，但直到用户实际登录后，才会设置这两个特性。假定是这种方案，请考虑清单 14 中的 JSP 片段。在用户登录之后，这个片段将显示单词&#8220;Hello&#8221;，其后是他／她的用户名和一个惊叹号。但是，在用户登录之前，由这个片段生成的内容则是短语 &#8220;Hello Guest!&#8221;。在这种情况下，因为 username 特性还有待初始化，所以 &lt;c:out&gt; 标记将转而打印出 default 属性的值（即字符串&#8220;Guest&#8221;）。 <br><br>　　 清单 14. 带缺省内容的 &lt;c:out&gt; 操作示例 Hello <br><br><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code></ccid_code>&lt;c:out value="${user.username}" default=="Guest"/&gt;!</pre>
            </td>
        </tr>
    </tbody>
</table>
<br><br><ccid_code></ccid_code>　　接下来，考虑清单 15，它使用了 &lt;c:out&gt; 标记的 escapeXml 属性。如果在这种情况下已经将 company 特性设置成 Java String 值 "Flynn &amp; Sons"，那么，实际上该操作生成的内容将是 Flynn &amp; Sons。如果这个操作是生成 HTML 或 XML 内容的 JSP 页面的一部分，那么，这个字符串中间的&#8220;&amp;&#8221;符号最终可能被解释为 HTML 或 XML 控制字符，从而妨碍了对该内容的显示或解析。但是，如果将 escapeXml 属性值设置成 true，则所生成的内容将是 Flynn &amp;amp; Sons。浏览器或解析器不会因在解释时遇到这种内容而出问题。假定 HTML 和 XML 是 JSP 应用程序中最常见的内容类型，所以 escapeXml 属性的缺省值是 true 就不足为奇了。 <br><br>　　 清单 15. 禁用转义的 &lt;c:out&gt; 操作示例 <br><br><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code></ccid_code>&lt;c:out value="${user.company}" escapeXml=="false"/&gt;</pre>
            </td>
        </tr>
    </tbody>
</table>
<br><br>　　 <strong>用缺省值设置变量</strong> <br><br><ccid_code></ccid_code>　　除了 简化动态数据的显示之外，当通过 &lt;c:set&gt; 设置变量值时，&lt;c:out&gt; 指定缺省值的能力也很有用。正如清单 11 所示，用来赋给限制了作用域的变量的值可以指定为 &lt;c:set&gt; 标记的主体内容，也可以通过其值属性来指定。通过将 &lt;c:out&gt; 操作嵌套在 &lt;c:set&gt; 标记的主体内容中，变量赋值就可以利用其缺省值能力。 <br><br>　　 清单 16 中说明了这种方法。外部 &lt;c:set&gt; 标记的行为非常简单：它根据其主体内容设置会话作用域 timezone 变量的值。但是，在这种情况下，主体内容是通过 &lt;c:out&gt; 操作生成的。这个嵌套操作的值属性是表达式 ${cookie['tzPref'].value}，它尝试通过 cookie 隐式对象返回名为 tzPref 的 cookie 值。（cookie 隐式对象将 cookie 名称映射到相应的 Cookie 实例，这意味着必须通过对象的 value 特性使用点运算符来检索储存在 cookie 中的实际数据。） <br><br>　　 清单 16. 合并 &lt;c:set&gt; 和 &lt;c:out&gt; 以提供缺省变量值 <br><br><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code></ccid_code>&lt;c:set var="timezone" scope=="session"&gt;<br>   &lt;c:out value="${cookie['tzPref'].value}" default=="CST"/&gt;<br>&lt;/c:set&gt;</pre>
            </td>
        </tr>
    </tbody>
</table>
<br><br><ccid_code></ccid_code>　　但是，请考虑以下情况，用户是第一次尝试使用这段代码的 Web 应用程序。结果是，请求中没有提供名为 tzPref 的 cookie。这意味着使用隐式对象的查找将返回 null，在这种情况下整个表达式将返回 null。因为对 &lt;c:out&gt; 标记的 value 属性求值的结果是 null，所以 &lt;c:out&gt; 标记会转而输出对其 default 属性求值的结果。在这里是字符串 CST。因此，实际的结果是将 timezone 限制了作用域的变量设置成用户的 tzPref cookie 中存储的时区，或者，如果没有，则使用缺省时区 CST。 <br><br>　　 <strong>EL 和 JSP 2.0</strong> <br><br><ccid_code></ccid_code>　 　目前，表达式语言仅可用于指定 JSTL 定制标记中的动态属性值。但 JSTL 1.0 表达式语言的一个扩展已经被提出，会把它包括到 JSP 2.0 中去，眼下正在进行最后评审。这个扩展将允许开发人员通过自己的定制标记来使用 EL。页面作者将可以在目前允许使用 JSP 表达式的任何地方使用 EL 表达式，譬如将动态值插入模板文本中：&lt;p&gt;Your preferred time zone is ${timezone}&lt;/p&gt;。 <br><br>　　 这个 JSP 2.0 功能（就象 JSTL 本身一样）将支持页面作者进一步减少对 JSP 编制脚本元素的依赖，从而改进 JSP 应用程序的可维护性。 <br><br>　　 <strong>结束语</strong> <br><br><ccid_code></ccid_code>　 　EL（与四个 JSTL 定制标记库提供的操作结合起来）允许页面作者不使用脚本元素即可实现表示层逻辑。例如，对比本文开头清单 1 中的 JSP 代码和清单 17 中显示的通过 JSTL 实现的同样功能。（JSTL core 库中其余的标记，包括 &lt;c:choose&gt; 及其子标记，将在本系列的下一篇文章中讨论。）尽管显然执行了条件逻辑，但是 JSTL 版本中没有 Java 语言源代码，并且标记之间的关系（尤其是关于嵌套需求）对于任何精通 HTML 语法的人都应该是熟悉的。 <br><br>　　 清单 17. 合并 &lt;c:set&gt; 和 &lt;c:out&gt; 以提供缺省变量值 <br><br><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code></ccid_code>&lt;c:choose&gt;&lt;c:when test="${user.role == 'member'}"&gt;<br>    &lt;p&gt;Welcome, member!&lt;/p&gt;<br>  &lt;/c:when&gt;&lt;c:otherwise&gt;<br>    &lt;p&gt;Welcome, guest!&lt;/p&gt;<br>  &lt;/c:otherwise&gt;&lt;/c:choose&gt;</pre>
            </td>
        </tr>
    </tbody>
</table>
<br><br><ccid_code></ccid_code>　　通过提供大多数 Web 应用程序常用功能的标准实现，JSTL 有助于加速开发周期。与 EL 结合起来，JSTL 可以不需要对表示层程序编写代码，这极大地简化了 JSP 应用程序的维护。 <br><br>　　 <strong>参考资料</strong> <br><br>　　 <a href="http://java.sun.com/products/jsp/jstl/index.html" target=_blank><u><font color=#0000ff>Sun 的 JSP 标准标记库主页是了解关于 JSTL 的更多信息的良好起点。</font></u></a> <br><br>　　 <a href="http://jcp.org/aboutJava/communityprocess/final/jsr052/" target=_blank><u><font color=#0000ff>JSTL 1.0 规范是关于 EL 和四个 JSTL 标记库的最终权威文本。 </font></u></a><br><br>　　 <a href="http://jakarta.apache.org/taglibs/index.html" target=_blank><u><font color=#0000ff>Jakarta Taglibs 项目是 JSTL 1.0 参考实现的起源。</font></u></a> <br><br>　　 <a href="http://www.manning.com/bayern/index.html" target=_blank><u><font color=#0000ff>Shawn Bayern 所著的 JSTL in Action（Manning Publications Co.，2002 年）提供了对所有 JSTL 功能的精彩论述，作者是该参考实现的领导。</font></u></a> <br><br>　　 <a href="http://www.amazon.com/exec/obidos/tg/detail/-/0131001531/103-4207394-1320606?vi=glance" target=_blank><u><font color=#0000ff>David Geary 是 Java 技术方面很受欢迎的作者，他也写了一本关于 JSTL 的书，书名是 Core JSTL。</font></u></a> <br><br>　　 <a href="http://jsptags.com/index.jsp" target=_blank><u><font color=#0000ff>JSPTags.com 是 JSP 技术参考资料的目录，它尤其专注于定制标记库。</font></u></a> <br><br>　　 <a href="http://java.sun.com/webservices/docs/ea2/tutorial/doc/JSTL3.html" target=_blank><u><font color=#0000ff>Sun 的 Java Web Services Tutorial 中包含了对 JSTL 的讨论。 </font></u></a><br><br>　　 <a href="http://www-900.ibm.com/developerWorks/cn/cgi-bin/click.cgi?url=http://www7b.software.ibm.com/wsdd/library/tutorials/vajwebsph353/Part-I/JSP11Part-I.html&amp;origin=j" target=_blank><u><font color=#0000ff>&#8220;Using JSPs and custom tags within VisualAge for Java and WebSphere Studio&#8221;（WebSphere 开发者园地）是一篇 WBOnline 实用论文，它演示了 servlet、JSP 和定制标记库的使用。</font></u></a> <br><br>　　 <a href="http://www-900.ibm.com/developerworks/cn/java/j-taglib/index.shtml" target=_blank><u><font color=#0000ff>通过 Jeff Wilson 精彩的文章&#8220;使用定制标记控制 JSP 页面&#8221;（developerWorks，2002 年 1 月）了解关于定制标记库的一切。</font></u></a> <br><br>　　 <a href="http://www-900.ibm.com/developerworks/cn/java/j-jsptags/index.shtml" target=_blank><u><font color=#0000ff>Noel Bergman 的文章&#8220;JSP 标记库：着意设计的更好的可用性&#8221;（developerWorks，2001 年 12 月）向您展示了声明性标记是如何帮助提高 JSP 页面的可用性的。</font></u></a> <br><br>　　 <a href="http://www-900.ibm.com/developerworks/cn/java/j-qdjava/index.shtml" target=_blank><u><font color=#0000ff>有关 EcmaScript 的更多详细信息，请参阅 Sing Li 的&#8220;快速上手 Java 编程&#8221;（developerWorks，2001 年 7 月）。</font></u></a> <br><br>　　 <a href="http://www-900.ibm.com/developerWorks/cn/java/index.shtml" target=_blank><u><font color=#0000ff>在 developerWorks Java 技术专区可以找到多达数百篇的 Java 技术参考资料。</font></u></a><br></div>
&nbsp;<br>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/135808.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2007-08-10 14:01 <a href="http://www.blogjava.net/wangxinsh55/archive/2007/08/10/135808.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>eclipse 启动参数</title><link>http://www.blogjava.net/wangxinsh55/archive/2007/07/06/128589.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Fri, 06 Jul 2007 07:04:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2007/07/06/128589.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/128589.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2007/07/06/128589.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/128589.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/128589.html</trackback:ping><description><![CDATA[		 其实，Eclipse是一个可以进行非常灵活配置的系统，除了以缺省的方式启动以外，还可以指定各种参数来定制启动方式。在参考了一些资料之后，我总结了一些比较常用的启动时Command Arguments，如果有不正确的地方希望大家予以指出。<br><br>-arch [processor architecture]<br>描述：指定所使用的处理器的类别<br>举例：eclipse -arch x86或eclipse -arch sparc<br><br>-application [id]<br>描述：指定要运行的应用，id为扩展org.eclipse.core.applications扩展点的插件id加扩展id<br>举例：例如有个插件id为edu.sdu.app，扩展id为myapp，则eclipse -application edu.sdu.app.myapp，就会执行你的扩展应用<br><br>-clean<br>描述：清空插件缓存内容<br>举例：eclipse -clean，有时插件显示不出来是因为Eclipse将插件进行了缓存以加速启动过程，若指定此参数则会清空缓存，从头加载<br><br>-configuration [cofigfile location]<br>描述：指定配置文件的位置，在启动时使用此目录下的配置文件config.ini来启动<br>举例：eclipse -configuration d:/eclipse/configuration<br><br>-data [workspace location]<br>描述：指定启动时的Workspace位置<br>举例：例如Workspace位置设在D:/myworkspace，则eclipse -data D:/myworkspace<br><br>-debug [option file]<br>描述：以Debug状态启动Eclipse，所有的Debug开关在.options文件中指定<br>举例：eclipse -debug d:/eclipse/.options<br><br>-dev [classpath entry]<br>描述：以开发状态启动Eclipse，这会添加所有指定的路径作为每个插件的Classpath<br>举例：例如eclipse -dev bin，会将产生在bin目录下的所有类加载到类路径中，这在开发插件时非常有用<br><br>-nosplash<br>描述：指定启动时不显示闪屏<br>举例：eclipse -nosplash<br><br>-vm [jre path]<br>描述：指定启动时所使用的Java虚拟机<br>举
例：例如要使用自己的Java虚拟机，则eclipse
-vmD:/j2sdk1.4.2_04/jre/bin/java.exe，这样还有一个好处，就是可以开启一个Console，能够显示控制台信息，
当然若使用eclipse -vm D:/j2sdk1.4.2_04/jre/bin/javaw.exe则不会再显示控制台<br><br>-vmargs [Java VM arguments]<br>描述：指定启动时要使用的Java虚拟机参数<br>举例：例如要指定使用的内存容量，则eclipse -vmargs "-Xms256m -Xmx1024m"<br>注：此参数一定要放在所有参数变量的最后面<br><br>
<div class="postText">
<p>如果你觉得你的Eclipse在启动的时候很慢（比如说超过20秒钟），也许你要调整一下你的Eclipse启动参数了，以下是一些``小贴士'':</p>
<p>1. 检查启动Eclipse的JVM设置。 在Help\About Eclipse SDK\Configuration
Detail里面，你可以看到启动Eclipse的JVM。 这个JVM和你在Eclipse中设置的Installed JDK是两回事情。
如果启动Eclipse的JVM还是JDK 1.4的话，那最好改为JDK 5，因为JDK 5的性能比1.4更好。</p>
<p><code>C:\eclipse\eclipse.exe -vm "C:\Program Files\Java\jdk1.5.0_08\ bin\javaw.exe"</code></p>
<p>2. 检查Eclipse所使用的heap的大小。 在C:\eclipse目录下有一个配置文件eclipse.ini，其中配置了Eclipse启动的默认heap大小</p>
<p><code>-vmargs<br>-Xms40M<br>-Xmx256M</code></p>
<p>所以你可以把默认值改为:</p>
<p><code>-vmargs<br>-Xms256M<br>-Xmx512M</code></p>
<p>当然，也可以这样做，把堆的大小改为256 - 512。</p>
<p><code>C:\eclipse\eclipse.exe -vm "C:\Program Files\Java\jdk1.5.0_08\ bin\javaw.exe" -vmargs -Xms256M -Xmx512M</code></p>
<p>3. 其他的启动参数。 如果你有一个双核的CPU，也许可以尝试这个参数:</p>
<p><code>-XX:+UseParallelGC</code></p>
<p>让GC可以更快的执行。（只是JDK 5里对GC新增加的参数）</p>
<p>【参考资料】<a href="http://swem.wm.edu/blogs/waynegraham/index.cfm/2006/9/7/Tweaking-Eclipse" class="externalLink" target="_blank">Tweaking Eclipse</a></p>
<p>
<!-- Tag links generated by Zoundry Blog Writer. Do not manually edit. http://www.zoundry.com -->
Technorati : <a href="http://technorati.com/tag/Eclipse" class="ztag" rel="tag">Eclipse</a> <br>Del.icio.us : <a href="http://del.icio.us/tag/Eclipse" class="ztag" rel="tag">Eclipse</a>
</p>
</div>
<br><img src ="http://www.blogjava.net/wangxinsh55/aggbug/128589.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2007-07-06 15:04 <a href="http://www.blogjava.net/wangxinsh55/archive/2007/07/06/128589.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>servlet 相关的Listener应用</title><link>http://www.blogjava.net/wangxinsh55/archive/2007/06/25/126058.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Mon, 25 Jun 2007 03:38:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2007/06/25/126058.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/126058.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2007/06/25/126058.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/126058.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/126058.html</trackback:ping><description><![CDATA[<table cellSpacing=1 cellPadding=1 width="98%" border=0>
    <tbody>
        <tr>
            <td><span class=date>张利海 于 2004年11月22日 23:27 发表</span> </td>
        </tr>
        <tr>
            <td>关键词 : servlet listener timer 定时器</td>
        </tr>
        <tr>
            <td>
            <p>从作用域范围来说,Servlet的作用域有ServletContext,HttpSession,ServletRequest.<br><br>Context范围:<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>ServletContextListener:<br>对一个应用进行全局监听.随应用启动而启动,随应用消失而消失主要有两个方法:<br>contextDestroyed(ServletContextEvent&nbsp;event)&nbsp;<br>&nbsp;在应用关闭的时候调用<br>contextInitialized(ServletContextEvent&nbsp;event)&nbsp;<br>在应用启动的时候调用<br><br>这个监听器主要用于一些随着应用启动而要完成的工作,也就是很多人说的我想在容器<br>启动的时候干..........<br>一般来说对"全局变量"初始化,如<br>public&nbsp;void&nbsp;contextInitialized(ServletContextEvent&nbsp;event){<br>&nbsp;&nbsp;&nbsp;&nbsp;ServletContex&nbsp;sc&nbsp;=&nbsp;event.getServletContext();<br>&nbsp;&nbsp;&nbsp;&nbsp;sc.setAttribute(name,value);<br>}<br>以后你就可以在任何servlet中getServletContext().getAttribute(name);<br>我最喜欢用它来做守护性工作,就是在contextInitialized(ServletContextEvent&nbsp;event)&nbsp;<br>方法中实现一个Timer,然后就让应用在每次启动的时候让这个Timer工作:<br>public&nbsp;void&nbsp;contextInitialized(ServletContextEvent&nbsp;event){<br>&nbsp;&nbsp;&nbsp;&nbsp;timer&nbsp;=&nbsp;new&nbsp;Timer();<br>&nbsp;&nbsp;&nbsp;&nbsp;timer.schedule(new&nbsp;TimerTask(){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;run(){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//do&nbsp;any&nbsp;things<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;},0,时间间隔);<br>}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;有人说Timer只能规定从现在开始的多长时间后,每隔多久做一次事或在什么时间做<br>一次事,那我想在每月1号或每天12点做一项工作如何做呢?<br>你只要设一个间隔,然后每次判断一下当时是不是那个时间段就行了啊,比如每月一号做,那你<br>时间间隔设为天,即24小时一个循环,然后在run方法中判断当时日期new&nbsp;Date().getDate()==1<br>就行了啊.如果是每天的12点,那你时间间隔设为小时,然后在run中判断new&nbsp;Date().getHour()<br>==12,再做某事就行了.<br><br>ServletContextAttributeListener:<br><br>这个监听器主要监听ServletContex对象在setAttribute()和removeAttribute()的事件,注意<br>也就是一个"全局变量"在被Add(第一次set),replace(对已有的变量重新赋值)和remove的时候.<br>分别调用下面三个方法:<br>public&nbsp;void&nbsp;attributeAdded(ServletContextAttributeEvent&nbsp;scab)这个方法不仅可以知道<br>哪些全局变量被加进来,而且可获取容器在启动时自动设置了哪些context变量:<br><br>public&nbsp;void&nbsp;attributeAdded(ServletContextAttributeEvent&nbsp;scab){<br>&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(scab.getName());<br>}<br>&nbsp;&nbsp;public&nbsp;void&nbsp;attributeRemoved(ServletContextAttributeEvent&nbsp;scab)&nbsp;<br><br>&nbsp;&nbsp;public&nbsp;void&nbsp;attributeReplaced(ServletContextAttributeEvent&nbsp;scab)&nbsp;<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;<br><br><br><br><br><br><br><br><br>Session范围:<br>HttpSessionListener:<br>这个监听器主要监听一个Session对象被生成和销毁时发生的事件.对应有两个方法:<br>&nbsp;&nbsp;public&nbsp;void&nbsp;sessionCreated(HttpSessionEvent&nbsp;se)&nbsp;<br><br>&nbsp;&nbsp;public&nbsp;void&nbsp;sessionDestroyed(HttpSessionEvent&nbsp;se)<br><br>&nbsp;&nbsp;一般来说,一个session对象被create时,可以说明有一个新客端进入.可以用来粗略统计在线人<br>数,注意这不是精确的,因为这个客户端可能立即就关闭了,但sessionDestroyed方法却会按一定<br>的策略很久以后才会发生.<br><br>HttpSessionAttributeListener:<br>和ServletContextAttributeListener一样,它监听一个session对象的Attribut被Add(一个特定<br>名称的Attribute每一次被设置),replace(已有名称的Attribute的值被重设)和remove时的事件.<br>对就的有三个方法.<br>&nbsp;&nbsp;public&nbsp;void&nbsp;attributeAdded(HttpSessionBindingEvent&nbsp;se)&nbsp;<br><br>&nbsp;&nbsp;public&nbsp;void&nbsp;attributeRemoved(HttpSessionBindingEvent&nbsp;se)&nbsp;<br><br>&nbsp;&nbsp;public&nbsp;void&nbsp;attributeReplaced(HttpSessionBindingEvent&nbsp;se)&nbsp;<br><br>&nbsp;&nbsp;上面的几个监听器的方法,都是在监听应用逻辑中servlet逻辑中发生了什么事,一般的来说.<br>我们只要完成逻辑功能,比如session.setAttribute("aaa","111");我只要把一个名为aaa的变量<br>放在session中以便以后我能获取它,我并不关心当session.setAttribute("aaa","111");发生时<br>我还要干什么.(当然有些时候要利用的),但对于下面这个监听器,你应该好好发解一下:<br><br>HttpSessionBindingListener:<br>上面的监听器都是作为一个独立的Listener在容器中控制事件的.而HttpSessionBindingListener<br>对在一对象中监听该对象的状态,实现了该接口的对象如果被作为value被add到一个session中或从<br>session中remove,它就会知道自己已经作为一个session对象或已经从session删除,这对于一些非<br>纯JAVA对象,生命周期长于session的对象,以及其它需要释放资源或改变状态的对象非常重要.<br>比如:<br>session.setAttribute("abcd","1111");<br>以后session.removeAttribute("abcd");因为abcd是一个字符中,你从session中remove后,它就会<br>自动被垃圾回收器回收,而如果是一个connection:(只是举例,你千万不要加connection往session<br>中加入)<br>session.setAttribute("abcd",conn);<br>以后session.removeAttribute("abcd");这时这个conn被从session中remove了,你已经无法获取它<br>的句柄,所以你根本没法关闭它.而在没有remove之前你根本不知道什么时候要被remove,你又无法<br>close(),那么这个connection对象就死了.另外还有一些对象可以在被加入一个session时要锁定<br>还要被remove时要解锁,应因你在程序中无法判断什么时候被remove(),add还好操作,我可以先加锁<br>再add,但remove就后你就找不到它的句柄了,根本没法解锁,所以这些操作只能在对象自身中实现.<br>也就是在对象被add时或remove时通知对象自己回调相应的方法:<br><br>MyConn&nbsp;extends&nbsp;Connection&nbsp;implements&nbsp;HttpSessionBindingListener{<br>&nbsp;&nbsp;public&nbsp;void&nbsp;valueBound(HttpSessionBindingEvent&nbsp;se){<br>&nbsp;&nbsp;&nbsp;&nbsp;this.initXXX();<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;public&nbsp;void&nbsp;valueUnbound(HttpSessionBindingEvent&nbsp;se){<br><br>&nbsp;&nbsp;&nbsp;&nbsp;this.close();<br>&nbsp;&nbsp;}<br>}<br><br>session.setAttribute("aaa",new&nbsp;MyConn());<br>这时如果调用session.removeAttribute("aaa"),则触发valueUnbound方法,就会自动关闭自己.<br>而其它的需要改变状态的对象了是一样.<br><br>另外还有一个HttpSessionActivationListener监听器是实现分布式应用中session同步的.不作<br>多介绍,如果有要实现该功能的朋友可以和我联系.<br><br><br><br><br>在servlet2.4中,对于request范围已经实现对应的监听器:<br>ServletRequestListener，ServletRequestAttributeListener<br>但没有找到好的容器的支持所以没有做过多的测试.虽然从API可以掌握99%,但没有经过真正的<br>测试我是不会仅把API抄出来的.以后我会补齐这方面的内容 <br><br>原作者:Axman<br></p>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/126058.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2007-06-25 11:38 <a href="http://www.blogjava.net/wangxinsh55/archive/2007/06/25/126058.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转贴]垃圾收集器与Java编程 </title><link>http://www.blogjava.net/wangxinsh55/archive/2007/06/19/125071.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Tue, 19 Jun 2007 03:22:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2007/06/19/125071.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/125071.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2007/06/19/125071.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/125071.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/125071.html</trackback:ping><description><![CDATA[<p><a href="http://www-900.ibm.com/developerWorks/cn/java/l-JavaMemoryLeak2/index.shtml#author1"><u><font color=#0000ff>欧阳辰</font></u></a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#121;&#101;&#101;&#107;&#101;&#101;&#64;&#115;&#105;&#110;&#97;&#46;&#99;&#111;&#109;"><u><font color=#0000ff>yeekee@sina.com</font></u></a>)<br><a href="http://www-900.ibm.com/developerWorks/cn/java/l-JavaMemoryLeak2/index.shtml#author2"><u><font color=#0000ff>周欣</font></u></a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#122;&#104;&#111;&#117;&#120;&#105;&#110;&#64;&#115;&#101;&#105;&#46;&#112;&#107;&#117;&#46;&#101;&#100;&#117;&#46;&#99;&#110;"><u><font color=#0000ff>zhouxin@sei.pku.edu.cn</font></u></a>)<br></p>
<blockquote>垃圾收集器(Garbage Collector，GC)对Java程序员来说，基本 上是透明的，但是一个优秀的Java程序员必须了解GC的工作原理、如何优化GC的性能、如何与GC进行有限的交互，因为有一些应用程序对性能要求较高，例如嵌入式系统、实时系统等，只有全面提升内存的管理效率 ,才能提高整个应用程序的性能。本篇文章首先简单介绍GC的工作原理之后，然后再对GC的几个关键问题进行深入探讨，最后提出一些Java程序设计建议，从GC角度提高Java程序的性能。</blockquote>
<p><a name=1><span class=atitle2>一GC的基本原理</span></a></p>
<p>Java的内存管理实际上就是对象的管理，其中包括对象的分配和释放。</p>
<p>对于程序员来说，分配对象使用new关键字；释放对象时，只要将对象所有引用赋值为null，让程序不能够再访问到这个对象，我们称该对象为"不可达的"。GC将负责回收所有"不可达"对象的内存空间。</p>
<p>对于GC来说，当程序员创建对象时，GC就开始监控这个对象的地址、大小以及使用情况。通常，GC采用有向图的方式记录和管理堆(heap)中的所有对象(详见<a href="http://www-900.ibm.com/developerWorks/cn/java/l-JavaMemoryLeak2/index.shtml#resources"><u><font color=#0000ff>参考资料1</font></u></a> )。通过这种方式确定哪些对象是"可达的"，哪些对象是"不可达的"。当GC确定一些对象为"不可达"时，GC就有责任回收这些内存空间。但是，为了保证GC能够在不同平台实现的问题，Java规范对GC的很多行为都没有进行严格的规定。例如，对于采用什么类型的回收算法、什么时候进行回收等重要问题都没有明确的规定。因此，不同的JVM的实现者往往有不同的实现算法。这也给Java程序员的开发带来行多不确定性。本文研究了几个与GC工作相关的问题，努力减少这种不确定性给Java程序带来的负面影响。</p>
<p><a name=2><span class=atitle2>二 增量式GC( Incremental GC )</span></a></p>
<p>GC在JVM中通常是由一个或一组进程来实现的，它本身也和用户程序一样占用heap空间，运行时也占用CPU。当GC进程运行时，应用程序停止运行。因此，当GC运行时间较长时，用户能够感到Java程序的停顿，另外一方面，如果GC运行时间太短，则可能对象回收率太低，这意味着还有很多应该回收的对象没有被回收，仍然占用大量内存。因此，在设计GC的时候，就必须在停顿时间和回收率之间进行权衡。一个好的GC实现允许用户定义自己所需要的设置，例如有些内存有限有设备，对内存的使用量非常敏感，希望GC能够准确的回收内存，它并不在意程序速度的放慢。另外一些实时网络游戏，就不能够允许程序有长时间的中断。增量式GC就是通过一定的回收算法，把一个长时间的中断，划分为很多个小的中断，通过这种方式减少GC对用户程序的影响。虽然，增量式GC在整体性能上可能不如普通GC的效率高，但是它能够减少程序的最长停顿时间。</p>
<p>下图就表示了，增量式GC和普通GC的比较。其中灰色部分表示线程占用CPU的时间。</p>
<p>&#160;</p>
<center><img height=210 alt="" src="http://www-900.ibm.com/developerWorks/cn/java/l-JavaMemoryLeak2/1.gif" width=600 border=0></center>
<p>&#160;</p>
<p>Sun JDK提供的HotSpot JVM就能支持增量式GC。HotSpot JVM缺省GC方式为不使用增量GC，为了启动增量GC，我们必须在运行Java程序时增加-Xincgc的参数。HotSpot JVM增量式GC的实现是采用Train GC算法。它的基本想法就是，将堆中的所有对象按照创建和使用情况进行分组(分层)，将使用频繁高和具有相关性的对象放在一队中，随着程序的运行，不断对组进行调整。当GC运行时，它总是先回收最老的(最近很少访问的)的对象，如果整组都为可回收对象，GC将整组回收。这样，每次GC运行只回收一定比例的不可达对象，保证程序的顺畅运行。Train GC算法是一个非常好的算法，具体算法见<a href="http://www-900.ibm.com/developerWorks/cn/java/l-JavaMemoryLeak2/index.shtml#resources"><u><font color=#0000ff>参考资料4</font></u></a>。</p>
<p><a name=3><span class=atitle2>三 详解finalize函数</span></a></p>
<p>finalize是位于Object类的一个方法，该方法的访问修饰符为protected，由于所有类为Object的子类，因此用户类很容易访问到这个方法。由于，finalize函数没有自动实现链式调用，我们必须手动的实现，因此finalize函数的最后一个语句通常是super.finalize()。通过这种方式，我们可以实现从下到上实现finalize的调用，即先释放自己的资源，然后再释放父类的资源。</p>
<p>根据Java语言规范，JVM保证调用finalize函数之前，这个对象是不可达的，但是JVM不保证这个函数一定会被调用。另外，规范还保证finalize函数最多运行一次。</p>
<p>很多Java初学者会认为这个方法类似与C++中的析构函数，将很多对象、资源的释放都放在这一函数里面。其实，这不是一种很好的方式。原因有三，其一，GC为了能够支持finalize函数，要对覆盖这个函数的对象作很多附加的工作。其二，在finalize运行完成之后，该对象可能变成可达的，GC还要再检查一次该对象是否是可达的。因此，使用finalize会降低GC的运行性能。其三，由于GC调用finalize的时间是不确定的，因此通过这种方式释放资源也是不确定的。</p>
<p>通常，finalize用于一些不容易控制、并且非常重要资源的释放，例如一些I/O的操作，数据的连接。这些资源的释放对整个应用程序是非常关键的。在这种情况下，程序员应该以通过程序本身管理(包括释放)这些资源为主，以finalize函数释放资源方式为辅，形成一种双保险的管理机制，而不应该仅仅依靠finalize来释放资源。</p>
<p>下面给出一个例子说明，finalize函数被调用以后，仍然可能是可达的，同时也可说明一个对象的finalize只可能运行一次。</p>
<p>&#160;</p>
<table cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
    <tbody>
        <tr>
            <td>
            <pre><code><br>class MyObject{<br>    Test main; //记录Test对象，在finalize中时用于恢复可达性<br>    public MyObject(Test t)<br>    {	 <br>	main=t; //保存Test 对象<br>    }<br>    protected void finalize()<br>    {<br>	main.ref=this;// 恢复本对象，让本对象可达<br>	System.out.println("This is finalize");//用于测试finalize只运行一次<br>    }<br>}<br><br>class Test {<br>	MyObject ref;<br> 	public static void main(String[] args) {<br> 		Test test=new Test();<br> 		test.ref=new MyObject(test);<br> 		test.ref=null; //MyObject对象为不可达对象，finalize将被调用<br> 		System.gc(); <br> 		if (test.ref!=null) System.out.println("My Object还活着");	<br>	}<br>}<br></code></pre>
            </td>
        </tr>
    </tbody>
</table>
<p>运行结果：<br>This is finalize<br>MyObject还活着</p>
<p>此例子中，需要注意的是虽然MyObject对象在finalize中变成可达对象，但是下次回收时候，finalize却不再被调用，因为finalize函数最多只调用一次。</p>
<p><a name=4><span class=atitle2>四 程序如何与GC进行交互</span></a></p>
<p>Java2增强了内存管理功能， 增加了一个java.lang.ref包，其中定义了三种引用类。这三种引用类分别为SoftReference、WeakReference和PhantomReference。通过使用这些引用类，程序员可以在一定程度与GC进行交互，以便改善GC的工作效率。这些引用类的引用强度介于可达对象和不可达对象之间。它们的引用强度如下图所示：</p>
<p>&#160;</p>
<center><img height=270 alt="" src="http://www-900.ibm.com/developerWorks/cn/java/l-JavaMemoryLeak2/2.gif" width=492 border=0></center>
<p>&#160;</p>
<p>创建一个引用对象也非常容易，例如如果你需要创建一个Soft Reference对象，那么首先创建一个对象，并采用普通引用方式(可达对象)；然后再创建一个SoftReference引用该对象；最后将普通引用设置为null。通过这种方式，这个对象就只有一个Soft Reference引用。同时，我们称这个对象为Soft Reference 对象。</p>
<p>Soft Reference的主要特点是据有较强的引用功能。只有当内存不够的时候，才进行回收这类内存，因此在内存足够的时候，它们通常不被回收。另外，这些引用对象还能保证在Java抛出OutOfMemory 异常之前，被设置为null。它可以用于实现一些常用图片的缓存，实现Cache的功能，保证最大限度的使用内存而不引起OutOfMemory。以下给出这种引用类型的使用伪代码；</p>
<p>&#160;</p>
<table cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
    <tbody>
        <tr>
            <td>
            <pre><code><br>//申请一个图像对象<br>Image image=new Image();//创建Image对象<br>&#8230;<br>//使用 image<br>&#8230;<br>//使用完了image，将它设置为soft 引用类型，并且释放强引用；<br>SoftReference sr=new SoftReference(image);<br>image=null;<br>	&#8230;<br>	//下次使用时<br>	if (sr!=null) image=sr.get();<br>	else{<br>	//由于GC由于低内存，已释放image，因此需要重新装载；<br>	image=new Image();<br>sr=new SoftReference(image);<br>}<br></code></pre>
            </td>
        </tr>
    </tbody>
</table>
<p>Weak引用对象与Soft引用对象的最大不同就在于：GC在进行回收时，需要通过算法检查是否回收Soft引用对象，而对于Weak引用对象，GC总是进行回收。Weak引用对象更容易、更快被GC回收。虽然，GC在运行时一定回收Weak对象，但是复杂关系的Weak对象群常常需要好几次GC的运行才能完成。Weak引用对象常常用于Map结构中，引用数据量较大的对象，一旦该对象的强引用为null时，GC能够快速地回收该对象空间。该例子见<a href="http://www-900.ibm.com/developerWorks/cn/java/l-JavaMemoryLeak2/index.shtml#resources"><u><font color=#0000ff>参考资料4</font></u></a>;</p>
<p>Phantom引用的用途较少，主要用于辅助finalize函数的使用。Phantom对象指一些对象，它们执行完了finalize函数，并为不可达对象，但是它们还没有被GC回收。这种对象可以辅助finalize进行一些后期的回收工作，我们通过覆盖Reference的clear()方法，增强资源回收机制的灵活性。</p>
<p><a name=5><span class=atitle2>五一些Java编码的建议</span></a></p>
<p>根据GC的工作原理，我们可以通过一些技巧和方式，让GC运行更加有效率，更加符合应用程序的要求。以下就是一些程序设计的几点建议。</p>
<ol class=n01>
    <li>最基本的建议就是尽早释放无用对象的引用。大多数程序员在使用临时变量的时候，都是让引用变量在退出活动域(scope)后，自动设置为null。我们在使用这种方式时候，必须特别注意一些复杂的对象图，例如数组，队列，树，图等，这些对象之间有相互引用关系较为复杂。对于这类对象，GC回收它们一般效率较低。如果程序允许，尽早将不用的引用对象赋为null。这样可以加速GC的工作。
    <li>尽量少用finalize函数。finalize函数是Java提供给程序员一个释放对象或资源的机会。但是，它会加大GC的工作量，因此尽量少采用finalize方式回收资源。
    <li>如果需要使用经常使用的图片，可以使用soft应用类型。它可以尽可能将图片保存在内存中，供程序调用，而不引起OutOfMemory。
    <li>注意集合数据类型，包括数组，树，图，链表等数据结构，这些数据结构对GC来说，回收更为复杂。另外，注意一些全局的变量，以及一些静态变量。这些变量往往容易引起悬挂对象(dangling reference)，造成内存浪费。
    <li>当程序有一定的等待时间，程序员可以手动执行System.gc()，通知GC运行，但是Java语言规范并不保证GC一定会执行。使用增量式GC可以缩短Java程序的暂停时间。 </li>
</ol>
<p><a name=resources><span class=atitle2>参考资料</span></a></p>
<p>文章</p>
<ol class=n01>
    <li>欧阳辰，周欣 "Java与内存泄漏" <a href="http://www-900.ibm.com/developerWorks/cn/java/l-JavaMemoryLeak/index.shtml"><u><font color=#0000ff>http://www-900.ibm.com/developerWorks/cn/java/l-JavaMemoryLeak/index.shtml</font></u></a>
    <li>Y. Srinivas Ramakrishna "Atuomatic Memory Management in the Java HotSpot Virtual Machine"，此文章JavaOne2002的演讲材料, <a href="http://java.sun.com/javaone"><u><font color=#0000ff>http://java.sun.com/javaone</font></u></a>
    <li>Monica Pawlan "Reference Objects and Garbage Collector" 此文章为JDC的文章，可在<a href="http://developer.java.sun.com/"><u><font color=#0000ff>http://developer.java.sun.com/</font></u></a>上找到
    <li>Bill Venners Chapter 9 of "Inside the Java 2 Virtual Machine" <a href="http://www.artima.com/insidejvm/ed2/ch09GarbageCollectionPrint.html"><u><font color=#0000ff>http://www.artima.com/insidejvm/ed2/ch09GarbageCollectionPrint.html</font></u></a>
    <li>Sun Microsystems, "Java Language Specification, Second Version" </li>
</ol>
<br><!-- AUTHOR BIOS--><!-- Make author heading singular or plural as needed-->
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td><a name=author1><span class=atitle2>关于作者</span></a> <br>欧阳辰，北京大学计算机硕士毕业，98年起开始研究基于java的软件开发、测试，参与开发、测试过多个基于Java的应用程序和Web服务项目。联系方式<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#121;&#101;&#101;&#107;&#101;&#101;&#64;&#115;&#105;&#110;&#97;&#46;&#99;&#111;&#109;"><u><font color=#0000ff>yeekee@sina.com</font></u></a><br>周欣，北京大学计算机系在读博士生，主要研究方向：程序理解、逆向工程及软件度量，联系方式 <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#122;&#104;&#111;&#117;&#120;&#105;&#110;&#64;&#115;&#101;&#105;&#46;&#112;&#107;&#117;&#46;&#101;&#100;&#117;&#46;&#99;&#110;"><u><font color=#0000ff>zhouxin@sei.pku.edu.cn</font></u></a>。 </td>
        </tr>
    </tbody>
</table>
<br><br>
<p id=TBPingURL>Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=281108</p>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/125071.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2007-06-19 11:22 <a href="http://www.blogjava.net/wangxinsh55/archive/2007/06/19/125071.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XML+XSLT 在IE, Firefox 下显示</title><link>http://www.blogjava.net/wangxinsh55/archive/2007/06/07/122631.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Thu, 07 Jun 2007 08:15:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2007/06/07/122631.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/122631.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2007/06/07/122631.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/122631.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/122631.html</trackback:ping><description><![CDATA[下边是xslt文件<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">&lt;?</span><span style="COLOR: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"</span><span style="COLOR: #0000ff">?&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">xsl:stylesheet&nbsp;</span><span style="COLOR: #ff0000">version</span><span style="COLOR: #0000ff">="2.0"</span><span style="COLOR: #ff0000"><br>&nbsp;&nbsp;&nbsp;&nbsp;xmlns:xsl</span><span style="COLOR: #0000ff">="http://www.w3.org/1999/XSL/Transform"</span><span style="COLOR: #ff0000"><br>&nbsp;&nbsp;&nbsp;&nbsp;xmlns:xs</span><span style="COLOR: #0000ff">="http://www.w3.org/2001/XMLSchema"</span><span style="COLOR: #ff0000"><br>&nbsp;&nbsp;&nbsp;&nbsp;xmlns:fn</span><span style="COLOR: #0000ff">="http://www.w3.org/2005/xpath-functions"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">xsl:template&nbsp;</span><span style="COLOR: #ff0000">match</span><span style="COLOR: #0000ff">="root"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">html</span><span style="COLOR: #0000ff">&gt;&lt;</span><span style="COLOR: #800000">title</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">ss</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">title</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">body</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">xsl:value-of&nbsp;</span><span style="COLOR: #ff0000">select</span><span style="COLOR: #0000ff">="message"</span><span style="COLOR: #ff0000">&nbsp;</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">body</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">html</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">xsl:template</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">xsl:stylesheet</span><span style="COLOR: #0000ff">&gt;</span></div>
下边是XML文件<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">&lt;?</span><span style="COLOR: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"</span><span style="COLOR: #0000ff">?&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">&lt;?</span><span style="COLOR: #ff00ff">xml-stylesheet&nbsp;type="text/xsl"&nbsp;href="1.xslt"</span><span style="COLOR: #0000ff">?&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">root</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">message</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">这里的</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">message</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">root</span><span style="COLOR: #0000ff">&gt;</span></div>
下边是通过Ajax调用的函数<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;getHtml(xmlText,&nbsp;xsltFile){<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000">&nbsp;text;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">typeof</span><span style="COLOR: #000000">(window.ActiveXObject)&nbsp;</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">&nbsp;'undefined'){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;支持IE浏览器</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000">{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000">&nbsp;xmlDoc</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;ActiveXObject(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Msxml2.DOMDocument.3.0</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xslDoc&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;ActiveXObject(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Msxml2.DOMDocument.3.0</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmlDoc.async</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xslDoc.async&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmlDoc.loadXML(xmlText);&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;xslDoc.load(xsltFile);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;text&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;xmlDoc.documentElement.transformNode(xslDoc.documentElement);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000">(e){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(isDebug)&nbsp;alert(e.name&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;e.message);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Unable&nbsp;to&nbsp;do&nbsp;xml/xsl&nbsp;processing</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(e.name&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;e.message);&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;<br>&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(document.implementation&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;document.implementation.createDocument){&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;支持Mozilla浏览器</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000">&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;在Firefox的XML&nbsp;DOM实现中，并没有loadXML()方法，不过通过Firefox中的DOMParser类可以模拟loadXML()的行为</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000">&nbsp;oParser&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;DOMParser();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000">&nbsp;xmlDoc&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;oParser.parseFromString(xmlText,</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">text/xml</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xslDoc&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;document.implementation.createDocument(</span><span style="COLOR: #000000">""</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">""</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xslDoc.async&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xslDoc.load(xsltFile);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;定义XSLTProcessor对象</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000">&nbsp;xsltProcessor&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;XSLTProcessor();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xsltProcessor.importStylesheet(xslDoc);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;transformToDocument方式</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000">&nbsp;result&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;xsltProcessor.transformToDocument(xmlDoc);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000">&nbsp;xmls&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;XMLSerializer();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;text&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;xmls.serializeToString(result);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000">(e)&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(isDebug)&nbsp;alert(e.name&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;e.message);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Unable&nbsp;to&nbsp;do&nbsp;xml/xsl&nbsp;processing</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;text;<br>}</span></div>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/122631.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2007-06-07 16:15 <a href="http://www.blogjava.net/wangxinsh55/archive/2007/06/07/122631.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>配置Spring的数据源</title><link>http://www.blogjava.net/wangxinsh55/archive/2007/05/25/120026.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Fri, 25 May 2007 08:33:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2007/05/25/120026.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/120026.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2007/05/25/120026.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/120026.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/120026.html</trackback:ping><description><![CDATA[<strong>概述</strong> <br>&nbsp;&nbsp;&nbsp;<strong> 【IT168 专稿】</strong>不管通过何种持久化技术，都必须通过数据连接访问数据库，在Spring中，数据连接是通过数据源获得的。在以往的应用中，数据源一般是Web应用服务器提供的。在Spring中，你不但可以通过JNDI获取应用服务器的数据源，也可以直接在Spring容器中配置数据源，此外，你还可以通过代码的方式创建一个数据源，以便进行无依赖的单元测试。 <br><br>&nbsp;&nbsp;&nbsp; 配置一个数据源 <br>&nbsp;&nbsp;&nbsp; Spring在第三方依赖包中包含了两个数据源的实现类包，其一是Apache的DBCP，其二是 C3P0。可以在Spring配置文件中利用这两者中任何一个配置数据源。 <br><br>&nbsp;&nbsp;<strong>&nbsp; DBCP数据源</strong> <br>&nbsp;&nbsp;&nbsp; DBCP类包位于 &lt;SPRING_HOME&gt;/lib/jakarta-commons/commons-dbcp.jar，DBCP是一个依赖Jakarta commons-pool对象池机制的数据库连接池，所以在类路径下还必须包括&lt;SPRING_HOME&gt;/lib/jakarta-commons/commons-pool.jar。下面是使用DBCP配置MySql数据源的配置片断： <br>
<div style="SCROLLBAR-HIGHLIGHT-COLOR: buttonhighlight; OVERFLOW: auto; WIDTH: 500px">
<pre style="BORDER-RIGHT: black 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: black 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 4px; BORDER-LEFT: black 1px solid; PADDING-TOP: 4px; BORDER-BOTTOM: black 1px solid; BACKGROUND-COLOR: #ededed">
<div><!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">bean id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">dataSource</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">org.apache.commons.dbcp.BasicDataSource</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> destroy</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">method</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">close</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">property name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">driverClassName</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">com.mysql.jdbc.Driver</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">property name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">url</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">jdbc:mysql://localhost:3309/sampledb</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">property name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">username</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">root</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">property name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">password</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">1234</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">bean</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span></div>
</pre>
</div>
&nbsp;&nbsp;&nbsp; BasicDataSource提供了close()方法关闭数据源，所以必须设定destroy-method=&#8221;close&#8221;属性， 以便Spring容器关闭时，数据源能够正常关闭。除以上必须的数据源属性外，还有一些常用的属性： <br> defaultAutoCommit：设置从数据源中返回的连接是否采用自动提交机制，默认值为 true； <br> defaultReadOnly：设置数据源是否仅能执行只读操作， 默认值为 false； <br> maxActive：最大连接数据库连接数，设置为0时，表示没有限制； <br> maxIdle：最大等待连接中的数量，设置为0时，表示没有限制； <br> maxWait：最大等待秒数，单位为毫秒， 超过时间会报出错误信息； <br> validationQuery：用于验证连接是否成功的查询SQL语句，SQL语句必须至少要返回一行数据，如你可以简单地设置为：&#8220;select count(*) from user&#8221;； <br> removeAbandoned：是否自我中断，默认是 false ； <br> removeAbandonedTimeout：几秒后数据连接会自动断开，在removeAbandoned为true，提供该值； <br> logAbandoned：是否记录中断事件， 默认为 false； <br><br><br><strong>C3P0数据源</strong> <br>&nbsp;&nbsp;&nbsp; C3P0是一个开放源代码的JDBC数据源实现项目，它在lib目录中与Hibernate一起发布，实现了JDBC3和JDBC2扩展规范说明的Connection 和Statement 池。C3P0类包位于&lt;SPRING_HOME&gt;/lib/c3p0/c3p0-0.9.0.4.jar。下面是使用C3P0配置一个Oracle数据源： <br>
<div style="SCROLLBAR-HIGHLIGHT-COLOR: buttonhighlight; OVERFLOW: auto; WIDTH: 500px">
<pre style="BORDER-RIGHT: black 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: black 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 4px; BORDER-LEFT: black 1px solid; PADDING-TOP: 4px; BORDER-BOTTOM: black 1px solid; BACKGROUND-COLOR: #ededed">
<div><!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><img alt="" src="" align=top><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">bean id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">dataSource</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">com.mchange.v2.c3p0.ComboPooledDataSource</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> destroy</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">method</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">close</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">
<img alt="" src="" align=top></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">property name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">driverClass</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> oracle.jdbc.driver.OracleDriver </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">
<img alt="" src="" align=top></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">property name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">jdbcUrl</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> jdbc:oracle:thin:@localhost:1521:ora9i </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">
<img alt="" src="" align=top></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">property name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">user</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">admin</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">
<img alt="" src="" align=top></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">property name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">password</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">1234</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">
<img alt="" src="" align=top></span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">bean</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">
<img alt="" src="" align=top></span></div>
</pre>
</div>
&nbsp;&nbsp;&nbsp; ComboPooledDataSource和BasicDataSource一样提供了一个用于关闭数据源的close()方法，这样我们就可以保证Spring容器关闭时数据源能够成功释放。 <br>&nbsp;&nbsp;&nbsp; C3P0拥有比DBCP更丰富的配置属性，通过这些属性，可以对数据源进行各种有效的控制： <br> acquireIncrement：当连接池中的连接用完时，C3P0一次性创建新连接的数目； <br> acquireRetryAttempts：定义在从数据库获取新连接失败后重复尝试获取的次数，默认为30； <br> acquireRetryDelay：两次连接中间隔时间，单位毫秒，默认为1000； <br> autoCommitOnClose：连接关闭时默认将所有未提交的操作回滚。默认为false； <br> automaticTestTable： C3P0将建一张名为Test的空表，并使用其自带的查询语句进行测试。如果定义了这个参数，那么属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作，它将中为C3P0测试所用，默认为null； <br> breakAfterAcquireFailure：获取连接失败将会引起所有等待获取连接的线程抛出异常。但是数据源仍有效保留，并在下次调&nbsp;&nbsp; 用getConnection()的时候继续尝试获取连接。如果设为true，那么在尝试获取连接失败后该数据源将申明已断开并永久关闭。默认为false； <br> checkoutTimeout：当连接池用完时客户端调用getConnection()后等待获取新连接的时间，超时后将抛出SQLException，如设为0则无限期等待。单位毫秒，默认为0； <br> connectionTesterClassName： 通过实现ConnectionTester或QueryConnectionTester的类来测试连接，类名需设置为全限定名。默认为com.mchange.v2.C3P0.impl.DefaultConnectionTester； <br> idleConnectionTestPeriod：隔多少秒检查所有连接池中的空闲连接，默认为0表示不检查； <br> initialPoolSize：初始化时创建的连接数，应在minPoolSize与maxPoolSize之间取值。默认为3； <br> maxIdleTime：最大空闲时间，超过空闲时间的连接将被丢弃。为0或负数则永不丢弃。默认为0； <br> maxPoolSize：连接池中保留的最大连接数。默认为15； <br> maxStatements：JDBC的标准参数，用以控制数据源内加载的PreparedStatement数量。但由于预缓存的Statement属于单个Connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素，如果maxStatements与maxStatementsPerConnection均为0，则缓存被关闭。默认为0； <br> maxStatementsPerConnection：连接池内单个连接所拥有的最大缓存Statement数。默认为0； <br> numHelperThreads：C3P0是异步操作的，缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能，通过多线程实现多个操作同时被执行。默认为3； <br> preferredTestQuery：定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个参数能显著提高测试速度。测试的表必须在初始数据源的时候就存在。默认为null； <br> propertyCycle： 用户修改系统配置参数执行前最多等待的秒数。默认为300； <br> testConnectionOnCheckout：因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable <br>等方法来提升连接测试的性能。默认为false； <br> testConnectionOnCheckin：如果设为true那么在取得连接的同时将校验连接的有效性。默认为false。 <br><br><br><strong>的方式引用属性： <br></strong>
<div style="SCROLLBAR-HIGHLIGHT-COLOR: buttonhighlight; OVERFLOW: auto; WIDTH: 500px">
<pre style="BORDER-RIGHT: black 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: black 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 4px; BORDER-LEFT: black 1px solid; PADDING-TOP: 4px; BORDER-BOTTOM: black 1px solid; BACKGROUND-COLOR: #ededed">
<div><!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><strong><img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></strong><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">bean id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">propertyConfigurer</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">org.springframework.beans.factory.config.PropertyPlaceholderConfigurer</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">property name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">location</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/WEB-INF/jdbc.properties</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">bean</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">bean id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">dataSource</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">org.apache.commons.dbcp.BasicDataSource</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> destroy</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">method</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">close</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">property name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">driverClassName</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">${jdbc.driverClassName}</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">property name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">url</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">${jdbc.url}</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">property name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">username</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">${jdbc.username}</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">property name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">password</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">${jdbc.password}</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">bean</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span></div>
</pre>
</div>
&nbsp;&nbsp;&nbsp; 在jdbc.properties属性文件中定义属性值： <br>&nbsp;&nbsp;&nbsp; jdbc.driverClassName= com.mysql.jdbc.Driver <br>&nbsp;&nbsp;&nbsp; jdbc.url= jdbc:mysql://localhost:3309/sampledb <br>&nbsp;&nbsp;&nbsp; jdbc.username=root <br>&nbsp;&nbsp;&nbsp; jdbc.password=1234 <br>&nbsp;&nbsp;&nbsp; 提示 经常有开发者在${xxx}的前后不小心键入一些空格，这些空格字符将和变量合并后作为属性的值。如：&lt;property name="username" value=" ${jdbc.username} "/&gt;的属性配置项，在前后都有空格，被解析后，username的值为&#8220; 1234 &#8221;，这将造成最终的错误，因此需要特别小心。 <br><br><strong>&nbsp;&nbsp;&nbsp; 获取JNDI数据源</strong> <br>&nbsp;&nbsp;&nbsp; 如果应用配置在高性能的应用服务器（如WebLogic或Websphere等）上，我们可能更希望使用应用服务器本身提供的数据源。应用服务器的数据源使用JNDI开放调用者使用，Spring为此专门提供引用JNDI资源的JndiObjectFactoryBean类。下面是一个简单的配置： <br>
<div style="SCROLLBAR-HIGHLIGHT-COLOR: buttonhighlight; OVERFLOW: auto; WIDTH: 500px">
<pre style="BORDER-RIGHT: black 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: black 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 4px; BORDER-LEFT: black 1px solid; PADDING-TOP: 4px; BORDER-BOTTOM: black 1px solid; BACKGROUND-COLOR: #ededed">
<div><!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">bean id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">dataSource</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">org.springframework.jndi.JndiObjectFactoryBean</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">property name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">jndiName</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">java:comp/env/jdbc/bbt</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">bean</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span></div>
</pre>
</div>
&nbsp;&nbsp;&nbsp; 通过jndiName指定引用的JNDI数据源名称。 <br>&nbsp;&nbsp;&nbsp; Spring 2.0为获取J2EE资源提供了一个jee命名空间，通过jee命名空间，可以有效地简化J2EE资源的引用。下面是使用jee命名空间引用JNDI数据源的配置： <br>
<div style="SCROLLBAR-HIGHLIGHT-COLOR: buttonhighlight; OVERFLOW: auto; WIDTH: 500px">
<pre style="BORDER-RIGHT: black 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: black 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 4px; BORDER-LEFT: black 1px solid; PADDING-TOP: 4px; BORDER-BOTTOM: black 1px solid; BACKGROUND-COLOR: #ededed">
<div><!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">beans xmlns</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">http://www.springframework.org/schema/beans</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top>xmlns:xsi</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">http://www.w3.org/2001/XMLSchema-instance</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top>xmlns:jee</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">http://www.springframework.org/schema/jee</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top>xsi:schemaLocation</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">http://www.springframework.org/schema/beans </span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">http:</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">www.springframework.org/schema/beans/spring-beans-2.0.xsd </span><span style="COLOR: #008000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">http:</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">www.springframework.org/schema/jee </span><span style="COLOR: #008000; TEXT-DECORATION: underline">http://www.springframework.org/schema/jee/spring-jee-2.0.xsd</span><span style="COLOR: #008000">"&gt; </span><span style="COLOR: #008000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">jee:jndi</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">lookup id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">dataSource</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> jndi</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> java:comp/env/jdbc/bbt</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">beans</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span></div>
</pre>
</div>
&nbsp;&nbsp;&nbsp; Spring的数据源实现类 <br>&nbsp;&nbsp;&nbsp; Spring本身也提供了一个简单的数据源实现类DriverManagerDataSource ，它位于org.springframework.jdbc.datasource包中。这个类实现了javax.sql.DataSource接口，但它并没有提供池化连接的机制，每次调用getConnection()获取新连接时，只是简单地创建一个新的连接。因此，这个数据源类比较适合在单元测试或简单的独立应用中使用，因为它不需要额外的依赖类。 <br>&nbsp;&nbsp;&nbsp;&nbsp; 下面，我们来看一下DriverManagerDataSource的简单使用： <br>
<div style="SCROLLBAR-HIGHLIGHT-COLOR: buttonhighlight; OVERFLOW: auto; WIDTH: 500px">
<pre style="BORDER-RIGHT: black 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: black 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 4px; BORDER-LEFT: black 1px solid; PADDING-TOP: 4px; BORDER-BOTTOM: black 1px solid; BACKGROUND-COLOR: #ededed">
<div><!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">DriverManagerDataSource ds </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> DriverManagerDataSource ();
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top>ds.setDriverClassName(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">com.mysql.jdbc.Driver</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top>ds.setUrl(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">jdbc:mysql://localhost:3309/sampledb</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top>ds.setUsername(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">root</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top>ds.setPassword(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">1234</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top>Connection actualCon </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> ds.getConnection();
<img alt="" src="http://cms.it168.com/Images/OutliningIndicators/None.gif" align=top></span></div>
</pre>
</div>
&nbsp;&nbsp; 当然，我们也可以通过配置的方式直接使用DriverManagerDataSource。 <br>&nbsp;&nbsp;&nbsp; 小结 <br>&nbsp;&nbsp;&nbsp; 不管采用何种持久化技术，都需要定义数据源。Spring附带了两个数据源的实现类包，你可以自行选择进行定义。在实际部署时，我们可能会直接采用应用服务器本身提供的数据源，这时，则可以通过JndiObjectFactoryBean或jee命名空间引用JNDI中的数据源。 
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/120026.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2007-05-25 16:33 <a href="http://www.blogjava.net/wangxinsh55/archive/2007/05/25/120026.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c3p0在Spring中的配置 </title><link>http://www.blogjava.net/wangxinsh55/archive/2007/05/25/120021.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Fri, 25 May 2007 08:29:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2007/05/25/120021.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/120021.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2007/05/25/120021.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/120021.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/120021.html</trackback:ping><description><![CDATA[&nbsp;
<ol>
    <li class=alt><span><span class=comments>&lt;!--&nbsp;DataSource&nbsp;Definition,&nbsp;using&nbsp;c3p0&nbsp;connection&nbsp;pool&nbsp;--&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=""><span><span class=tag>&lt;</span><span class=tag-name>bean</span><span>&nbsp;</span><span class=attribute>id</span><span>=</span><span class=attribute-value>"dataSource"</span><span>&nbsp;</span><span class=attribute>class</span><span>=</span><span class=attribute-value>"com.mchange.v2.c3p0.ComboPooledDataSource"</span><span>&nbsp;</span><span class=attribute>destroy-method</span><span>=</span><span class=attribute-value>"close"</span><span class=tag>&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=alt><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"driverClass"</span><span>&nbsp;</span><span class=attribute>value</span><span>=</span><span class=attribute-value>"${jdbc.driverClassName}"</span><span>&nbsp;</span><span class=tag>/&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"jdbcUrl"</span><span>&nbsp;</span><span class=attribute>value</span><span>=</span><span class=attribute-value>"${jdbc.url}"</span><span>&nbsp;</span><span class=tag>/&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=alt><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"user"</span><span>&nbsp;</span><span class=attribute>value</span><span>=</span><span class=attribute-value>"${jdbc.username}"</span><span>&nbsp;</span><span class=tag>/&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"password"</span><span>&nbsp;</span><span class=attribute>value</span><span>=</span><span class=attribute-value>"${jdbc.password}"</span><span>&nbsp;</span><span class=tag>/&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=alt><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"minPoolSize"</span><span>&nbsp;</span><span class=attribute>value</span><span>=</span><span class=attribute-value>"10"</span><span>&nbsp;</span><span class=tag>/&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"maxPoolSize"</span><span>&nbsp;</span><span class=attribute>value</span><span>=</span><span class=attribute-value>"20"</span><span>&nbsp;</span><span class=tag>/&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=alt><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"maxIdleTime"</span><span>&nbsp;</span><span class=attribute>value</span><span>=</span><span class=attribute-value>"1800"</span><span>&nbsp;</span><span class=tag>/&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"acquireIncrement"</span><span>&nbsp;</span><span class=attribute>value</span><span>=</span><span class=attribute-value>"2"</span><span>&nbsp;</span><span class=tag>/&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=alt><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"maxStatements"</span><span>&nbsp;</span><span class=attribute>value</span><span>=</span><span class=attribute-value>"0"</span><span>&nbsp;</span><span class=tag>/&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"initialPoolSize"</span><span>&nbsp;</span><span class=attribute>value</span><span>=</span><span class=attribute-value>"2"</span><span>&nbsp;</span><span class=tag>/&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=alt><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"idleConnectionTestPeriod"</span><span>&nbsp;</span><span class=attribute>value</span><span>=</span><span class=attribute-value>"1800"</span><span>&nbsp;</span><span class=tag>/&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"acquireRetryAttempts"</span><span>&nbsp;</span><span class=attribute>value</span><span>=</span><span class=attribute-value>"30"</span><span>&nbsp;</span><span class=tag>/&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=alt><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"breakAfterAcquireFailure"</span><span>&nbsp;</span><span class=attribute>value</span><span>=</span><span class=attribute-value>"true"</span><span>&nbsp;</span><span class=tag>/&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"testConnectionOnCheckout"</span><span>&nbsp;</span><span class=attribute>value</span><span>=</span><span class=attribute-value>"false"</span><span>&nbsp;</span><span class=tag>/&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=alt><span><span class=tag>&lt;/</span><span class=tag-name>bean</span><span class=tag>&gt;</span></span></li>
</ol>
<p class=alt><span><span class=tag><br><br>&nbsp;</p>
<h1 class=block_title><a id=viewpost1_TitleUrl href="http://www.blogjava.net/grantbb/archive/2006/12/18/88601.html"><font color=#808080>Spring整合C3P0的配置</font></a></h1>
<div class=post>
<div class=postcontent>网上没有找到比较合适的，自己看了看，然后放到项目中实验的一下。<br>很多人都认为比DBCP优秀。<br><br>&lt;bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="driverClass"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;${jdbc.driverClassName}&lt;/value&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="jdbcUrl"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;${jdbc.url}&lt;/value&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="user"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&lt;value&gt;${jdbc.username}&lt;/value&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="password"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&lt;value&gt;${jdbc.password}&lt;/value&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="initialPoolSize"&gt;&lt;value&gt;10&lt;/value&gt;&lt;/property&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="minPoolSize"&gt;&lt;value&gt;5&lt;/value&gt;&lt;/property&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="maxPoolSize"&gt;&lt;value&gt;30&lt;/value&gt;&lt;/property&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="acquireIncrement"&gt;&lt;value&gt;5&lt;/value&gt;&lt;/property&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="maxIdleTime"&gt;&lt;value&gt;10&lt;/value&gt;&lt;/property&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="maxStatements"&gt;&lt;value&gt;0&lt;/value&gt;&lt;/property&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br><br>以下几个参数是使用的基本配置参数：<br>initialPoolSize： <br>Number of Connections a pool will try to acquire upon startup. Should be between minPoolSize and maxPoolSize<br>连接池初始化时获取的链接数，介于minPoolSize和maxPoolSize之间<br><br>minPoolSize：<br>Minimum number of Connections a pool will maintain at any given time.<br>最小链接数<br><br>maxPoolSize：<br>Maximum number of Connections a pool will maintain at any given time.<br>最大连接数<br><br>acquireIncrement：<br>Determines how many connections at a time c3p0 will try to acquire when the pool is exhausted.<br>在当前连接数耗尽的时候，一次获取的新的连接数<br><br>maxIdleTime：<br>Seconds a Connection can remain pooled but unused before being discarded. Zero means idle connections never expire.<br>最大空闲的时间，单位是秒，无用的链接再过时后会被回收<br></div>
</div>
</span></span>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/120021.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2007-05-25 16:29 <a href="http://www.blogjava.net/wangxinsh55/archive/2007/05/25/120021.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>commons DBCP 配置说明</title><link>http://www.blogjava.net/wangxinsh55/archive/2007/05/25/120015.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Fri, 25 May 2007 07:45:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2007/05/25/120015.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/120015.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2007/05/25/120015.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/120015.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/120015.html</trackback:ping><description><![CDATA[<p>　　前段时间因为项目原因，要在修改数据库连接池到DBCP上，折腾了半天，有一点收获，不敢藏私，特在这里与朋友们共享。<br>　　在配置时，主要难以理解的主要有：removeAbandoned 、logAbandoned、removeAbandonedTimeout、maxWait这四个参数，设置了rmoveAbandoned=true那么在getNumActive()快要到getMaxActive()的时候，系统会进行无效的Connection的回收，回收的Connection为removeAbandonedTimeout(默认300秒)中设置的秒数后没有使用的Connection，激活回收机制好像是getNumActive()=getMaxActive()-2。 :) 有点忘了。<br>　　logAbandoned=true的话，将会在回收事件后，在log中打印出回收Connection的错误信息，包括在哪个地方用了Connection却忘记关闭了，在调试的时候很有用。<br>　　在这里私人建议maxWait的时间不要设得太长，maxWait如果设置太长那么客户端会等待很久才激发回收事件。<br>　　以下是我的配置的properties文件：<br>#连接设置<br>jdbc.driverClassName=oracle.jdbc.driver.OracleDriver<br>jdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:DBSERVER<br>jdbc.username=user<br>jdbc.password=pass</p>
<p>#&lt;!-- 初始化连接 --&gt;<br>dataSource.initialSize=10</p>
<p>#&lt;!-- 最大空闲连接 --&gt;<br>dataSource.maxIdle=20</p>
<p>#&lt;!-- 最小空闲连接 --&gt;<br>dataSource.minIdle=5</p>
<p>#最大连接数量<br>dataSource.maxActive=50</p>
<p>#是否在自动回收超时连接的时候打印连接的超时错误<br>dataSource.logAbandoned=true</p>
<p>#是否自动回收超时连接<br>dataSource.removeAbandoned=true</p>
<p>#超时时间(以秒数为单位)<br>#设置超时时间有一个要注意的地方，超时时间=现在的时间-程序中创建Connection的时间，如果maxActive比较大，比如超过100，那么removeAbandonedTimeout可以设置长一点比如180，也就是三分钟无响应的连接进行回收，当然应用的不同设置长度也不同。<br>dataSource.removeAbandonedTimeout=180</p>
<p>#&lt;!-- 超时等待时间以毫秒为单位 --&gt;<br>#maxWait代表当Connection用尽了，多久之后进行回收丢失连接<br>dataSource.maxWait=1000<br><br>　　以下是我在连接控制中调用的方法：<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Properties&nbsp; dbProps=null;<br>　　//下面的读取配置文件可以根据实际的不同修改<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dbProps = ConfigProperties.getInstance().getProperties("jdbc.properties");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;String driveClassName = dbProps.getProperty("jdbc.driverClassName");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;String url = dbProps.getProperty("jdbc.url");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;String username = dbProps.getProperty("jdbc.username");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;String password = dbProps.getProperty("jdbc.password");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;String initialSize = dbProps.getProperty("dataSource.initialSize");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;String minIdle = dbProps.getProperty("dataSource.minIdle");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;String maxIdle = dbProps.getProperty("dataSource.maxIdle");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;String maxWait = dbProps.getProperty("dataSource.maxWait");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;String maxActive = dbProps.getProperty("dataSource.maxActive");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;//是否在自动回收超时连接的时候打印连接的超时错误<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;boolean logAbandoned = (Boolean.valueOf(dbProps.getProperty("dataSource.logAbandoned","false"))).booleanValue();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;//是否自动回收超时连接<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;boolean removeAbandoned = (Boolean.valueOf(dbProps.getProperty("dataSource.removeAbandoned","false"))).booleanValue();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;//超时时间(以秒数为单位)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;int removeAbandonedTimeout = Integer.parseInt(dbProps.getProperty("dataSource.removeAbandonedTimeout","300"));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;dataSource = new BasicDataSource();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;dataSource.setDriverClassName(driveClassName);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;dataSource.setUrl(url);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;dataSource.setUsername(username);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;dataSource.setPassword(password);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;//初始化连接数<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;if(initialSize!=null)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;dataSource.setInitialSize(Integer.parseInt(initialSize));<br>&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;if(minIdle!=null)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;dataSource.setMinIdle(Integer.parseInt(minIdle));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;//最大空闲连接<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;if(maxIdle!=null)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;dataSource.setMaxIdle(Integer.parseInt(maxIdle));<br>&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;if(maxWait!=null)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;dataSource.setMaxWait(Long.parseLong(maxWait));<br>&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;if(maxActive!=null){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;if(!maxActive.trim().equals("0"))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;dataSource.setMaxActive(Integer.parseInt(maxActive));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;System.out.println("logAbandoned="+logAbandoned);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;dataSource.setLogAbandoned(logAbandoned);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;dataSource.setRemoveAbandoned(removeAbandoned);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;dataSource.setRemoveAbandonedTimeout(removeAbandonedTimeout);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;Connection conn = dataSource.getConnection();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;if(conn==null){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;log.error("创建连接池时,无法取得连接!检查设置!!!");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;}else{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;conn.close();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.error("连接池创建成功!!!");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (Exception e) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log.error("创建连接池失败!请检查设置!!!");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br></p>
<p>有误的地方欢迎指正!&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;by yy。。。。。。</p>
<br><br>
<p>Hibernate支持DBCP包进行数据库连接池的配置。简要说明配置过程： <br>(仅仅是个人摸索，如有问题，欢迎指点) <br>需要的包： <br>Commons-Pool （下载地址：<a href="http://jakarta.apache.org/commons/pool/" target=blank><u><font color=#0000ff>http://jakarta.apache.org/commons/pool/</font></u></a>） ：提供一个一般对象池的接口，而且包含实现了通常池工具箱。 <br>Commons-DBCP（下载地址：<a href="http://jakarta.apache.org/commons/dbcp/" target=blank><u><font color=#0000ff>http://jakarta.apache.org/commons/dbcp/</font></u></a>） ：提供数据库连接池服务。DBCP很聪明，把Commons-Pool和JDBC的driver封装起来，使达到连接池的目的。</p>
<p>Hibernate属性文件的配置参数 <br>#连接池的最大活动个数 <br>hibernate.dbcp.maxActive 100 <br>#当连接池中的连接已经被耗尽的时候，DBCP将怎样处理( 0 = 失败, 1 = 等待, 2= 增长) <br>hibernate.dbcp.whenExhaustedAction 1 <br>#最大等待时间 <br>hibernate.dbcp.maxWait 120000 <br>#没有人用连接的时候，最大闲置的连接个数。 <br>hibernate.dbcp.maxIdle 10 <br>##以下是对prepared statement的处理，同上。 <br>hibernate.dbcp.ps.maxActive 100 <br>hibernate.dbcp.ps.whenExhaustedAction 1 <br>hibernate.dbcp.ps.maxWait 120000 <br>hibernate.dbcp.ps.maxIdle 10</p>
<p>## 可选，是否对池化的连接进行验证 <br>#给出一条简单的sql语句进行验证 <br>#hibernate.dbcp.validationQuery select 1 from dual <br>#在取出连接时进行有效验证 <br>#hibernate.dbcp.testOnBorrow true <br>#在放回连接时进行有效验证 <br>#hibernate.dbcp.testOnReturn false</p>
<p>#Hibernate已经实现了DBCP Provider实现，别忘了在下面的键值去掉＃字符 <br>hibernate.connection.provider_class net.sf.hibernate.connection.DBCPConnectionProvider</p>
<br><br>
<ol>
    <li class=alt><span><span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"connection.pool.size"</span><span class=tag>&gt;</span><span>2</span><span class=tag>&lt;/</span><span class=tag-name>property</span><span class=tag>&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span></span><span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"statement_cache.size"</span><span class=tag>&gt;</span><span>25</span><span class=tag>&lt;/</span><span class=tag-name>property</span><span class=tag>&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=alt><span></span><span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"jdbc.fetch_size"</span><span class=tag>&gt;</span><span>50</span><span class=tag>&lt;/</span><span class=tag-name>property</span><span class=tag>&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span></span><span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"jdbc.batch_size"</span><span class=tag>&gt;</span><span>30</span><span class=tag>&lt;/</span><span class=tag-name>property</span><span class=tag>&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=alt><span>&nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"show_sql"</span><span class=tag>&gt;</span><span>true</span><span class=tag>&lt;/</span><span class=tag-name>property</span><span class=tag>&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=alt><span></span><span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"connection.provider_class"</span><span class=tag>&gt;</span><span>net.sf.hibernate.connection.DBCPConnectionProvider</span><span class=tag>&lt;/</span><span class=tag-name>property</span><span class=tag>&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span></span><span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"dbcp.maxActive"</span><span class=tag>&gt;</span><span>100</span><span class=tag>&lt;/</span><span class=tag-name>property</span><span class=tag>&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=alt><span></span><span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"dbcp.whenExhaustedAction"</span><span class=tag>&gt;</span><span>1</span><span class=tag>&lt;/</span><span class=tag-name>property</span><span class=tag>&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span></span><span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"dbcp.maxWait"</span><span class=tag>&gt;</span><span>120000</span><span class=tag>&lt;/</span><span class=tag-name>property</span><span class=tag>&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=alt><span></span><span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"dbcp.maxIdle"</span><span class=tag>&gt;</span><span>10</span><span class=tag>&lt;/</span><span class=tag-name>property</span><span class=tag>&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span></span><span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"dbcp.ps.maxActive"</span><span class=tag>&gt;</span><span>100</span><span class=tag>&lt;/</span><span class=tag-name>property</span><span class=tag>&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=alt><span></span><span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"dbcp.ps.whenExhaustedAction"</span><span class=tag>&gt;</span><span>1</span><span class=tag>&lt;/</span><span class=tag-name>property</span><span class=tag>&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span></span><span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"dbcp.ps.maxWait"</span><span class=tag>&gt;</span><span>120000</span><span class=tag>&lt;/</span><span class=tag-name>property</span><span class=tag>&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=alt><span></span><span class=tag>&lt;</span><span class=tag-name>property</span><span>&nbsp;</span><span class=attribute>name</span><span>=</span><span class=attribute-value>"dbcp.ps.maxIdle"</span><span class=tag>&gt;</span><span>100</span><span class=tag>&lt;/</span><span class=tag-name>property</span><span class=tag>&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/120015.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2007-05-25 15:45 <a href="http://www.blogjava.net/wangxinsh55/archive/2007/05/25/120015.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>无尽的任务 JSON </title><link>http://www.blogjava.net/wangxinsh55/archive/2007/01/04/91708.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Thu, 04 Jan 2007 03:03:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2007/01/04/91708.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/91708.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2007/01/04/91708.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/91708.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/91708.html</trackback:ping><description><![CDATA[
		<p>技术饭还真是不好吃,今天为了搞定眼下这个难题,选择了Ajax.在看Ajax的时候看到了Json.这个东西看着不错,好吧,上网去down个用.</p>
		<p>打开网站开始寻找我的目标,发现这个东西居然有好多版本.比如</p>
		<li>JSON in ActionScript: 
<ul><li><a href="http://www.schaffhausen.de/downloads/json.html">ActionScript1</a>. 
</li><li><a href="http://www.theorganization.net/work/jos/JSON.as">ActionScript2</a>. </li></ul><ul><li><a href="http://labs.adobe.com/wiki/index.php/ActionScript_3:resources:apis:libraries#corelib">ActionScript3</a>. </li></ul></li>
		<li>
				<a href="http://oss.metaparadigm.com/json-c/">JSON in C</a>. 
<ul><li><a href="http://www.json.org/JSON_checker/">JSON_checker</a>. </li></ul></li>
		<li>JSON in C++: 
<ul><li><a href="http://sourceforge.net/projects/jsoncpp/">jsoncpp</a>. 
</li><li><a href="http://cvs.sourceforge.net/viewcvs.py/zoolib/zoolib/src_other/misc/">zoolib</a>. </li></ul></li>
		<li>JSON in C#: 
<ul><li><a href="http://jayrock.berlios.de/">Jayrock</a>. 
</li><li><a href="http://www.newtonsoft.com/products/json/">Newtonsoft Json.NET</a>. </li></ul></li>
		<li>JSON in Cold Fusion. 
<ul><li><a href="http://jehiah.com/projects/cfjson/">CFJSON</a>. 
</li><li><a href="http://cfopen.org/projects/json-serializer/%20">JSON Serializer</a>. </li></ul></li>
		<li>
				<a href="https://sourceforge.net/projects/is-webstart/">JSON in Delphi</a>. 
</li>
		<li>JSON in <a href="http://erights.org/data/terml/embeddings.html">E</a>. 
</li>
		<li>
				<a href="http://www.erlang-projects.org/Public/news/ejson/view">JSON in Erlang</a>. 
</li>
		<li>JSON in Java: 
<ul><li><a href="http://www.json.org/java/index.html">org.json</a>. 
</li><li><a href="http://json-lib.sourceforge.net/">Json-lib</a>. 
</li><li><a href="http://developer.berlios.de/projects/jsontools/">JSON Tools</a>. 
</li><li><a href="http://www.json.org/java/simple.txt">org.json.simple</a>. 
</li><li><a href="http://blog.stringtree.org/2006/08/12/json/">Stringtree</a>. </li></ul></li>
		<li>
				<a href="http://www.json.org/js.html">JSON in JavaScript</a>. 
</li>
		<li>JSON in Lisp: 
<ul><li><a href="http://common-lisp.net/project/cl-json/">Common Lisp</a>. 
</li><li><a href="http://edward.oconnor.cx/elisp/json.el">Emacs Lisp</a>. 
</li><li><a href="http://www.call-with-current-continuation.org/eggs/json.html">Chicken Scheme</a>. 
</li><li><a href="http://www.lshift.net/blog/2005/08/22/json-for-mzscheme-and-a-portable-packrat-parsing-combinator-library">MZScheme</a>. </li></ul></li>
		<li>
				<a href="http://json.luaforge.net/">JSON in Lua</a>. 
</li>
		<li>
				<a href="http://sourceforge.net/projects/json">JSON in ML and Ruby</a>. 
</li>
		<li>
				<a href="http://blakeseely.com/blog/archives/2006/03/29/bsjsonadditions-12/">JSON in Objective C</a>. 
</li>
		<li>
				<a href="http://freshmeat.net/projects/ocaml-json/">JSON in Objective CAML</a>. 
</li>
		<li>
				<a href="http://osteele.com/sources/openlaszlo/json/">JSON in OpenLaszlo</a>. 
</li>
		<li>
				<a href="http://search.cpan.org/dist/JSON/">JSON in Perl</a>. 
</li>
		<li>JSON in PHP: 
<ul><li><a href="http://framework.zend.com/manual/en/zend.json.html">Zend_JSON</a></li><li><a href="http://mike.teczno.com/json.html">JSON-PHP</a>. 
</li><li><a href="http://www.aurore.net/projects/php-json/">PHP-JSON</a>. 
</li><li><a href="http://pear.php.net/pepr/pepr-proposal-show.php?id=198">Services_JSON</a>. 
</li><li><a href="http://freshmeat.net/projects/json_php_package/">JSON PHP</a>. </li></ul></li>
		<li>
				<a href="http://undefined.org/python/#simple_json">JSON in Python</a>. 
</li>
		<li>
				<a href="http://www.json.org/json.r">JSON in Rebol</a>. 
</li>
		<li>
				<a href="http://rubyforge.org/snippet/detail.php?type=snippet&amp;id=29">JSON in Ruby</a>. 
</li>
		<li>
				<a href="http://map1.squeakfoundation.org/sm/package/d38bdc2d-e52a-4167-ae73-2cf438c65c2f">JSON in Squeak</a>. 
<p>说实话,看到这些玩意,心里面顿时是凉了半截.</p><p>好多名词!!!</p><p>.看着这些东西感觉自己特别无知.幸好大多脸熟,心里面的虚荣心还没有跌倒低谷.</p><p>点击一个链接,比现在多一倍的新链接出现在眼前,每一个链接代表一个知识点.页面呈现的一瞬间理智立刻崩溃了.只是一个名不见经传的json就有如此之多的知识,那么其他的.......面对无穷无尽的知识海洋,不由理解了知识是学不完这句话.</p><p>在知识爆炸的今天,也许只有"现用现学"是解决这种情况的最好办法.</p><p>可是面对这些东西,开始觉得那句:"现用现学"是多么恐怖的一种境界.这种东西现学了能马上会用,用不是问题,问题是用这些新东西还能算出工程进度,还能编出可以维护的代码.如果再能保证代码的健壮性,那........</p><p>这里不由想到另一个问题:为什么现用现学还能用呢?如果是全新的东西,快速的学习肯定神仙也做不了.所以看起来全新的知识应该有相应的共通点.</p><p>是不是因为面向对象的思想呢?个人猜测,可能性比较大,因为一旦变成对象了,就可以不管他们的实现方式,一律归到已有的面向对象的思路中来,无非是多了几个新元素要记而已.要是这样,真应该感谢面向对象.</p><br /></li>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/91708.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2007-01-04 11:03 <a href="http://www.blogjava.net/wangxinsh55/archive/2007/01/04/91708.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于W3C DOM </title><link>http://www.blogjava.net/wangxinsh55/archive/2006/12/31/91199.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Sun, 31 Dec 2006 08:59:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2006/12/31/91199.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/91199.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2006/12/31/91199.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/91199.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/91199.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: W3C   DOM																		文档对象模型														(DOM)												是与平台和语言无关的接口，允许程序和脚本动态地访问和更新文档的内容，结构和样式。文档可以进一步处理，处理的结果可以放回到所提供的页面中。																																 	...&nbsp;&nbsp;<a href='http://www.blogjava.net/wangxinsh55/archive/2006/12/31/91199.html'>阅读全文</a><img src ="http://www.blogjava.net/wangxinsh55/aggbug/91199.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2006-12-31 16:59 <a href="http://www.blogjava.net/wangxinsh55/archive/2006/12/31/91199.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Ajax中使用JSON </title><link>http://www.blogjava.net/wangxinsh55/archive/2006/12/31/91198.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Sun, 31 Dec 2006 08:52:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2006/12/31/91198.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/91198.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2006/12/31/91198.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/91198.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/91198.html</trackback:ping><description><![CDATA[提交数据使用json代替xml
<p>    页面：jsonExample.jsp</p><p>&lt;%@ page contentType="text/html; charset=GBK" %&gt;<br />&lt;html&gt;<br />&lt;head&gt;<br />&lt;title&gt;<br />JSON示例<br />&lt;/title&gt;<br />&lt;script type="text/javascript" src="zxml.src.js"&gt;&lt;/script&gt;<br />&lt;script type="text/javascript" src="json.js"&gt;&lt;/script&gt;<br />&lt;script type="text/javascript"&gt;<br /> var xmlHttp;<br />        <br />        //创建对象<br />        function createXMLHttpRequest(){<br />         xmlHttp = zXmlHttp.createRequest();<br />        }<br />        <br />        function doJSON(){<br />           //得到Car对象<br />         var car = getCarObject();<br />                <br />                //用JSON字符串化car对象<br />                var carAsJSON = car.toJSONString();<br />                alert("汽车对象JSON化为:\n" + carAsJSON);<br />                <br />                var url = "JSONExample?timeStamp=" + new Date().getTime();<br />                <br />                //创建对象<br />                createXMLHttpRequest();<br />                xmlHttp.open("POST",url,true);<br />                xmlHttp.onreadystatechange = handleStateChange;<br />                xmlHttp.setRequestHeader("Content-Type","application/x-www-form.urlencoded");<br />                xmlHttp.send(carAsJSON);<br />        }<br />        <br />        //回调方法<br />        function handleStateChange(){<br />         if (xmlHttp.readyState == 4){<br />                 if (xmlHttp.status == 200){<br />                         parseResults();<br />                        }<br />                }<br />        }<br />        <br />        //解析结果<br />        function parseResults(){<br />         var responseDiv = document.getElementById("serverResponse");<br />                if (responseDiv.hasChildNodes()){<br />                 responseDiv.removeChild(responseDiv.childNode[0]);<br />                }<br />                <br />                var responseText = document.createTextNode(xmlHttp.responseText);<br />                responseDiv.appendChild(responseText);<br />        }<br />        <br />        //得到Car对象<br />        function getCarObject(){<br />         return new Car("Dodge","Coronet R/T",1968,"yellow");<br />        }<br />        <br />        <br />        //Car构造函数<br />        function Car(make,model,year,color){<br />         this.make = make;<br />                this.model = model;<br />                this.year = year;<br />                this.color = color;<br />        }<br />&lt;/script&gt;<br />&lt;/head&gt;<br />&lt;body&gt;<br />&lt;br /&gt;&lt;br /&gt;<br />&lt;form action="#"&gt;<br />  &lt;input type="button" value="发送JSON数据" onclick="doJSON();"/&gt;<br />&lt;/form&gt;<br />&lt;h2&gt;<br />  服务器响应：<br />&lt;/h2&gt;<br />&lt;div id="serverResponse"&gt;<br />&lt;/div&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;<br /></p><p>    服务器：JSONExample.java</p><p>package ajaxbook.chap4;</p><p>import java.io.*;<br />import java.net.*;<br />import java.text.ParseException;<br />import javax.servlet.*;<br />import javax.servlet.http.*;<br />import org.json.JSONObject;</p><p>public class JSONExample<br />    extends HttpServlet {<br />  //处理Post方法<br />  protected void doPost(HttpServletRequest request,<br />                        HttpServletResponse response) throws ServletException,<br />      IOException {<br />    String json = readJSONStringFromRequestBody(request);</p><p>    //使用JSON绑字Ajax对象<br />    JSONObject jsonObject = null;<br />    try {<br />      jsonObject = new JSONObject(json);<br />    }<br />    catch (ParseException pe) {<br />      System.out.println("ParseException: " + pe.toString());<br />    }</p><p>    //返回输出结果<br />    String responseText = "You have a " + jsonObject.getInt("year") + " "<br />        + jsonObject.getString("make") + " " + jsonObject.getString("model")<br />        + " " + " that is " + jsonObject.getString("color") + " in color.";</p><p>    response.setContentType("text/xml");<br />    response.getWriter().print(responseText);<br />  }</p><p>  //得到参数<br />  private String readJSONStringFromRequestBody(HttpServletRequest request) {<br />    StringBuffer json = new StringBuffer();<br />    String line = null;<br />    try {<br />      BufferedReader reader = request.getReader();<br />      while ( (line = reader.readLine()) != null) {<br />        json.append(line);<br />      }<br />    }<br />    catch (Exception e) {<br />      System.out.println("Error reading JSON string: " + e.toString());<br />    }<br />    return json.toString();<br />  }<br />}</p><p> </p><p>注意：要引入json.js和json的源文件，使用json.jar不行，源文件参见书籍源代码第三章</p><p>参考：Ajax基础教程  作笔记吧 </p><br /><br /><p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=975204</p><img src ="http://www.blogjava.net/wangxinsh55/aggbug/91198.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2006-12-31 16:52 <a href="http://www.blogjava.net/wangxinsh55/archive/2006/12/31/91198.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>经典：Java及相关字符集编码问题研究</title><link>http://www.blogjava.net/wangxinsh55/archive/2006/12/28/90473.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Thu, 28 Dec 2006 05:21:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2006/12/28/90473.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/90473.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2006/12/28/90473.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/90473.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/90473.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td valign="top" width="86%">1. 概述<br /><br />本文主要包括以下几个方面：编码基本知识，java，系统软件，url，工具软件等。<br /><br />在下面的描述中，将以"中文"两个字为例，经查表可以知道其GB2312编码是"d6d0 cec4"，Unicode编码为"4e2d 6587"，UTF编码就是"e4b8ad e69687"。注意，这两个字没有iso8859-1编码，但可以用iso8859-1编码来"表示"。<br /><br />2. 编码基本知识<br /><br />最早的编码是iso8859-1，和ascii编码相似。但为了方便表示各种各样的语言，逐渐出现了很多标准编码，重要的有如下几个。<br /><br />2.1. iso8859-1<br /><br />属于单字节编码，最多能表示的字符范围是0-255，应用于英文系列。比如，字母a的编码为0x61=97。<br /><br />很明显，iso8859-1编码表示的字符范围很窄，无法表示中文字符。但是，由于是单字节编码，和计算机最基础的表示单位一致，所以很多时候，仍旧使用iso8859-1编码来表示。而且在很多协议上，默认使用该编码。比如，虽然"中文"两个字不存在iso8859-1编码，以gb2312编码为例，应该是"d6d0 cec4"两个字符，使用iso8859-1编码的时候则将它拆开为4个字节来表示："d6 d0 ce c4"（事实上，在进行存储的时候，也是以字节为单位处理的）。而如果是UTF编码，则是6个字节"e4 b8 ad e6 96 87"。很明显，这种表示方法还需要以另一种编码为基础。<br /><br />2.2. GB2312/GBK<br /><br />这就是汉子的国标码，专门用来表示汉字，是双字节编码，而英文字母和iso8859-1一致（兼容iso8859-1编码）。其中gbk编码能够用来同时表示繁体字和简体字，而gb2312只能表示简体字，gbk是兼容gb2312编码的。<br /><br />2.3. unicode<br /><br />这是最统一的编码，可以用来表示所有语言的字符，而且是定长双字节（也有四字节的）编码，包括英文字母在内。所以可以说它是不兼容iso8859-1编码的，也不兼容任何编码。不过，相对于iso8859-1编码来说，uniocode编码只是在前面增加了一个0字节，比如字母a为"00 61"。<br /><br />需要说明的是，定长编码便于计算机处理（注意GB2312/GBK不是定长编码），而unicode又可以用来表示所有字符，所以在很多软件内部是使用unicode编码来处理的，比如java。<br /><br />2.4. UTF<br /><br />考虑到unicode编码不兼容iso8859-1编码，而且容易占用更多的空间：因为对于英文字母，unicode也需要两个字节来表示。所以unicode不便于传输和存储。因此而产生了utf编码，utf编码兼容iso8859-1编码，同时也可以用来表示所有语言的字符，不过，utf编码是不定长编码，每一个字符的长度从1-6个字节不等。另外，utf编码自带简单的校验功能。一般来讲，英文字母都是用一个字节表示，而汉字使用三个字节。<br /><br />注意，虽然说utf是为了使用更少的空间而使用的，但那只是相对于unicode编码来说，如果已经知道是汉字，则使用GB2312/GBK无疑是最节省的。不过另一方面，值得说明的是，虽然utf编码对汉字使用3个字节，但即使对于汉字网页，utf编码也会比unicode编码节省，因为网页中包含了很多的英文字符。<br /><br />3. java对字符的处理<br /><br />在java应用软件中，会有多处涉及到字符集编码，有些地方需要进行正确的设置，有些地方需要进行一定程度的处理。<br /><br />3.1. getBytes(charset)<br /><br />这是java字符串处理的一个标准函数，其作用是将字符串所表示的字符按照charset编码，并以字节方式表示。注意字符串在java内存中总是按unicode编码存储的。比如"中文"，正常情况下（即没有错误的时候）存储为"4e2d 6587"，如果charset为"gbk"，则被编码为"d6d0 cec4"，然后返回字节"d6 d0 ce c4"。如果charset为"utf8"则最后是"e4 b8 ad e6 96 87"。如果是"iso8859-1"，则由于无法编码，最后返回 "3f 3f"（两个问号）。<br /><br />3.2. new String(charset)<br /><br />这是java字符串处理的另一个标准函数，和上一个函数的作用相反，将字节数组按照charset编码进行组合识别，最后转换为unicode存储。参考上述getBytes的例子，"gbk" 和"utf8"都可以得出正确的结果"4e2d 6587"，但iso8859-1最后变成了"003f 003f"（两个问号）。<br /><br />因为utf8可以用来表示/编码所有字符，所以new String( str.getBytes( "utf8" ), "utf8" ) === str，即完全可逆。<br /><br />3.3. setCharacterEncoding()<br /><br />该函数用来设置http请求或者相应的编码。<br /><br />对于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()自然就无效。<br /><br />对于response，则是指定输出内容的编码，同时，该设置会传递给浏览器，告诉浏览器输出内容所采用的编码。<br /><br />3.4. 处理过程<br /><br />下面分析两个有代表性的例子，说明java对编码有关问题的处理方法。<br /><br />3.4.1. 表单输入<br /><br />User input *(gbk:d6d0 cec4) browser *(gbk:d6d0 cec4) web server iso8859-1(00d6 00d 000ce 00c4) class，需要在class中进行处理：getbytes("iso8859-1")为d6 d0 ce c4，new String("gbk")为d6d0 cec4，内存中以unicode编码则为4e2d 6587。<br /><br />l 用户输入的编码方式和页面指定的编码有关，也和用户的操作系统有关，所以是不确定的，上例以gbk为例。<br /><br />l 从browser到web server，可以在表单中指定提交内容时使用的字符集，否则会使用页面指定的编码。而如果在url中直接用?的方式输入参数，则其编码往往是操作系统本身的编码，因为这时和页面无关。上述仍旧以gbk编码为例。<br /><br />l Web server接收到的是字节流，默认时（getParameter）会以iso8859-1编码处理之，结果是不正确的，所以需要进行处理。但如果预先设置了编码（通过request. setCharacterEncoding ()），则能够直接获取到正确的结果。<br /><br />l 在页面中指定编码是个好习惯，否则可能失去控制，无法指定正确的编码。<br /><br />3.4.2. 文件编译<br /><br />假设文件是gbk编码保存的，而编译有两种编码选择：gbk或者iso8859-1，前者是中文windows的默认编码，后者是linux的默认编码，当然也可以在编译时指定编码。<br /><br />Jsp *(gbk:d6d0 cec4) java file *(gbk:d6d0 cec4) compiler read uincode(gbk: 4e2d 6587; iso8859-1: 00d6 00d 000ce 00c4) compiler write utf(gbk: e4b8ad e69687; iso8859-1: *) compiled file unicode(gbk: 4e2d 6587; iso8859-1: 00d6 00d 000ce 00c4) class。所以用gbk编码保存，而用iso8859-1编译的结果是不正确的。<br /><br />class unicode(4e2d 6587) system.out / jsp.out gbk(d6d0 cec4) os console / browser。<br /><br />l 文件可以以多种编码方式保存，中文windows下，默认为ansi/gbk。<br /><br />l 编译器读取文件时，需要得到文件的编码，如果未指定，则使用系统默认编码。一般class文件，是以系统默认编码保存的，所以编译不会出问题，但对于jsp文件，如果在中文windows下编辑保存，而部署在英文linux下运行/编译，则会出现问题。所以需要在jsp文件中用pageEncoding指定编码。<br /><br />l Java编译的时候会转换成统一的unicode编码处理，最后保存的时候再转换为utf编码。<br /><br />l 当系统输出字符的时候，会按指定编码输出，对于中文windows下，System.out将使用gbk编码，而对于response（浏览器），则使用jsp文件头指定的contentType，或者可以直接为response指定编码。同时，会告诉browser网页的编码。如果未指定，则会使用iso8859-1编码。对于中文，应该为browser指定输出字符串的编码。<br /><br />l browser显示网页的时候，首先使用response中指定的编码（jsp文件头指定的contentType最终也反映在response上），如果未指定，则会使用网页中meta项指定中的contentType。<br /><br />3.5. 几处设置<br /><br />对于web应用程序，和编码有关的设置或者函数如下。<br /><br />3.5.1. jsp编译<br /><br />指定文件的存储编码，很明显，该设置应该置于文件的开头。例如：&lt;%@page pageEncoding="GBK"%&gt;。另外，对于一般class文件，可以在编译的时候指定编码。<br /><br />3.5.2. jsp输出<br /><br />指定文件输出到browser是使用的编码，该设置也应该置于文件的开头。例如：&lt;%@ page contentType="text/html; charset= GBK" %&gt;。该设置和response.setCharacterEncoding("GBK")等效。<br /><br />3.5.3. meta设置<br /><br />指定网页使用的编码，该设置对静态网页尤其有作用。因为静态网页无法采用jsp的设置，而且也无法执行response.setCharacterEncoding()。例如：<br /><br />如果同时采用了jsp输出和meta设置两种编码指定方式，则jsp指定的优先。因为jsp指定的直接体现在response中。<br /><br />需要注意的是，apache有一个设置可以给无编码指定的网页指定编码，该指定等同于jsp的编码指定方式，所以会覆盖静态网页中的meta指定。所以有人建议关闭该设置。<br /><br />3.5.4. form设置<br /><br />当浏览器提交表单的时候，可以指定相应的编码。例如： 
<form accept-charset="gb2312">。一般不必不使用该设置，浏览器会直接使用网页的编码。<br /><br />4. 系统软件<br /><br />下面讨论几个相关的系统软件。<br /><br />4.1. mysql数据库<br /><br />很明显，要支持多语言，应该将数据库的编码设置成utf或者unicode，而utf更适合与存储。但是，如果中文数据中包含的英文字母很少，其实unicode更为适合。<br /><br />数据库的编码可以通过mysql的配置文件设置，例如default-character-set=utf8。还可以在数据库链接URL中设置，例如： useUnicode=true&amp;characterEncoding=UTF-8。注意这两者应该保持一致，在新的sql版本里，在数据库链接URL里可以不进行设置，但也不能是错误的设置。<br /><br />4.2. apache<br /><br />appache和编码有关的配置在httpd.conf中，例如AddDefaultCharset UTF-8。如前所述，该功能会将所有静态页面的编码设置为UTF-8，最好关闭该功能。<br /><br />另外，apache还有单独的模块来处理网页响应头，其中也可能对编码进行设置。<br /><br />4.3. linux默认编码<br /><br />这里所说的linux默认编码，是指运行时的环境变量。两个重要的环境变量是LC_ALL和LANG，默认编码会影响到java URLEncode的行为，下面有描述。<br /><br />建议都设置为"zh_CN.UTF-8"。<br /><br />4.4. 其它<br /><br />为了支持中文文件名，linux在加载磁盘时应该指定字符集，例如：mount /dev/hda5 /mnt/hda5/ -t ntfs -o iocharset=gb2312。<br /><br />另外，如前所述，使用GET方法提交的信息不支持request.setCharacterEncoding()，但可以通过tomcat的配置文件指定字符集，在tomcat的server.xml文件中，形如：<connector ...="" uriencoding="GBK" />。这种方法将统一设置所有请求，而不能针对具体页面进行设置，也不一定和browser使用的编码相同，所以有时候并不是所期望的。<br /><br />5. URL地址<br /><br />URL地址中含有中文字符是很麻烦的，前面描述过使用GET方法提交表单的情况，使用GET方法时，参数就是包含在URL中。<br /><br />5.1. URL编码<br /><br />对于URL中的一些特殊字符，浏览器会自动进行编码。这些字符除了"/?&amp;"等外，还包括unicode字符，比如汉子。这时的编码比较特殊。<br /><br />IE有一个选项"总是使用UTF-8发送URL"，当该选项有效时，IE将会对特殊字符进行UTF-8编码，同时进行URL编码。如果改选项无效，则使用默认编码"GBK"，并且不进行URL编码。但是，对于URL后面的参数，则总是不进行编码，相当于UTF-8选项无效。比如"中文.html?a=中文"，当UTF-8选项有效时，将发送链接"%e4%b8%ad%e6%96%87.html?a=x4ex2dx65x87"；而UTF-8选项无效时，将发送链接"x4ex2dx65x87.html?a=x4ex2dx65x87"。注意后者前面的"中文"两个字只有4个字节，而前者却有18个字节，这主要时URL编码的原因。<br /><br />当web server（tomcat）接收到该链接时，将会进行URL解码，即去掉"%"，同时按照ISO8859-1编码（上面已经描述，可以使用URLEncoding来设置成其它编码）识别。上述例子的结果分别是"ue4ub8uadue6u96u87.html?a=u4eu2du65u87"和"u4eu2du65u87.html?a=u4eu2du65u87"，注意前者前面的"中文"两个字恢复成了6个字符。这里用"u"，表示是unicode。<br /><br />所以，由于客户端设置的不同，相同的链接，在服务器上得到了不同结果。这个问题不少人都遇到，却没有很好的解决办法。所以有的网站会建议用户尝试关闭UTF-8选项。不过，下面会描述一个更好的处理办法。<br /><br />5.2. rewrite<br /><br />熟悉的人都知道，apache有一个功能强大的rewrite模块，这里不描述其功能。需要说明的是该模块会自动将URL解码（去除%），即完成上述web server（tomcat）的部分功能。有相关文档介绍说可以使用[NE]参数来关闭该功能，但我试验并未成功，可能是因为版本（我使用的是apache 2.0.54）问题。另外，当参数中含有"?&amp; "等符号的时候，该功能将导致系统得不到正常结果。<br /><br />rewrite本身似乎完全是采用字节处理的方式，而不考虑字符串的编码，所以不会带来编码问题。<br /><br />5.3. URLEncode.encode()<br /><br />这是Java本身提供对的URL编码函数，完成的工作和上述UTF-8选项有效时浏览器所做的工作相似。值得说明的是，java已经不赞成不指定编码来使用该方法（deprecated）。应该在使用的时候增加编码指定。<br /><br />当不指定编码的时候，该方法使用系统默认编码，这会导致软件运行结果得不确定。比如对于"中文"，当系统默认编码为"gb2312"时，结果是"%4e%2d%65%87"，而默认编码为"UTF-8"，结果却是"%e4%b8%ad%e6%96%87"，后续程序将难以处理。另外，这儿说的系统默认编码是由运行tomcat时的环境变量LC_ALL和LANG等决定的，曾经出现过tomcat重启后就出现乱码的问题，最后才郁闷的发现是因为修改修改了这两个环境变量。<br /><br />建议统一指定为"UTF-8"编码，可能需要修改相应的程序。<br /><br />5.4. 一个解决方案<br /><br />上面说起过，因为浏览器设置的不同，对于同一个链接，web server收到的是不同内容，而软件系统有无法知道这中间的区别，所以这一协议目前还存在缺陷。<br /><br />针对具体问题，不应该侥幸认为所有客户的IE设置都是UTF-8有效的，也不应该粗暴的建议用户修改IE设置，要知道，用户不可能去记住每一个web server的设置。所以，接下来的解决办法就只能是让自己的程序多一点智能：根据内容来分析编码是否UTF-8。<br /><br />比较幸运的是UTF-8编码相当有规律，所以可以通过分析传输过来的链接内容，来判断是否是正确的UTF-8字符，如果是，则以UTF-8处理之，如果不是，则使用客户默认编码（比如"GBK"），下面是一个判断是否UTF-8的例子，如果你了解相应规律，就容易理解。<br /><br />public static boolean isValidUtf8(byte[] b,int aMaxCount){<br /><br />int lLen=b.length,lCharCount=0;<br /><br />for(int i=0;i<llen &&="" lcharcount<amaxcount;++lcharcount){<br="" /><br />byte lByte=b[i++];//to fast operation, ++ now, ready for the following for(;;)<br /><br />if(lByte&gt;=0) continue;//&gt;=0 is normal ascii<br /><br />if(lByte&lt;(byte)0xc0 || lByte&gt;(byte)0xfd) return false;<br /><br />int lCount=lByte&gt;(byte)0xfc?5:lByte&gt;(byte)0xf8?4<br /><br />:lByte&gt;(byte)0xf0?3:lByte&gt;(byte)0xe0?2:1;<br /><br />if(i+lCount&gt;lLen) return false;<br /><br />for(int j=0;j<lcount;++j,++i) if(b[i]="">=(byte)0xc0) return false;<br /><br />}<br /><br />return true;<br /><br />}<br /><br />相应地，一个使用上述方法的例子如下：<br /><br />public static String getUrlParam(String aStr,String aDefaultCharset)<br /><br />throws UnsupportedEncodingException{<br /><br />if(aStr==null) return null;<br /><br />byte[] lBytes=aStr.getBytes("ISO-8859-1");<br /><br />return new String(lBytes,StringUtil.isValidUtf8(lBytes)?"utf8":aDefaultCharset);<br /><br />}<br /><br />不过，该方法也存在缺陷，如下两方面：<br /><br />l 没有包括对用户默认编码的识别，这可以根据请求信息的语言来判断，但不一定正确，因为我们有时候也会输入一些韩文，或者其他文字。<br /><br />l 可能会错误判断UTF-8字符，一个例子是"学习"两个字，其GBK编码是" xd1xa7xcfxb0"，如果使用上述isValidUtf8方法判断，将返回true。可以考虑使用更严格的判断方法，不过估计效果不大。<br /><br />有一个例子可以证明google也遇到了上述问题，而且也采用了和上述相似的处理方法，比如，如果在地址栏中输入"http://www.google.com/search?hl=zh-CN&amp;newwindow=1&amp;q=学习"，google将无法正确识别，而其他汉字一般能够正常识别。<br /><br />最后，应该补充说明一下，如果不使用rewrite规则，或者通过表单提交数据，其实并不一定会遇到上述问题，因为这时可以在提交数据时指定希望的编码。另外，中文文件名确实会带来问题，应该谨慎使用。<br /><br />6. 其它<br /><br />下面描述一些和编码有关的其他问题。<br /><br />6.1. SecureCRT<br /><br />除了浏览器和控制台与编码有关外，一些客户端也很有关系。比如在使用SecureCRT连接linux时，应该让SecureCRT的显示编码（不同的session，可以有不同的编码设置）和linux的编码环境变量保持一致。否则看到的一些帮助信息，就可能是乱码。<br /><br />另外，mysql有自己的编码设置，也应该保持和SecureCRT的显示编码一致。否则通过SecureCRT执行sql语句的时候，可能无法处理中文字符，查询结果也会出现乱码。<br /><br />对于Utf-8文件，很多编辑器（比如记事本）会在文件开头增加三个不可见的标志字节，如果作为mysql的输入文件，则必须要去掉这三个字符。（用linux的vi保存可以去掉这三个字符）。一个有趣的现象是，在中文windows下，创建一个新txt文件，用记事本打开，输入"连通"两个字，保存，再打开，你会发现两个字没了，只留下一个小黑点。<br /><br />6.2. 过滤器<br /><br />如果需要统一设置编码，则通过filter进行设置是个不错的选择。在filter class中，可以统一为需要的请求或者回应设置编码。参加上述setCharacterEncoding()。这个类apache已经给出了可以直接使用的例子SetCharacterEncodingFilter。<br /><br />6.3. POST和GET<br /><br />很明显，以POST提交信息时，URL有更好的可读性，而且可以方便的使用setCharacterEncoding()来处理字符集问题。但GET方法形成的URL能够更容易表达网页的实际内容，也能够用于收藏。<br /><br />从统一的角度考虑问题，建议采用GET方法，这要求在程序中获得参数是进行特殊处理，而无法使用setCharacterEncoding()的便利，如果不考虑rewrite，就不存在IE的UTF-8问题，可以考虑通过设置URIEncoding来方便获取URL中的参数。<br /><br />6.4. 简繁体编码转换<br /><br />GBK同时包含简体和繁体编码，也就是说同一个字，由于编码不同，在GBK编码下属于两个字。有时候，为了正确取得完整的结果，应该将繁体和简体进行统一。可以考虑将UTF、GBK中的所有繁体字，转换为相应的简体字，BIG5编码的数据，也应该转化成相应的简体字。当然，仍旧以UTF编码存储。<br /><br />例如，对于"语言 語言"，用UTF表示为"xE8xAFxADxE8xA8x80 xE8xAAx9ExE8xA8x80"，进行简繁体编码转换后应该是两个相同的 "xE8xAFxADxE8xA8x80&gt;"。<br /><br /></lcount;++j,++i)></form></td>
								<td valign="top" width="14%">
										<div align="right">
												<font color="gray">    </font>
										</div>
										<script type="text/javascript">
												<!--
google_ad_client = "pub-1552958637257019";
google_ad_width = 160;
google_ad_height = 600;
google_ad_format = "160x600_as";
google_ad_channel ="";
google_ad_type = "text";
google_color_border = "A8DDA0";
google_color_bg = "EBFFED";
google_color_link = "0000CC";
google_color_url = "008000";
google_color_text = "6F6F6F";
//-->
										</script>
										<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript">
										</script>
										<iframe name="google_ads_frame" marginwidth="0" marginheight="0" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-1552958637257019&amp;dt=1167283070984&amp;lmt=1167283070&amp;format=160x600_as&amp;output=html&amp;url=http%3A%2F%2Fwww.cn-java.com%2Ftarget%2Fnews.php%3Fnews_id%3D3662&amp;color_bg=EBFFED&amp;color_text=6F6F6F&amp;color_link=0000CC&amp;color_url=008000&amp;color_border=A8DDA0&amp;ad_type=text&amp;cc=100&amp;u_h=1024&amp;u_w=1280&amp;u_ah=994&amp;u_aw=1280&amp;u_cd=32&amp;u_tz=480&amp;u_java=true" frameborder="0" width="160" scrolling="no" height="600" allowtransparency="">
										</iframe>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/90473.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2006-12-28 13:21 <a href="http://www.blogjava.net/wangxinsh55/archive/2006/12/28/90473.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Axis2体系结构中文手册</title><link>http://www.blogjava.net/wangxinsh55/archive/2006/12/22/89562.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Fri, 22 Dec 2006 09:42:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2006/12/22/89562.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/89562.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2006/12/22/89562.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/89562.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/89562.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 前言								结构都是它本身所能产生效率的结果。任何一个成功结构都是基于它期望的需求。我们通过期望用				Axis2				做什么来开始我们的				Axis2				之旅。								用										Axis2								做什么								在				SOAP				的术语里，一个				We...&nbsp;&nbsp;<a href='http://www.blogjava.net/wangxinsh55/archive/2006/12/22/89562.html'>阅读全文</a><img src ="http://www.blogjava.net/wangxinsh55/aggbug/89562.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2006-12-22 17:42 <a href="http://www.blogjava.net/wangxinsh55/archive/2006/12/22/89562.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AJAX+jsp无刷新验证码实例</title><link>http://www.blogjava.net/wangxinsh55/archive/2006/12/11/86907.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Mon, 11 Dec 2006 06:55:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2006/12/11/86907.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/86907.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2006/12/11/86907.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/86907.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/86907.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="shortmsg_td">
										<font color="#006600">【导读】本文通过实例，介绍在做验证码的时候为了给用户很好的体验，需要在原有验证方式基础之上增加一段js，通过xmlhttp来获取返回值，以此来验证是否有效。同时，本例还特别适合检验用户名是否有效。</font>
								</td>
						</tr>
				</tbody>
		</table>
		<div class="test_6">
				<!-- 画中画广告开始 -->
				<div class="floatright">
						<span id="hzhok">
						</span>
				</div>
				<!-- 画中画广告结束 -->
				<span class="top11">
						<p>
						</p>
						<p>1、我们在做验证码的时候往往由于要反作弊，验证有时故意加入多的干扰因素，这时验证码显示不很清楚，用户经常输入错误。这样不但要重新刷新页面，导致用户没有看清楚验证码而重填而不是修改，而且如果没有用session保存下用户输入的其它数据的话(如姓名)，用户刚刚输入的内容也不存在了，这样给用户造成不好的体验。 </p>
						<p>2、本例在原有验证方式基础之上增加一段js，通过xmlhttp来获取返回值，以此来验证是否有效，这样即使用户浏览器不支持js，也不会影响他的正常使用了。 </p>
						<p>3、为了防止作弊，当用户连接3次输入错误时则重载一下图片，这样也利于用户因为图片上的验证码辨认不清而使其终无法输入正确。 </p>
						<p>4、本例还特别适合检验用户名是否有效，只要从后台做个sql查询，返回一个值或是xml即可。(这种例子太多 ，就在此不赘述了)。 </p>
						<p>5、本例的优点在于非常方便用户输入，而且减少对服务器端的请求，可以说既改善用户体验而且略会节省带宽成本，但相应地要在页面上增加一段JavaScript代码，在目前网速越来越快人们要求便捷舒适的今天，似乎我们更应注意提供给用户良好的使用感受。 </p>
						<p>代码如下：</p>
						<p>
								<strong>1、img.jsp,输入主页面</strong>
						</p>
						<p>
						</p>
						<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1">
								<tbody>
										<tr>
												<td class="code" bgcolor="#e6e6e6">
														<pre>
																<p>&lt;%@ page contentType="text/html; charset=GBK" language="java" </p>
																<p>import="java.sql.*" errorPage="" pageEncoding="GBK"%&gt;<br /><br />&lt;%<br /><br />//set Chinese Char <br /><br />//Cody by <a href="mailto:JarryLi@gmail.com">JarryLi@gmail.com</a>;<br /><br />//homepage:jiarry.126.com<br /><br />request.setCharacterEncoding("GBK");<br /><br />response.setCharacterEncoding("GBK");<br /><br />response.setContentType("text/html; charset=GBK");<br /><br />%&gt;<br /><br />&lt;html&gt;<br /><br />&lt;head&gt;<br /><br />&lt;title&gt;图片验证&lt;/title&gt;<br /><br />&lt;meta http-equiv="Content-Type" content="text/html; charset=gb2312"&gt;<br /><br />&lt;script src="net.js"&gt;&lt;/script&gt;<br /><br />&lt;/head&gt;</p>
																<p>&lt;body&gt;<br /><br />AJAX(无刷新及时提示)验证码实例！cody by jarry<br /><br />&lt;hr&gt;<br /><br />&lt;%<br /><br />String num=request.getParameter("num");<br /><br />String random=(String)session.getAttribute("random");<br /><br />String name=request.getParameter("name");<br /><br />if(num!=null&amp;&amp;random!=null&amp;&amp;name!=null)<br /><br />{<br /><br />if(num.equals(random))<br /><br />{  <br /><br />out.println("&lt;font style=\"color:green;font-weight:bold\"&gt;</p>
																<p>恭喜您，验证码输入成功，这里是提交结果页面，可以写入数据库了！&lt;/font&gt; </p>
																<p>&lt;a href=\"img.jsp\"&gt;返回再测试&lt;/a&gt;&lt;br&gt;");<br /><br />out.println("您的名字是："+name);<br /><br />out.println("&lt;br&gt;");<br /><br />out.println("您输入的是："+num);<br /><br />out.println("验证码是："+random);<br /><br />out.println("&lt;/body&gt;");<br /><br />return;//javascript:history.go(-1)<br /><br />}<br /><br />}<br /><br />%&gt;<br /><br />&lt;script type="text/javascript"&gt;<br /><br />var times=0;<br /><br />function subform(){<br /><br />var gtext=this.req.responseText;<br /><br />var info=document.getElementById("info");<br /><br />if(gtext.indexOf("validate_successful")!=-1){<br /><br />//info.innerHTML="&lt;font color=green&gt;验证码通过&lt;/font&gt;";<br /><br />document.forms["myform"].submit();<br /><br />//当得到的值表示合法，则验证码通过。<br /><br />}else{<br /><br />times++;<br /><br />if(times&gt;=3){//如果连接3次输入错误，则重载图片，可以防止作弊和用户看不清图片;<br /><br />info.innerHTML="接连3次输入错误。更新验证码，请重新输入";<br /><br />document.forms["myform"].num.value="";<br /><br />show(document.getElementById('random'));<br /><br />times=0;<br /><br />}else{<br /><br />info.innerHTML="第"+times+"次验证码错误,请注意区分大小写 ";<br /><br />}<br /><br />document.forms["myform"].num.select();<br /><br />}</p>
																<p>}<br /><br />function validata(obj){<br /><br />var enter=true;<br /><br />var info=document.getElementById("info");<br /><br />var msg="";<br /><br />if(obj.name.value.match(/^\s*$/g)){//如果未输入名字，提示<br /><br />msg+="请输入您的姓名&lt;br&gt;";enter=false<br /><br />}<br /><br />if(obj.num.value.match(/^\s*$/g)){//如果未输入验证码，提示<br /><br />msg+="请输入验证码&lt;br&gt;";enter=false  <br /><br />}<br /><br />if(enter==false){<br /><br />info.innerHTML=msg;<br /><br />return false;<br /><br />}<br /><br />var url="num.jsp?num="+obj.num.value;<br /><br />var newxmlhttp=new net.ContentLoader(url,subform,"","get",null,null); <br /><br />return false;<br /><br />}<br /><br />function show(o){<br /><br />//重载验证码<br /><br />var timenow = new Date().getTime();<br /><br />o.src="random.jsp?d="+timenow;<br /><br />/*<br /><br />//超时执行;<br /><br />setTimeout(function(){<br /><br />o.src="random.jsp?d="+timenow;<br /><br />}<br /><br />,20);<br /><br />*/<br /><br />}<br /><br />&lt;/script&gt;<br /><br />&lt;form action="img.jsp" name="myform" method="post"</p>
																<p>onsubmit="return validata(this);"&gt;<br /><br />您的姓名：&lt;input type="text" name="name" size=10&gt; (为了更好地说明此例，特加姓名一项)&lt;br&gt;<br /><br />验 证 码：&lt;input type="text" name="num" size=10 maxlength="4"&gt; </p>
																<p>&lt;img src="random.jsp" id="random" align="" valign="absmiddle" hspace="5"&gt; </p>
																<p>&lt;a href="javascript:show(document.getElementById('random'))"&gt;验证码看不清&lt;/a&gt;&lt;br&gt;<br /><br />&lt;br&gt; &lt;input type="submit" value=" 提交 "&gt;&lt;br&gt;<br /><br />&lt;div id=info style="color:red;padding:10px;font-size:12px;"&gt;&lt;/div&gt;<br /><br />&lt;/form&gt;<br /><br />&lt;/body&gt;<br /><br />&lt;/html&gt;</p>
														</pre>
												</td>
										</tr>
								</tbody>
						</table>
						<p>
								<strong>2、num.jsp,反馈xmlhttp请求的页面</strong>
						</p>
						<p>
						</p>
						<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1">
								<tbody>
										<tr>
												<td class="code" bgcolor="#e6e6e6">
														<pre>
																<p>&lt;%@ page contentType="text/html; charset=GBK" language="java" </p>
																<p>import="java.sql.*" errorPage="" pageEncoding="GBK"%&gt;<br /><br />&lt;%<br /><br />//set Chinese Char <br /><br />//Cody by <a href="mailto:JarryLi@gmail.com">JarryLi@gmail.com</a>;<br /><br />//homepage:jiarry.126.com<br /><br />request.setCharacterEncoding("GBK");<br /><br />response.setCharacterEncoding("GBK");<br /><br />response.setContentType("text/html; charset=GBK");<br /><br />%&gt;<br /><br />&lt;%<br /><br />String num=request.getParameter("num");<br /><br />String random=(String)session.getAttribute("random");</p>
																<p>if(num!=null&amp;&amp;random!=null)<br /><br />{<br /><br />if(!num.equals(random))<br /><br />{<br /><br />/*<br /><br />out.println("&lt;script&gt;alert('验证码错误！请重试。')&lt;/script&gt;");<br /><br />out.println("&lt;script&gt;history.go(-1)&lt;/script&gt;");<br /><br />//response.sendRedirect("img.jsp");<br /><br />*/<br /><br />out.print("validate_failed:"+random);<br /><br />}<br /><br />else<br /><br />{<br /><br />//out.println("&lt;center&gt;验证成功！&lt;/center&gt;");<br /><br />out.print("validate_successful:"+random);<br /><br />}<br /><br />}<br /><br />%&gt;</p>
														</pre>
												</td>
										</tr>
								</tbody>
						</table>
						<p>
								<strong>3、random.jsp,生成验证码图片的页面</strong>
						</p>
						<p>
						</p>
						<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1">
								<tbody>
										<tr>
												<td class="code" bgcolor="#e6e6e6">
														<pre>
																<p><![CDATA[<%@ page autoFlush="false"&nbsp; import="java.util.*,java.awt.*,java.awt.image.*,</p><p>com.sun.image.codec.jpeg.*,java.util.*" %>]]&gt;</p>
																<p>&lt;%@ page autoFlush="false"  import="java.util.*,java.awt.*,</p>
																<p>java.awt.image.*,com.sun.image.codec.jpeg.*,java.util.*" %&gt;</p>
																<p>&lt;%<br /><br />//set Chinese Char <br /><br />//Cody by <a href="mailto:JarryLi@gmail.com">JarryLi@gmail.com</a>;<br /><br />//homepage:jiarry.126.com<br /><br />request.setCharacterEncoding("GBK");<br /><br />response.setCharacterEncoding("GBK");<br /><br />response.setContentType("text/html; charset=GBK");<br /><br />%&gt;<br /><br />&lt;%<br /><br />String chose="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";</p>
																<p>char display[]={'0',' ','0',' ','0',' ','0'},ran[]={'0','0','0','0'},temp;</p>
																<p>Random rand=new Random();</p>
																<p>for(int i=0;i&lt;4;i++)<br /><br />{</p>
																<p>temp=chose.charAt(rand.nextInt(chose.length()));</p>
																<p>display[i*2]=temp;</p>
																<p>ran[i]=temp;<br /><br />}<br /><br /><br /><br />String random=String.valueOf(display);</p>
																<p>session.setAttribute("random",String.valueOf(ran));<br /><br />%&gt;<br /><br />&lt;%</p>
																<p>out.clear();<br /><br />response.setContentType("image/jpeg");<br /><br />response.addHeader("pragma","NO-cache");<br /><br />response.addHeader("Cache-Control","no-cache");<br /><br />response.addDateHeader("Expries",0);<br /><br />int width=80, height=30;<br /><br />BufferedImage image = new BufferedImage(width, height, </p>
																<p>BufferedImage.TYPE_INT_RGB);<br /><br />Graphics g = image.getGraphics();<br /><br />//以下填充背景颜色<br /><br />g.setColor(Color.GREEN);<br /><br />g.fillRect(0, 0, width, height);<br /><br />//设置字体颜色<br /><br />g.setColor(Color.RED);<br /><br />Font font=new Font("Arial",Font.PLAIN,20);<br /><br />g.setFont(font);<br /><br />//g.drawString(random,5,14);<br /><br />g.drawString(random,5,20);<br /><br />g.dispose();<br /><br />ServletOutputStream outStream = response.getOutputStream();<br /><br />JPEGImageEncoder encoder =JPEGCodec.createJPEGEncoder(outStream);<br /><br />encoder.encode(image);<br /><br />outStream.close();<br /><br />%&gt;</p>
														</pre>
												</td>
										</tr>
								</tbody>
						</table>
						<br />
						<br />
						<strong>4、net.js,封装好的xmlhttp对象，可以很方便的调用</strong>
						<p>
						</p>
						<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1">
								<tbody>
										<tr>
												<td class="code" bgcolor="#e6e6e6">
														<pre>
																<p>/* namespacing object */<br /><br />var net=new Object();<br /><br /><br /><br />net.READY_STATE_UNINITIALIZED=0;<br /><br />net.READY_STATE_LOADING=1;<br /><br />net.READY_STATE_LOADED=2;<br /><br />net.READY_STATE_INTERACTIVE=3;<br /><br />net.READY_STATE_COMPLETE=4;<br /><br />/*--- content loader object for cross-browser requests ---*/<br /><br />net.ContentLoader=function(url,on_load,on_error,method,params,contentType){<br /><br />this.req=null;<br /><br />this.on_load=on_load;<br /><br />this.on_error=(on_error) ? on_error : this.defaultError;<br /><br />this.loadXMLDoc(url,method,params,contentType);<br /><br />}<br /><br />net.ContentLoader.prototype.loadXMLDoc=function(url,method,params,contentType){<br /><br />if (!method)<br /><br />{<br /><br />method="GET";<br /><br />}<br /><br />if (!contentType &amp;&amp; method=="POST")<br /><br />{<br /><br />contentType='application/x-www-form-urlencoded';<br /><br />}<br /><br />if (window.XMLHttpRequest)<br /><br />{<br /><br />this.req=new XMLHttpRequest();<br /><br />}<br /><br />else if (window.ActiveXObject)<br /><br />{<br /><br />//add try catch;<br /><br />try {<br /><br />this.req = new ActiveXObject("Msxml2.XMLHTTP");<br /><br />}catch (e1){<br /><br />try {<br /><br />this.req = new ActiveXObject("Microsoft.XMLHTTP");     <br /><br />} catch (e2){<br /><br />}<br /><br />}<br /><br />//<br /><br />//this.req=new ActiveXObject("Microsoft.XMLHTTP");<br /><br />}<br /><br />if (this.req)<br /><br />{<br /><br />try<br /><br />{<br /><br />var loader=this;<br /><br />this.req.onreadystatechange=function()<br /><br />{<br /><br />net.ContentLoader.onReadyState.call(loader);<br /><br />}<br /><br />this.req.open(method,url,true);<br /><br />if (contentType)<br /><br />{<br /><br />this.req.setRequestHeader('Content-Type', contentType);<br /><br />}<br /><br />this.req.send(params);<br /><br />}<br /><br />catch (err)<br /><br />{<br /><br />this.on_error.call(this);<br /><br />}<br /><br />}<br /><br />}<br /><br />net.ContentLoader.onReadyState=function(){<br /><br />var req=this.req;<br /><br />var ready=req.readyState;<br /><br />if (ready==net.READY_STATE_COMPLETE){<br /><br />var httpStatus=req.status;<br /><br />if (httpStatus==200 || httpStatus==0){<br /><br />this.on_load.call(this);<br /><br />}else{<br /><br />this.on_error.call(this);<br /><br />}<br /><br />}<br /><br />}<br /><br />net.ContentLoader.prototype.defaultError=function(){<br /><br />alert("error fetching data!"<br /><br />+"\n\nreadyState:"+this.req.readyState<br /><br />+"\nstatus: "+this.req.status<br /><br />+"\nheaders: "+this.req.getAllResponseHeaders());<br /><br />}</p>
														</pre>
												</td>
										</tr>
								</tbody>
						</table>
						<p align="right">（责任编辑 火凤凰 <a href="mailto:sunsj@51cto.com">sunsj@51cto.com</a>  TEL：（010）68476636-8007）<br /><br /></p>
						<br />
						<br />
				</span>
		</div>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/86907.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2006-12-11 14:55 <a href="http://www.blogjava.net/wangxinsh55/archive/2006/12/11/86907.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java 根据日期取得星期</title><link>http://www.blogjava.net/wangxinsh55/archive/2006/12/08/86303.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Fri, 08 Dec 2006 05:25:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2006/12/08/86303.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/86303.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2006/12/08/86303.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/86303.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/86303.html</trackback:ping><description><![CDATA[方法一、<br /> public static String getFullDateWeekTime(String sDate){<br />   try{<br />    String formater = "yyyy-MM-dd HH:mm:ss";<br />    SimpleDateFormat format = new SimpleDateFormat(formater);<br />    Date date=format.parse(sDate);<br />    format.applyPattern("yyyy-MM-dd E HH:mm:ss");<br />    return format.format(date);<br />   }catch(Exception ex){<br />    System.out.println("TimeUtil  getFullDateWeekTime"+ex.getMessage());<br />    return "";<br />   }<br />  }<br /><br /><br /><br />方法二、<br /><p>import java.text.ParseException;<br />import java.text.SimpleDateFormat;<br />import java.util.Calendar;<br />import java.util.Date;</p><p>public class Test {<br /> public static void main(String[] args) {<br />  final String dayNames[] = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五",<br />    "星期六" };</p><p>  String s = "2006-01-12 16:30";<br />  SimpleDateFormat sdfInput = new SimpleDateFormat("yyyy-MM-dd HH:mm");</p><p>  Calendar calendar = Calendar.getInstance();<br />  Date date = new Date();</p><p>  try {<br />   date = sdfInput.parse(s);<br />  } catch (ParseException e) {<br />   e.printStackTrace();<br />  }</p><p>  calendar.setTime(date);<br />  int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK)-1;<br />  if(dayOfWeek&lt;0)dayOfWeek=0;<br /> System.out.println(dayNames[dayOfWeek]);<br /> }<br />}<br /></p><img src ="http://www.blogjava.net/wangxinsh55/aggbug/86303.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2006-12-08 13:25 <a href="http://www.blogjava.net/wangxinsh55/archive/2006/12/08/86303.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网页右键菜单（二）</title><link>http://www.blogjava.net/wangxinsh55/archive/2006/09/26/72069.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Tue, 26 Sep 2006 09:22:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2006/09/26/72069.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/72069.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2006/09/26/72069.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/72069.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/72069.html</trackback:ping><description><![CDATA[
		<p> &lt;HTML&gt;&lt;HEAD&gt;&lt;TITLE&gt;右键菜单的淡入淡出效果&lt;/TITLE&gt;<br />&lt;META content="text/html; charset=gb2312" http-equiv=Content-Type&gt;<br />&lt;SCRIPT language=javascript&gt;<br />&lt;!-- // RightClickMenu<br />var intDelay=10; //设置菜单显示速度，越大越慢<br />var intInterval=5; //每次更改的透明度<br />function showmenuie5(){<br />        var rightedge=document.body.clientWidth-event.clientX<br />        var bottomedge=document.body.clientHeight-event.clientY<br />        if (rightedge&lt;ie5menu.offsetWidth)<br />            ie5menu.style.left=document.body.scrollLeft+event.clientX-ie5menu.offsetWidth<br />        else<br />            ie5menu.style.left=document.body.scrollLeft+event.clientX<br />        if (bottomedge&lt;ie5menu.offsetHeight)<br />            ie5menu.style.top=document.body.scrollTop+event.clientY-ie5menu.offsetHeight<br />        else<br />            ie5menu.style.top=document.body.scrollTop+event.clientY<br />        ie5menu.style.visibility="visible"<br />        //ie5menu.style.visibility=""<br />        ie5menu.filters.alpha.opacity=0<br />        GradientShow()<br />        return false<br />}<br />function hidemenuie5(){<br />        //ie5menu.style.visibility="hidden"<br />        GradientClose()<br />}<br />function highlightie5(){<br />        if (event.srcElement.className=="menuitems"){<br />            event.srcElement.style.backgroundColor="highlight"<br />            event.srcElement.style.color="white"<br />        }<br />}<br />function lowlightie5(){<br />        if (event.srcElement.className=="menuitems"){<br />            event.srcElement.style.backgroundColor=""<br />            event.srcElement.style.color="#000000"<br />        }<br />} <br />function jumptoie5(){<br />        if (event.srcElement.className=="menuitems"){<br />            if (event.srcElement.url != ''){<br />                if (event.srcElement.getAttribute("target")!=null)<br />                    window.open(event.srcElement.url,event.srcElement.getAttribute("target"))<br />                else<br />                    window.location=event.srcElement.url<br />            }<br />        }<br />}</p>
		<p>function GradientShow() //实现淡入的函数 <br />{ <br />    ie5menu.filters.alpha.opacity+=intInterval <br />    if (ie5menu.filters.alpha.opacity&lt;100) setTimeout("GradientShow()",intDelay)<br />} <br />    <br />function GradientClose() //实现淡出的函数 <br />    { <br />    ie5menu.filters.alpha.opacity-=intInterval <br />    if (ie5menu.filters.alpha.opacity&gt;0) { <br />     setTimeout("GradientClose()",intDelay) <br />     } <br />    else { <br />     ie5menu.style.visibility="hidden"<br />     } <br />} </p>
		<p>function ChangeBG() //改变菜单项的背景颜色，这里的两种颜色值可以改为你需要的 <br />{ <br />    oEl=event.srcElement <br />    if (oEl.style.background!="navy") { <br />        oEl.style.background="navy" <br />    } <br />    else { <br />        oEl.style.background="#cccccc" <br />    } <br />} <br />// --&gt;<br />&lt;/SCRIPT&gt;</p>
		<p>&lt;STYLE type=text/CSS&gt;<br />.cMenu {<br />    FILTER: alpha(opacity=0);BACKGROUND-COLOR: #D6D3CE;BORDER-BOTTOM: #666666 2px solid; BORDER-LEFT: #E4E4E4 2px solid; BORDER-RIGHT: #666666 2px solid; BORDER-TOP: #E4E4E4 2px solid; COLOR: #000000; CURSOR: default; FONT-SIZE: 9pt; color:#000000;FONT-WEIGHT: normal; LINE-HEIGHT: 20px; POSITION: absolute; VISIBILITY: hidden; WIDTH: 110px<br />}<br />.menuitems {<br />    font-size:9pt;<br />    MARGIN: 2px;<br />    PADDING-BOTTOM: 0px;<br />PADDING-LEFT: 15px;<br />PADDING-RIGHT: 3px;<br />PADDING-TOP: 0px;<br />}<br />&lt;/STYLE&gt;</p>
		<p>&lt;META content="Microsoft FrontPage 4.0" name=GENERATOR&gt;<br />&lt;/HEAD&gt;<br />&lt;BODY&gt;<br />&lt;OBJECT classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2 height=0 id=WebBrowser width=0&gt;<br />&lt;/OBJECT&gt;<br />&lt;RIGHTCLICK&gt;&lt;!--[if IE]&gt;<br />&lt;DIV class=cMenu id=ie5menu onclick=jumptoie5() onmouseout=lowlightie5() <br />onmouseover=highlightie5()&gt;</p>
		<p>&lt;DIV class=menuitems url="javascript:click_obj(0)"&gt;后退&lt;/DIV&gt;<br />&lt;DIV class=menuitems url="javascript:click_obj(1)"&gt;前进&lt;/DIV&gt;<br />&lt;DIV class=menuhr&gt;&lt;hr style="width:100%"&gt;&lt;/DIV&gt;<br />&lt;DIV class=menuitems url="javascript:click_obj(2)"&gt;刷新&lt;/DIV&gt;<br />&lt;DIV class=menuitems url="javascript:click_obj(3)"&gt;加入收藏夹&lt;/DIV&gt;<br />&lt;DIV class=menuitems url="javascript:click_obj(4)"&gt;查看源文件&lt;/DIV&gt;<br />&lt;DIV class=menuhr&gt;&lt;hr style="width:100%"&gt;&lt;/DIV&gt;<br />&lt;DIV class=menuitems url="javascript:click_obj(5)"&gt;属性&lt;/DIV&gt;</p>
		<p>&lt;/DIV&gt;<br />&lt;![endif]--&gt;</p>
		<p>&lt;SCRIPT language=JavaScript&gt;<br />&lt;!--<br />function click_obj(id){<br />    switch(id){<br />        case 0:    <br />            history.back()<br />            break<br />        case 1:<br />            history.forward()<br />            break<br />        case 2:<br />            window.location.reload()<br />            break<br />        case 3:<br />            window.external.AddFavorite(location.href, document.title)<br />            break<br />        case 4:<br />            window.location = "view-source:" + window.location.href<br />            break<br />        case 5:<br />            document.all.WebBrowser.ExecWB(10,1)<br />            break<br />    }<br />}</p>
		<p>if (document.all&amp;&amp;window.print){<br />    ie5menu.className="cMenu"<br />    document.oncontextmenu=showmenuie5<br />    document.body.onclick=hidemenuie5<br />}<br />//--&gt;<br />&lt;/SCRIPT&gt;<br />&lt;/RIGHTCLICK&gt;<br />&lt;/BODY&gt;&lt;/HTML&gt;</p>
		<p>
				<br /> </p>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/72069.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2006-09-26 17:22 <a href="http://www.blogjava.net/wangxinsh55/archive/2006/09/26/72069.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>