﻿<?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-xyz's blog-文章分类-网络文摘</title><link>http://www.blogjava.net/xyzroundo/category/28133.html</link><description>执着......坚持......</description><language>zh-cn</language><lastBuildDate>Wed, 14 May 2008 06:26:43 GMT</lastBuildDate><pubDate>Wed, 14 May 2008 06:26:43 GMT</pubDate><ttl>60</ttl><item><title>轻松实现Apache,Tomcat集群和负载均衡</title><link>http://www.blogjava.net/xyzroundo/articles/200282.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Tue, 13 May 2008 11:29:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/200282.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/200282.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/200282.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/200282.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/200282.html</trackback:ping><description><![CDATA[<p>来源：http://hi.baidu.com/luodaijun/blog/item/5bbe4cfb5ffef864034f56a1.html</p>
<p>&nbsp;</p>
作者:罗代均 ldj_work#126.com,转载请保持完整性
<p><strong>0， 环境说明</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Apache&nbsp; :apache_2.0.55&nbsp;&nbsp;&nbsp;&nbsp; 1 个</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tomcat:&nbsp; apache-tomcat-5.5.17 (zip版) 2个</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mod_jk:: mod_jk-apache-2.0.55.so&nbsp; 1个</p>
<p><strong>第一部分：负载均衡</strong></p>
<p>&nbsp;&nbsp;&nbsp; 负载均衡，就是apache将客户请求均衡的分给tomcat1,tomcat2....去处理</p>
<p><strong>&nbsp;&nbsp; 1.安装apche,tomcat</strong></p>
<p>&nbsp;&nbsp; <a href="http://httpd.apache.org/">http://httpd.apache.org/</a>&nbsp;下载Apache 2.0.55</p>
<p>&nbsp;&nbsp;&nbsp; <a href="http://tomcat.apache.org/download-55.cgi">http://tomcat.apache.org/download-55.cgi</a>&nbsp;下载tomcat5.5 zip版本（解压即可，绿色版）</p>
<p>&nbsp;&nbsp; <a href="http://apache.justdn.org/tomcat/tomcat-connectors/jk/binaries/win32/jk-1.2.15/">http://apache.justdn.org/tomcat/tomcat-connectors/jk/binaries/win32/jk-1.2.15/</a>&nbsp; 下载mod_jk,注意和&nbsp; apache版本匹配</p>
<p>&nbsp;&nbsp; 按照jdk,我的路径为:E:\ide\apache\Apache2</p>
<p>&nbsp;&nbsp; 解压两份Tomcat, 路径分别为 E:\ide\tomcat1,E:\ide\tomcat2</p>
<div forimg="1"><img class="blogimg" src="http://hiphotos.baidu.com/luodaijun/pic/item/9d61f003d5034eec09fa935b.jpg" border="0" small="0"  alt="" /></div>
<p>下载mod_jk</p>
<div forimg="1"><img class="blogimg" src="http://hiphotos.baidu.com/luodaijun/pic/item/52855e82373a3ea20df4d224.jpg" border="0" small="0"  alt="" /></div>
<div forimg="1"><img class="blogimg" src="http://hiphotos.baidu.com/luodaijun/pic/item/46899c50d44e3b628435245b.jpg" border="0" small="0"  alt="" /></div>
<div forimg="1"></div>
<div forimg="1"></div>
<p><strong>2.修改Apache配置文件http.conf</strong></p>
<p>&nbsp;&nbsp; 在apache安装目录下conf目录中找到http.conf</p>
<p>&nbsp;&nbsp; 在文件最后加上下面一句话就可以了</p>
<p>&nbsp; include "E:\ide\apache\Apache2\conf\mod_jk.conf"</p>
<div forimg="1"><img class="blogimg" src="http://hiphotos.baidu.com/luodaijun/pic/item/d1c28cd49b8d6901a08bb720.jpg" border="0" small="0"  alt="" /></div>
<div forimg="1"></div>
<div forimg="1"></div>
<div forimg="1"><strong>2. http.conf 同目录下新建mod_jk.conf文件，内容如下</strong></div>
<div forimg="1">&nbsp;&nbsp; </div>
<div forimg="1">#加载mod_jk Module<br />
LoadModule jk_module modules/mod_jk-apache-2.0.55.so</div>
<div forimg="1"></div>
<div forimg="1">#指定 workers.properties文件路径<br />
JkWorkersFile conf/workers.properties</div>
<div forimg="1"></div>
<div forimg="1">#指定那些请求交给tomcat处理,"controller"为在workers.propertise里指定的负载分配控制器</div>
<div forimg="1">JkMount /*.jsp controller</div>
<div forimg="1"></div>
<div forimg="1"></div>
<div forimg="1"></div>
<div forimg="1"><strong>3.在http.conf同目录下新建 workers.properties文件，内容如下</strong></div>
<div forimg="1">&nbsp;</div>
<div forimg="1">worker.list = controller,tomcat1,tomcat2&nbsp; #server 列表</div>
<div forimg="1"></div>
<div forimg="1">#========tomcat1========</div>
<div forimg="1">worker.tomcat1.port=8009&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #ajp13 端口号，在tomcat下server.xml配置,默认8009<br />
worker.tomcat1.host=localhost&nbsp; #tomcat的主机地址，如不为本机，请填写ip地址<br />
worker.tomcat1.type=ajp13<br />
worker.tomcat1.lbfactor = 1&nbsp;&nbsp; #server的加权比重，值越高，分得的请求越多</div>
<div forimg="1"></div>
<div forimg="1">#========tomcat2========</div>
<div forimg="1">worker.tomcat2.port=9009&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #ajp13 端口号，在tomcat下server.xml配置,默认8009<br />
worker.tomcat2.host=localhost&nbsp; #tomcat的主机地址，如不为本机，请填写ip地址<br />
worker.tomcat2.type=ajp13<br />
worker.tomcat2.lbfactor = 1&nbsp;&nbsp; #server的加权比重，值越高，分得的请求越多</div>
<div forimg="1"><br />
#========controller,负载均衡控制器========<br />
worker.controller.type=lb<br />
worker.controller.balanced_workers=tomcat1,tomcat2&nbsp;&nbsp; #指定分担请求的tomcat<br />
worker.controller.sticky_session=1</div>
<div forimg="1"></div>
<div forimg="1"></div>
<div forimg="1"></div>
<div forimg="1"><strong>4.修改tomcat配置文件server.xml</strong></div>
<div forimg="1">如果你在不同电脑上安装tomcat,tomcat的安装数量为一个，可以不必修改tomcat配置文件</div>
<div forimg="1">我这里是在同一台电脑上安装两个tomcat，所以需要更改其中一个的设置</div>
<div forimg="1"></div>
<div forimg="1">打开tomcat2/conf/server.xml文件</div>
<div forimg="1">
<div forimg="1"><img class="blogimg" src="http://hiphotos.baidu.com/luodaijun/pic/item/a3d133a8ed4063b1ca130c36.jpg" border="0" small="0"  alt="" />
<div forimg="1"><img class="blogimg" src="http://hiphotos.baidu.com/luodaijun/pic/item/8c3cae7727b25d1bb151b937.jpg" border="0" small="0"  alt="" /></div>
<div forimg="1">
<div forimg="1"><img class="blogimg" src="http://hiphotos.baidu.com/luodaijun/pic/item/56b04b085ba7f3950b7b8230.jpg" border="0" small="0"  alt="" /></div>
<div forimg="1"></div>
<div forimg="1"></div>
<div forimg="1"></div>
<div forimg="1"><strong>5.编写一个测试jsp</strong></div>
<div forimg="1"></div>
<div forimg="1">建立一个目录test.里面新建一个test.jsp,内容为</div>
<div forimg="1"></div>
<div forimg="1">&lt;% <br />
&nbsp;&nbsp; System.out.println("===========================");<br />
%&gt;<br />
</div>
<div forimg="1">把test放到tomcat1,tomcat2的webapps下</div>
<div forimg="1"></div>
<div forimg="1"></div>
<div forimg="1"></div>
<div forimg="1"><strong>6.启动apache,tomcat1,tomcat2,进行测试</strong></div>
<div forimg="1"></div>
<div forimg="1">通过 <a href="http://localhost/test/test.jsp">http://localhost/test/test.jsp</a>&nbsp;访问，查看tomcat1的窗口，可以看到打印了一行"=========="</div>
<div forimg="1">再刷新一次，tomcat2也打印了一条，再刷新，可以看到请求会被tomcat1,tomcat2轮流处理,实现了负载均衡</div>
<div forimg="1">
<div forimg="1"><img class="blogimg" src="http://hiphotos.baidu.com/luodaijun/pic/item/acf2fcf2c8b77d13b17ec53d.jpg" border="0" small="0"  alt="" /></div>
<div forimg="1"></div>
<div forimg="1"></div>
<div forimg="1"><strong>第二部分，配置集群</strong></div>
<div forimg="1">&nbsp;&nbsp; 只配置负载均衡还不行，还要session复制，也就是说其中任何一个tomcat的添加的session，是要同步复制到其它tomcat， 集群内的tomcat都有相同的session</div>
<div forimg="1"></div>
<div forimg="1"><strong>1. 修改tomcat1, tomcat2的server.xml</strong>,将集群部分配置的在注释符删掉,并将tomcat2的4001端口改为4002，以避免与tomcat冲突，当然，如果是两台电脑，是不用改端口的，去掉注释符即可</div>
<div forimg="1">&nbsp;&nbsp;
<div forimg="1"><img class="blogimg" src="http://hiphotos.baidu.com/luodaijun/pic/item/aa4ab5fb0f3582224f4aeab2.jpg" border="0" small="0"  alt="" /></div>
<div forimg="1">
<div forimg="1">
<div forimg="1"><img class="blogimg" src="http://hiphotos.baidu.com/luodaijun/pic/item/89b84c3627ecc1dda3cc2b92.jpg" border="0" small="0"  alt="" /></div>
</div>
<div forimg="1">
<div forimg="1"><img class="blogimg" src="http://hiphotos.baidu.com/luodaijun/pic/item/cc4b858b603d47d3fd1f10b2.jpg" border="0" small="0"  alt="" /></div>
<div forimg="1"></div>
<div forimg="1"></div>
<div forimg="1"><strong>
<div forimg="1"><img class="blogimg" src="http://hiphotos.baidu.com/luodaijun/pic/item/52dfdac4bc506ecb38db4959.jpg" border="0" small="0"  alt="" /></div>
</strong></div>
<div forimg="1"><strong></strong></div>
<div forimg="1"><strong>2，修改测试项目test</strong></div>
<div forimg="1">修改test.jsp,内容如下</div>
<div forimg="1"></div>
<div forimg="1">&nbsp; &lt;%@ page contentType="text/html; charset=GBK" %&gt;<br />
&lt;%@ page import="java.util.*" %&gt;<br />
&lt;html&gt;&lt;head&gt;&lt;title&gt;Cluster App Test&lt;/title&gt;&lt;/head&gt;<br />
&lt;body&gt;<br />
Server Info:<br />
&lt;%<br />
out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"&lt;br&gt;");%&gt;<br />
&lt;%<br />
&nbsp; out.println("&lt;br&gt; ID " + session.getId()+"&lt;br&gt;");</div>
<div forimg="1">&nbsp; // 如果有新的 Session 属性设置<br />
&nbsp; String dataName = request.getParameter("dataName");<br />
&nbsp; if (dataName != null &amp;&amp; dataName.length() &gt; 0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp; String dataValue = request.getParameter("dataValue");<br />
&nbsp;&nbsp;&nbsp;&nbsp; session.setAttribute(dataName, dataValue);<br />
&nbsp; }</div>
<div forimg="1">&nbsp; out.print("&lt;b&gt;Session 列表&lt;/b&gt;");</div>
<div forimg="1">&nbsp; Enumeration e = session.getAttributeNames();<br />
&nbsp; while (e.hasMoreElements()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp; String name = (String)e.nextElement();<br />
&nbsp;&nbsp;&nbsp;&nbsp; String value = session.getAttribute(name).toString();<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println( name + " = " + value+"&lt;br&gt;");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println( name + " = " + value);<br />
&nbsp;&nbsp; }<br />
%&gt;<br />
&nbsp; &lt;form action="index.jsp" method="POST"&gt;<br />
&nbsp;&nbsp;&nbsp; 名称:&lt;input type=text size=20 name="dataName"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;br&gt;<br />
&nbsp;&nbsp;&nbsp; 值:&lt;input type=text size=20 name="dataValue"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;br&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;input type=submit&gt;<br />
&nbsp;&nbsp; &lt;/form&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</div>
<div forimg="1"></div>
<div forimg="1">然后在test 新建WEB-INF目录，WEB-INF下新建web.xml,内容如下</div>
<div forimg="1">&lt;web-app xmlns="<a href="http://java.sun.com/xml/ns/j2ee">http://java.sun.com/xml/ns/j2ee</a>" xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>" xsi:schemaLocation="<a href="http://java.sun.com/xml/ns/j2ee">http://java.sun.com/xml/ns/j2ee</a> <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>" version="2.4"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;display-name&gt;TomcatDemo&lt;/display-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#ff0000"> &lt;distributable/&gt;</font></strong><br />
&lt;/web-app&gt;</div>
<div forimg="1"></div>
<div forimg="1">注意：在你的应用的web.xml加入&nbsp;<font color="#ff0000"><strong> &lt;distributable/&gt;</strong> </font><font color="#000000">即可</font></div>
<div forimg="1"></div>
<div forimg="1">ok,讲test复制到tomcat1,tomcat2的webapps下，重启apache,tomcat1,tomcat2,</div>
<div forimg="1">输入网址 <a href="http://localhost/test/test.jsp">http://localhost/test/test.jsp</a>&nbsp;&nbsp; </div>
<div forimg="1"></div>
<div forimg="1">新建一个 名称为 xiaoluo&nbsp; ,值为 cdut 的session,提交查询，新开一个ie窗口，再提交查询，如图，可以看到，两个tomcat 是负载均衡，并且session同步的</div>
<div forimg="1">
<div forimg="1"><img class="blogimg" src="http://hiphotos.baidu.com/luodaijun/pic/item/79a9317af99aa5ed2e73b385.jpg" border="0" small="0"  alt="" /></div>
</div>
<div forimg="1"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br />
<img src ="http://www.blogjava.net/xyzroundo/aggbug/200282.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-05-13 19:29 <a href="http://www.blogjava.net/xyzroundo/articles/200282.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>实践中整理出tomcat集群和负载均衡</title><link>http://www.blogjava.net/xyzroundo/articles/200280.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Tue, 13 May 2008 11:25:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/200280.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/200280.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/200280.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/200280.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/200280.html</trackback:ping><description><![CDATA[<p>来源：http://macrochen.blogdriver.com/macrochen/1207263.html</p>
<p>(一)环境说明<br />
(1)服务器有4台，一台安装apache,三台安装tomcat<br />
(2)apache2.0.55、tomcat5.5.15、jk2.0.4、jdk1.5.6或jdk1.4.2<br />
(3)ip配置,一台安装apache的ip为192.168.0.88,三台安装tomcat的服务器ip分别为192.168.0.1/2/4<br />
(二)安装过程<br />
(1)在三台要安装tomcat的服务器上先安装jdk<br />
(2)配置jdk的安装路径,在环境变量path中加入jdk的bin路径,新建环境变量JAVA_HOME指向jdk的安装路径<br />
(3)在三台要安装tomcat的服务器上分别安装tomcat,调试三个tomcat到能够正常启动<br />
(4)tomcat的默认WEB服务端口是8080,默认的模式是单独服务,我的三个tomcat的WEB服务端口修改为7080/8888/9999<br />
修改位置为tomcat的安装目录下的conf/server.xml<br />
修改前的配置为<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Connector port="8080" maxHttpHeaderSize="8192"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxThreads="150" minSpareThreads="25" maxSpareThreads="75"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enableLookups="false" redirectPort="8443" acceptCount="100"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; connectionTimeout="20000" disableUploadTimeout="true" /&gt;<br />
修改后的配置为<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Connector port="7080" maxHttpHeaderSize="8192"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxThreads="150" minSpareThreads="25" maxSpareThreads="75"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enableLookups="false" redirectPort="8443" acceptCount="100"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; connectionTimeout="20000" disableUploadTimeout="true" /&gt;<br />
依次修改每个tomcat的监听端口(7080/8888/9999)<br />
<br />
(5)分别测试每个tomcat的启动是否正常<br />
http://192.168.0.1:7080<br />
http://192.168.0.2:8888<br />
http://192.168.0.4:9999<br />
(三)负载均衡配置过程<br />
(1)在那台要安装apache的服务器上安装apache2.0.55,我的安装路径为默认C:\Program Files\Apache Group\Apache2<br />
(2)安装后测试apache能否正常启动，调试到能够正常启动http://192.168.0.88<br />
(3)下载jk2.0.4后解压缩文件<br />
(4)将解压缩后的目录中的modules目录中的mod_jk2.so文件复制到apache的安装目录下的modules目录中,我的为C:\Program Files\Apache Group\Apache2\modules<br />
(5)修改apache的安装目录中的conf目录的配置文件httpd.conf，在文件中加LoadModule模块配置信息的最后加上一句LoadModule jk2_module modules/mod_jk2.so<br />
(6)分别修改三个tomcat的配置文件conf/server.xml，修改内容如下<br />
修改前<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- An Engine represents the entry point (within Catalina) that processes<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; every request.&nbsp;&nbsp;The Engine implementation for Tomcat stand alone<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; analyzes the HTTP headers included with the request, and passes them<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; on to the appropriate Host (virtual host). --&gt;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- You should set jvmRoute to support load-balancing via AJP ie :<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Engine name="Standalone" defaultHost="localhost" jvmRoute="jvm1"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;--&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- Define the top level container in our container hierarchy --&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Engine name="Catalina" defaultHost="localhost"&gt;<br />
修改后<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- An Engine represents the entry point (within Catalina) that processes<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; every request.&nbsp;&nbsp;The Engine implementation for Tomcat stand alone<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; analyzes the HTTP headers included with the request, and passes them<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; on to the appropriate Host (virtual host). --&gt;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- You should set jvmRoute to support load-balancing via AJP ie :--&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Engine name="Standalone" defaultHost="localhost" jvmRoute="tomcat1"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- Define the top level container in our container hierarchy <br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Engine name="Catalina" defaultHost="localhost"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;--&gt;<br />
将其中的jvmRoute="jvm1"分别修改为jvmRoute="tomcat1"和jvmRoute="tomcat2"和jvmRoute="tomcat3"<br />
<br />
(7)然后重启三个tomcat，调试能够正常启动。<br />
(8)在apache的安装目录中的conf目录下创建文件workers2.propertie，写入文件内容如下<br />
<br />
# fine the communication channel <br />
[channel.socket:192.168.0.1:8009] <br />
info=Ajp13 forwarding over socket<br />
#配置第一个服务器 <br />
tomcatId=tomcat1 #要和tomcat的配置文件server.xml中的jvmRoute="tomcat1"名称一致<br />
debug=0 <br />
lb_factor=1 #负载平衡因子，数字越大请求被分配的几率越高<br />
<br />
# Define the communication channel <br />
[channel.socket:192.168.0.2:8009] <br />
info=Ajp13 forwarding over socket<br />
tomcatId=tomcat2 <br />
debug=0 <br />
lb_factor=1 <br />
<br />
# Define the communication channel <br />
[channel.socket:192.168.0.4:8009] <br />
info=Ajp13 forwarding over socket<br />
tomcatId=tomcat3 <br />
debug=0 <br />
lb_factor=1 <br />
<br />
[status:] <br />
info=Status worker, displays runtime information.&nbsp;&nbsp;<br />
<br />
[uri:/jkstatus.jsp] <br />
info=Display status information and checks the config file for changes. <br />
group=status: <br />
<br />
[uri:/*] <br />
info=Map the whole webapp <br />
debug=0<br />
(9)在三个tomcat的安装目录中的webapps建立相同的应用,我和应用目录名为TomcatDemo,在三个应用目录中建立相同 WEB-INF目录和页面index.jsp,index.jsp的页面内容如下<br />
&lt;%@ page contentType="text/html; charset=GBK" %&gt;<br />
&lt;%@ page import="java.util.*" %&gt;<br />
&lt;html&gt;&lt;head&gt;&lt;title&gt;Cluster App Test&lt;/title&gt;&lt;/head&gt;<br />
&lt;body&gt;<br />
Server Info:<br />
&lt;%<br />
out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"&lt;br&gt;");%&gt;<br />
&lt;%<br />
&nbsp;&nbsp;out.println("&lt;br&gt; ID " + session.getId()+"&lt;br&gt;");<br />
<br />
&nbsp;&nbsp;// 如果有新的 Session 属性设置<br />
&nbsp;&nbsp;String dataName = request.getParameter("dataName");<br />
&nbsp;&nbsp;if (dataName != null &amp;&amp; dataName.length() &gt; 0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp; String dataValue = request.getParameter("dataValue");<br />
&nbsp;&nbsp;&nbsp;&nbsp; session.setAttribute(dataName, dataValue);<br />
&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;out.print("&lt;b&gt;Session 列表&lt;/b&gt;");<br />
<br />
&nbsp;&nbsp;Enumeration e = session.getAttributeNames();<br />
&nbsp;&nbsp;while (e.hasMoreElements()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp; String name = (String)e.nextElement();<br />
&nbsp;&nbsp;&nbsp;&nbsp; String value = session.getAttribute(name).toString();<br />
&nbsp;&nbsp;&nbsp;&nbsp; out.println( name + " = " + value+"&lt;br&gt;");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println( name + " = " + value);<br />
&nbsp;&nbsp; }<br />
%&gt;<br />
&nbsp;&nbsp;&lt;form action="index.jsp" method="POST"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;名称:&lt;input type=text size=20 name="dataName"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;br&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;值:&lt;input type=text size=20 name="dataValue"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;br&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;input type=submit&gt;<br />
&nbsp;&nbsp; &lt;/form&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;<br />
(10)重启apache服务器和三个tomcat服务器,到此负载 均衡已配置完成。测试负载均衡先测试apache,访问http://192.168.0.88/jkstatus.jsp<br />
能否正常访问，并查询其中的内容，有三个tomcat的相关配置信息和负载说明,访问http://192.168.0.88/TomcatDemo/index.jsp看能够运行,<br />
能运行，则已建立负载均衡。<br />
(四)tomcat集群配置<br />
(1)负载均衡配置的条件下配置tomcat集群<br />
(2)分别修改三个tomcat的配置文件conf/server.xml,修改内容如下<br />
修改前<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; managerClassName="org.apache.catalina.cluster.session.DeltaManager"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; expireSessionsOnShutdown="false"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; useDirtyFlag="true"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; notifyListenersOnReplication="true"&gt;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Membership <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;className="org.apache.catalina.cluster.mcast.McastService"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mcastAddr="228.0.0.4"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mcastPort="45564"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mcastFrequency="500"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mcastDropTime="3000"/&gt;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Receiver <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;className="org.apache.catalina.cluster.tcp.ReplicationListener"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tcpListenAddress="auto"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tcpListenPort="4001"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tcpSelectorTimeout="100"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tcpThreadCount="6"/&gt;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Sender<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;replicationMode="pooled"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ackTimeout="5000"/&gt;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempDir="/tmp/war-temp/"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;deployDir="/tmp/war-deploy/"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;watchDir="/tmp/war-listen/"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;watchEnabled="false"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Cluster&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--&gt;&nbsp;&nbsp; <br />
修改后<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- modify by whh --&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; managerClassName="org.apache.catalina.cluster.session.DeltaManager"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; expireSessionsOnShutdown="false"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; useDirtyFlag="true"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; notifyListenersOnReplication="true"&gt;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Membership <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;className="org.apache.catalina.cluster.mcast.McastService"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mcastAddr="228.0.0.4"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mcastPort="45564"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mcastFrequency="500"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mcastDropTime="3000"/&gt;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Receiver <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;className="org.apache.catalina.cluster.tcp.ReplicationListener"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tcpListenAddress="auto"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tcpListenPort="4001"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tcpSelectorTimeout="100"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tcpThreadCount="6"/&gt;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Sender<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;replicationMode="pooled"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ackTimeout="5000"/&gt;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempDir="/tmp/war-temp/"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;deployDir="/tmp/war-deploy/"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;watchDir="/tmp/war-listen/"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;watchEnabled="false"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Cluster&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- modify by whh --&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
将集群配置选项的注释放开即可，如上。<br />
(3)重启三个tomcat。到此tomcat的集群已配置完成。</p>
<p>(五)应用配置<br />
对于要进行负载和集群的的tomcat目录下的webapps中的应用中的WEB-INF中的web.xml文件要添加如下一句配置<br />
&lt;distributable/&gt;<br />
配置前<br />
&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
&lt;web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"&gt;<br />
&nbsp;&nbsp;&lt;display-name&gt;TomcatDemo&lt;/display-name&gt;<br />
&lt;/web-app&gt;<br />
配置后<br />
&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
&lt;web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"&gt;<br />
&nbsp;&nbsp;&lt;display-name&gt;TomcatDemo&lt;/display-name&gt;<br />
&nbsp;&nbsp; &lt;distributable/&gt;<br />
&lt;/web-app&gt;</p>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/200280.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-05-13 19:25 <a href="http://www.blogjava.net/xyzroundo/articles/200280.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat集群与负载均衡</title><link>http://www.blogjava.net/xyzroundo/articles/200279.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Tue, 13 May 2008 11:23:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/200279.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/200279.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/200279.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/200279.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/200279.html</trackback:ping><description><![CDATA[<p>来源:http://blog.csdn.net/ladofwind/archive/2006/08/29/1138484.aspx<br />
<br />
&nbsp;&nbsp;在单一的服务器上执行WEB应用程序有一些重大的问题，当网站成功建成并开始接受大量请求时，单一服务器终究无法满足需要处理的负荷量，所以就有点显得有点力不从心了。另外一个常见的问题是会产生单点故障，如果该服务器坏掉，那么网站就立刻无法运作了。不论是因为要有较佳的扩充性还是容错能力，我们都会想在一台以上的服务器计算机上执行WEB应用程序。所以，这时候我们就需要用到集群这一门技术了。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在进入集群系统架构探讨之前，先定义一些专门术语：<br />
1.&nbsp;集群(Cluster)：是一组独立的计算机系统构成一个松耦合的多处理器系统，它们之间通过网络实现进程间的通信。应用程序可以通过网络共享内存进行消息传送，实现分布式计算机。&nbsp;<br />
2.&nbsp;负载均衡(Load&nbsp;Balance)：先得从集群讲起，集群就是一组连在一起的计算机，从外部看它是一个系统，各节点可以是不同的操作系统或不同硬件构成的计算机。如一个提供Web服务的集群，对外界来看是一个大Web服务器。不过集群的节点也可以单独提供服务。<br />
3.&nbsp;特点：在现有网络结构之上，负载均衡提供了一种廉价有效的方法扩展服务器带宽和增加吞吐量，加强网络数据处理能力，提高网络的灵活性和可用性。集群系统(Cluster)主要解决下面几个问题：&nbsp;<br />
高可靠性（HA）：利用集群管理软件，当主服务器故障时，备份服务器能够自动接管主服务器的工作，并及时切换过去，以实现对用户的不间断服务。<br />
高性能计算（HP）：即充分利用集群中的每一台计算机的资源，实现复杂运算的并行处理，通常用于科学计算领域，比如基因分析，化学分析等。&nbsp;<br />
负载平衡：即把负载压力根据某种算法合理分配到集群中的每一台计算机上，以减轻主服务器的压力，降低对主服务器的硬件和软件要求。<br />
<br />
目前比较常用的负载均衡技术主要有：&nbsp;<br />
　　1.&nbsp;基于DNS的负载均衡&nbsp;<br />
　　通过DNS服务中的随机名字解析来实现负载均衡，在DNS服务器中，可以为多个不同的地址配置同一个名字，而最终查询这个名字的客户机将在解析这个名字时得到其中一个地址。因此，对于同一个名字，不同的客户机会得到不同的地址，他们也就访问不同地址上的Web服务器，从而达到负载均衡的目的。&nbsp;<br />
<br />
　　2.&nbsp;反向代理负载均衡&nbsp;（如Apache+JK2+Tomcat这种组合）<br />
　　使用代理服务器可以将请求转发给内部的Web服务器，让代理服务器将请求均匀地转发给多台内部Web服务器之一上，从而达到负载均衡的目的。这种代理方式与普通的代理方式有所不同，标准代理方式是客户使用代理访问多个外部Web服务器，而这种代理方式是多个客户使用它访问内部Web服务器，因此也被称为反向代理模式。<br />
<br />
　　3.&nbsp;基于NAT（Network&nbsp;Address&nbsp;Translation）的负载均衡技术&nbsp;（如Linux&nbsp;Virtual&nbsp;Server，简称LVS）<br />
　　网络地址转换为在内部地址和外部地址之间进行转换，以便具备内部地址的计算机能访问外部网络，而当外部网络中的计算机访问地址转换网关拥有的某一外部地址时，地址转换网关能将其转发到一个映射的内部地址上。因此如果地址转换网关能将每个连接均匀转换为不同的内部服务器地址，此后外部网络中的计算机就各自与自己转换得到的地址上服务器进行通信，从而达到负载分担的目的。<br />
<br />
介绍完上面的集群技术之后，下面就基于Tomcat的集群架构方案进行说明：<br />
<br />
上面是采用了Apache&nbsp;httpd作为web服务器的，即作为Tomcat的前端处理器，根据具体情况而定，有些情况下是不需要Apache&nbsp;httpd作为&nbsp;web&nbsp;服务器的，如系统展现没有静态页面那就不需要Apache&nbsp;httpd，那时可以直接使用Tomcat作为web&nbsp;服务器来使用。使用Apache&nbsp;httpd主要是它在处理静态页面方面的能力比Tomcat强多了。<br />
1、&nbsp;用户的网页浏览器做完本地&nbsp;DNS和企业授权的DNS之的请求/响应后，这时候企业授权的DNS（即21cn&nbsp;BOSS&nbsp;DNS）会给用户本地的DNS服务器提供一个NAT请求分配器（即网关）IP。<br />
<br />
<br />
2、&nbsp;NAT分配器，它会根据特定的分配算法，来决定要将连接交给哪一台内部&nbsp;Apache&nbsp;httpd来处理请求。大多数的NAT请求分配器提供了容错能力：根据侦测各种WEB服务器的失效状况，停止将请求分配给已经宕掉的服务器。并且有些分配器还可以监测到WEB服务器机器的负载情况，并将请求分配给负载最轻的服务器等等。Linux&nbsp;Virtual&nbsp;Server是一个基于Linux操作系统上执行的VS-NAT开源软件套件，而且它有丰富的功能和良好的说明文件。商业硬件解决方案&nbsp;Foundry&nbsp;Networks的ServerIron是目前业界公认最佳的请求分配器之一。<br />
<br />
<br />
3、&nbsp;Apache&nbsp;httpd&nbsp;+&nbsp;Mod_JK2在这里是作为负载均衡器，那为什么要做集群呢？如果集群系统要具备容错能力，以便在任何单一的硬件或软件组件失效时还能100%可用，那么集群系统必须没有单点故障之忧。所以，不能只架设一台有mod_jk2的Apache&nbsp;httpd，因为如果&nbsp;httpd或mod_jk2失效了，将不会再有请求被会送交到任何一个Tomcat&nbsp;实例。这种情况下，Apache&nbsp;httpd就是瓶劲，特别在访问量大的网站。<br />
<br />
<br />
4、&nbsp;Mod_JK2负载均衡与故障复原，决定把Apache&nbsp;httpd当成web服务器，而且使用mod_jk2将请求传送给Tomcat，则可以使用mod_jk2的负载均衡与容错功能。在集群系统中，带有mod_jk2的Apache&nbsp;httpd可以做的事情包括：<br />
A、&nbsp;将请求分配至一或多个Tomcat实例上<br />
你可以在mod_jk2的workers.properties文件中，设定许多Tomcat实例，并赋于每个实例一个lb_factor值，以作为请求分配的加权因子。<br />
<br />
<br />
B、&nbsp;侦测Tomcat实例是否失败<br />
当Tomcat实例的连接器服务不再响应时，mod_jk2会及时侦测到，并停止将请求送给它。其他的Tomcat实例则会接受失效实例的负载。<br />
<br />
<br />
C、&nbsp;侦测Tomcat实例在失效后的何时恢复<br />
因连接器服务失效，而停止将请求分配给Tomcat实例之后，mod_jk2会周期性地检查是否已恢复使用性，并自动将其加入现行的Tomcat实例池中。<br />
<br />
<br />
5、&nbsp;Tomcat中的集群原理是通过组播的方式进行节点的查找并使用TCP连接进行会话的复制。这里提示一下就是，对每个请求的处理，Tomcat都会进行会话复制，复制后的会话将会慢慢变得庞大。<br />
<br />
<br />
6、&nbsp;Mod_jk2同时支持会话亲和和会话复制。在tomcat&nbsp;5中如何实现会话亲和和会话复制？把server.xml中的&lt;cluster/&gt;标签去掉就实现会话亲和，把&lt;cluster/&gt;标签加上就实现会话复制。<br />
<br />
<br />
7、&nbsp;会话亲和：就是表示来自同会话的所有请求都由相同的Tomcat&nbsp;实例来处理，这种情况下，如果Tomcat实例或所执行的服务器机器失效，也会丧失Servlet的会话数据。即使在集群系统中执行更多的Tomcat实例，也永远不会复制会话数据。这样是提高集群性能的一种方案，但不具备有容错能力了。<br />
<br />
<br />
8、&nbsp;使用会话复制，则当一个Tomcat实例宕掉时，由于至少还有另一个Tomcat实例保有一份会话状态数据，因而数据不会丧失。但性能会有所降低。&nbsp;</p>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/200279.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-05-13 19:23 <a href="http://www.blogjava.net/xyzroundo/articles/200279.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>freemarker 点滴</title><link>http://www.blogjava.net/xyzroundo/articles/200266.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Tue, 13 May 2008 10:40:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/200266.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/200266.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/200266.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/200266.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/200266.html</trackback:ping><description><![CDATA[<h2>FreeMarker概述</h2>
<ul>
    <li>FreeMarker是一个模板引擎，一个基于模板生成文本输出的通用工具，使用纯Java编写
    <li>Template + data model = output
    <li><img height="191" alt="" src="http://www.wujianrong.com/photo/overview.png" width="416" />
    <li>
    <h2>Hello world</h2>
    <li>FreeMarkerTest.java </li>
</ul>
<pre class="java">&nbsp;<br />
<span style="color: rgb(161,161,0)">import java.io.StringWriter;</span><span style="color: rgb(161,161,0)">import java.util.HashMap;</span><span style="color: rgb(161,161,0)">import java.util.Locale;</span><br />
&nbsp;<br />
<span style="color: rgb(161,161,0)">import freemarker.template.Configuration;</span><span style="color: rgb(161,161,0)">import freemarker.template.Template;</span><br />
&nbsp;<br />
<span style="font-weight: bold; color: rgb(0,0,0)">public</span><span style="font-weight: bold; color: rgb(0,0,0)">class</span> FreeMarkerTest <span style="color: rgb(102,204,102)">{</span><br />
&nbsp;<br />
<span style="font-weight: bold; color: rgb(0,0,0)">public</span><span style="font-weight: bold; color: rgb(0,0,0)">static</span><span style="color: rgb(153,51,51)">void</span> main<span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(170,170,221)">String</span><span style="color: rgb(102,204,102)">[</span><span style="color: rgb(102,204,102)">]</span> args<span style="color: rgb(102,204,102)">)</span><span style="color: rgb(102,204,102)">{</span><br />
FreeMarkerTest test = <span style="font-weight: bold; color: rgb(0,0,0)">new</span> FreeMarkerTest<span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>;<br />
test.<span style="color: rgb(0,102,0)">sayHello</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(255,0,0)">"Hermit"</span><span style="color: rgb(102,204,102)">)</span>;<br />
<span style="color: rgb(102,204,102)">}</span><br />
&nbsp;<br />
<span style="font-weight: bold; color: rgb(0,0,0)">public</span><span style="color: rgb(153,51,51)">void</span> sayHello<span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(170,170,221)">String</span> name<span style="color: rgb(102,204,102)">)</span><span style="color: rgb(102,204,102)">{</span><br />
Configuration freemarkerCfg = <span style="font-weight: bold; color: rgb(0,0,0)">new</span> Configuration<span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>;<br />
freemarkerCfg.<span style="color: rgb(0,102,0)">setClassForTemplateLoading</span><span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(0,0,0)">this</span>.<span style="color: rgb(0,102,0)">getClass</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>, <span style="color: rgb(255,0,0)">"/"</span><span style="color: rgb(102,204,102)">)</span>;<br />
&nbsp;<br />
freemarkerCfg.<span style="color: rgb(0,102,0)">setEncoding</span><span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(170,170,221)">Locale</span>.<span style="color: rgb(0,102,0)">getDefault</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>, <span style="color: rgb(255,0,0)">"UTF-8"</span><span style="color: rgb(102,204,102)">)</span>;<br />
Template template;<br />
<span style="font-weight: bold; color: rgb(170,170,221)">Locale</span>.<span style="color: rgb(0,102,0)">setDefault</span><span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(170,170,221)">Locale</span>.<span style="color: rgb(0,102,0)">ENGLISH</span><span style="color: rgb(102,204,102)">)</span>;<br />
<span style="font-weight: bold; color: rgb(0,0,0)">try</span><span style="color: rgb(102,204,102)">{</span><br />
template = freemarkerCfg.<span style="color: rgb(0,102,0)">getTemplate</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(255,0,0)">"Hello.ftl"</span><span style="color: rgb(102,204,102)">)</span>;<br />
template.<span style="color: rgb(0,102,0)">setEncoding</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(255,0,0)">"UTF-8"</span><span style="color: rgb(102,204,102)">)</span>;<br />
<span style="font-weight: bold; color: rgb(170,170,221)">HashMap</span> root = <span style="font-weight: bold; color: rgb(0,0,0)">new</span><span style="font-weight: bold; color: rgb(170,170,221)">HashMap</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>;<br />
root.<span style="color: rgb(0,102,0)">put</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(255,0,0)">"user"</span>, name<span style="color: rgb(102,204,102)">)</span>;<br />
&nbsp;<br />
<span style="font-weight: bold; color: rgb(170,170,221)">StringWriter</span> writer = <span style="font-weight: bold; color: rgb(0,0,0)">new</span><span style="font-weight: bold; color: rgb(170,170,221)">StringWriter</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>;<br />
template.<span style="color: rgb(0,102,0)">process</span><span style="color: rgb(102,204,102)">(</span>root, writer<span style="color: rgb(102,204,102)">)</span>;<br />
<span style="font-weight: bold; color: rgb(170,170,221)">System</span>.<span style="color: rgb(0,102,0)">out</span>.<span style="color: rgb(0,102,0)">println</span><span style="color: rgb(102,204,102)">(</span>writer.<span style="color: rgb(0,102,0)">toString</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span><span style="color: rgb(102,204,102)">)</span>;<br />
<span style="color: rgb(102,204,102)">}</span><span style="font-weight: bold; color: rgb(0,0,0)">catch</span><span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(170,170,221)">Exception</span> e<span style="color: rgb(102,204,102)">)</span><span style="color: rgb(102,204,102)">{</span><br />
e.<span style="color: rgb(0,102,0)">printStackTrace</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>;<br />
<span style="color: rgb(102,204,102)">}</span><span style="color: rgb(102,204,102)">}</span><br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />
<span style="color: rgb(102,204,102)">}</span><br />
&nbsp;</pre>
<ul>
    <li>Hello.ftl </li>
</ul>
<pre class="html4strict">&nbsp;<br />
&nbsp;<br />
Hello ${user}!<br />
&nbsp;<br />
&nbsp;</pre>
<ul>
    <li>输出 </li>
</ul>
<p>Hello Hermit! </p>
<p><br />
</p>
<a name=".E7.A9.BA.E5.80.BC.E7.9A.84.E5.A4.84.E7.90.86"></a>
<h2>空值的处理</h2>
<p>在我们的程序中难免会碰到值为空的时候，如果用一个空值直接去替换模板中的标记，freemarker会毫不犹豫的抛出异常，并把错误信息直接写到输出结果里。为了对付这种情况我们有两种写法 </p>
<ul>
    <li>模板 </li>
</ul>
<pre class="html4strict">&nbsp;<br />
Hello ${user!}!<br />
Hello ${user?if_exists}<br />
Hello ${user!'your name'}!<br />
Hello ${user?default('your name')}<br />
&nbsp;</pre>
<ul>
    <li>程序 </li>
</ul>
<pre class="java">&nbsp;<br />
test.<span style="color: rgb(0,102,0)">sayHello</span><span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(0,0,0)">null</span><span style="color: rgb(102,204,102)">)</span>;<br />
&nbsp;</pre>
<ul>
    <li>输出 </li>
</ul>
<pre class="java">&nbsp;<br />
Hello&nbsp;!<br />
Hello your name!<br />
Hello <br />
Hello your name<br />
&nbsp;</pre>
<a name="freemarker.E5.9B.BD.E9.99.85.E5.8C.96.E6.A8.A1.E6.9D.BF"></a>
<h2>freemarker国际化模板</h2>
<p>freemarker支持多语言国际化，只要把模板名称按照java资源文件的写法就可以了,也就是name_语言_国家地区.ftl 如果找不到对应的语言，就会用默认语言的模板。 </p>
<ul>
    <li>程序 </li>
</ul>
<pre class="java">&nbsp;<br />
<span style="color: rgb(161,161,0)">import java.io.StringWriter;</span><span style="color: rgb(161,161,0)">import java.util.HashMap;</span><span style="color: rgb(161,161,0)">import java.util.Locale;</span><br />
&nbsp;<br />
<span style="color: rgb(161,161,0)">import freemarker.template.Configuration;</span><span style="color: rgb(161,161,0)">import freemarker.template.Template;</span><br />
&nbsp;<br />
<span style="font-weight: bold; color: rgb(0,0,0)">public</span><span style="font-weight: bold; color: rgb(0,0,0)">class</span> FreeMarkerTest <span style="color: rgb(102,204,102)">{</span><br />
&nbsp;<br />
<span style="font-weight: bold; color: rgb(0,0,0)">public</span><span style="font-weight: bold; color: rgb(0,0,0)">static</span><span style="color: rgb(153,51,51)">void</span> main<span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(170,170,221)">String</span><span style="color: rgb(102,204,102)">[</span><span style="color: rgb(102,204,102)">]</span> args<span style="color: rgb(102,204,102)">)</span><span style="color: rgb(102,204,102)">{</span><br />
FreeMarkerTest test = <span style="font-weight: bold; color: rgb(0,0,0)">new</span> FreeMarkerTest<span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>;<br />
test.<span style="color: rgb(0,102,0)">sayHello</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(255,0,0)">"hermit"</span>,<span style="font-weight: bold; color: rgb(170,170,221)">Locale</span>.<span style="color: rgb(0,102,0)">CHINA</span><span style="color: rgb(102,204,102)">)</span>;<br />
test.<span style="color: rgb(0,102,0)">sayHello</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(255,0,0)">"hermit"</span>,<span style="font-weight: bold; color: rgb(170,170,221)">Locale</span>.<span style="color: rgb(0,102,0)">ENGLISH</span><span style="color: rgb(102,204,102)">)</span>;<br />
<span style="color: rgb(102,204,102)">}</span><br />
&nbsp;<br />
<span style="font-weight: bold; color: rgb(0,0,0)">public</span><span style="color: rgb(153,51,51)">void</span> sayHello<span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(170,170,221)">String</span> name,<span style="font-weight: bold; color: rgb(170,170,221)">Locale</span> locale<span style="color: rgb(102,204,102)">)</span><span style="color: rgb(102,204,102)">{</span><br />
Configuration freemarkerCfg = <span style="font-weight: bold; color: rgb(0,0,0)">new</span> Configuration<span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>;<br />
freemarkerCfg.<span style="color: rgb(0,102,0)">setClassForTemplateLoading</span><span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(0,0,0)">this</span>.<span style="color: rgb(0,102,0)">getClass</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>, <span style="color: rgb(255,0,0)">"/"</span><span style="color: rgb(102,204,102)">)</span>;<br />
&nbsp;<br />
freemarkerCfg.<span style="color: rgb(0,102,0)">setEncoding</span><span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(170,170,221)">Locale</span>.<span style="color: rgb(0,102,0)">getDefault</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>, <span style="color: rgb(255,0,0)">"UTF-8"</span><span style="color: rgb(102,204,102)">)</span>;<br />
Template template;<br />
<span style="font-weight: bold; color: rgb(170,170,221)">Locale</span>.<span style="color: rgb(0,102,0)">setDefault</span><span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(170,170,221)">Locale</span>.<span style="color: rgb(0,102,0)">ENGLISH</span><span style="color: rgb(102,204,102)">)</span>;<br />
<span style="font-weight: bold; color: rgb(0,0,0)">try</span><span style="color: rgb(102,204,102)">{</span><br />
template = freemarkerCfg.<span style="color: rgb(0,102,0)">getTemplate</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(255,0,0)">"Hello.ftl"</span>,locale<span style="color: rgb(102,204,102)">)</span>;<br />
template.<span style="color: rgb(0,102,0)">setEncoding</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(255,0,0)">"UTF-8"</span><span style="color: rgb(102,204,102)">)</span>;<br />
<span style="font-weight: bold; color: rgb(170,170,221)">HashMap</span> root = <span style="font-weight: bold; color: rgb(0,0,0)">new</span><span style="font-weight: bold; color: rgb(170,170,221)">HashMap</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>;<br />
root.<span style="color: rgb(0,102,0)">put</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(255,0,0)">"user"</span>, name<span style="color: rgb(102,204,102)">)</span>;<br />
&nbsp;<br />
<span style="font-weight: bold; color: rgb(170,170,221)">StringWriter</span> writer = <span style="font-weight: bold; color: rgb(0,0,0)">new</span><span style="font-weight: bold; color: rgb(170,170,221)">StringWriter</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>;<br />
template.<span style="color: rgb(0,102,0)">process</span><span style="color: rgb(102,204,102)">(</span>root, writer<span style="color: rgb(102,204,102)">)</span>;<br />
<span style="font-weight: bold; color: rgb(170,170,221)">System</span>.<span style="color: rgb(0,102,0)">out</span>.<span style="color: rgb(0,102,0)">println</span><span style="color: rgb(102,204,102)">(</span>writer.<span style="color: rgb(0,102,0)">toString</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span><span style="color: rgb(102,204,102)">)</span>;<br />
<span style="color: rgb(102,204,102)">}</span><span style="font-weight: bold; color: rgb(0,0,0)">catch</span><span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(170,170,221)">Exception</span> e<span style="color: rgb(102,204,102)">)</span><span style="color: rgb(102,204,102)">{</span><br />
e.<span style="color: rgb(0,102,0)">printStackTrace</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>;<br />
<span style="color: rgb(102,204,102)">}</span><span style="color: rgb(102,204,102)"><br />
}</span><br />
&nbsp;&nbsp;<br />
<span style="color: rgb(102,204,102)">}</span><br />
&nbsp;</pre>
<ul>
    <li>默认语言模版:Hello.ftl<br />
    </li>
</ul>
<pre class="html4strict">Hello ${user!}!&nbsp;<br />
中文模版:Hello_zh_CN.ftl <br />
你好 ${user!}!<br />
<br />
输出<br />
</pre>
<pre class="html4strict">你好 hermit!<br />
Hello hermit!<br />
&nbsp;</pre>
<a name=".E5.9C.A8struts.E9.A1.B9.E7.9B.AE.E4.B8.AD.E4.BD.BF.E7.94.A8freemarker"></a>
<h2>在struts项目中使用freemarker</h2>
<dl>
<dd>1、引入freemarker.jar
<dd>2、web.xml加入<br />
</dd></dl>
<pre class="xml">	<span style="color: rgb(0,153,0)"><span style="color: rgb(128,128,128); font-style: italic">&lt;!-- FreeMarker view servlet (to replace JSP) --&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black"><br />
&lt;servlet<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;servlet-name<span style="font-weight: bold; color: black">&gt;</span></span></span>freemarker<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/servlet-name<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;servlet-class<span style="font-weight: bold; color: black">&gt;</span></span></span><br />
freemarker.ext.servlet.FreemarkerServlet<br />
<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/servlet-class<span style="font-weight: bold; color: black">&gt;</span></span></span><br />
&nbsp;<br />
<span style="color: rgb(0,153,0)"><span style="color: rgb(128,128,128); font-style: italic">&lt;!-- FreemarkerServlet settings: --&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black"><br />
&lt;init-param<span style="font-weight: bold; color: black">&gt;<br />
</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;param-name<span style="font-weight: bold; color: black">&gt;</span></span></span>TemplatePath<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/param-name<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black"><br />
&lt;param-value<span style="font-weight: bold; color: black">&gt;</span></span></span>/<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/param-value<span style="font-weight: bold; color: black">&gt;<br />
</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/init-param<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black"><br />
&lt;init-param<span style="font-weight: bold; color: black">&gt;<br />
</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;param-name<span style="font-weight: bold; color: black">&gt;</span></span></span>NoCache<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/param-name<span style="font-weight: bold; color: black">&gt;<br />
</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;param-value<span style="font-weight: bold; color: black">&gt;</span></span></span>true<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/param-value<span style="font-weight: bold; color: black">&gt;<br />
</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/init-param<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black"><br />
&lt;init-param<span style="font-weight: bold; color: black">&gt;<br />
</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;param-name<span style="font-weight: bold; color: black">&gt;</span></span></span>ContentType<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/param-name<span style="font-weight: bold; color: black">&gt;<br />
</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;param-value<span style="font-weight: bold; color: black">&gt;</span></span></span>text/html<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/param-value<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black"><br />
&lt;/init-param<span style="font-weight: bold; color: black">&gt;</span></span></span><br />
&nbsp;<br />
<span style="color: rgb(0,153,0)"><span style="color: rgb(128,128,128); font-style: italic">&lt;!-- FreeMarker settings: --&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;init-param<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;param-name<span style="font-weight: bold; color: black">&gt;</span></span></span>template_update_delay<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/param-name<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;param-value<span style="font-weight: bold; color: black">&gt;</span></span></span>0<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/param-value<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="color: rgb(128,128,128); font-style: italic"><br />
&lt;!-- 0 is for development only! Use higher value otherwise. --&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black"><br />
&lt;/init-param<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;init-param<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;param-name<span style="font-weight: bold; color: black">&gt;</span></span></span>default_encoding<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/param-name<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black"><br />
&lt;param-value<span style="font-weight: bold; color: black">&gt;</span></span></span>utf-8<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/param-value<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/init-param<span style="font-weight: bold; color: black">&gt;<br />
</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;init-param<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;param-name<span style="font-weight: bold; color: black">&gt;</span></span></span>locale<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/param-name<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;param-value<span style="font-weight: bold; color: black">&gt;</span></span></span>en_US<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/param-value<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/init-param<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black"><br />
&lt;init-param<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;param-name<span style="font-weight: bold; color: black">&gt;</span></span></span>number_format<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/param-name<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;param-value<span style="font-weight: bold; color: black">&gt;</span></span></span>0.##########<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/param-value<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/init-param<span style="font-weight: bold; color: black">&gt;</span></span></span><br />
&nbsp;<br />
<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;load-on-startup<span style="font-weight: bold; color: black">&gt;</span></span></span>1<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/load-on-startup<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/servlet<span style="font-weight: bold; color: black">&gt;</span></span></span><br />
&nbsp;<br />
<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;servlet-mapping<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;servlet-name<span style="font-weight: bold; color: black">&gt;</span></span></span>freemarker<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/servlet-name<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;url-pattern<span style="font-weight: bold; color: black">&gt;</span></span></span>*.ftl<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/url-pattern<span style="font-weight: bold; color: black">&gt;</span></span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: black">&lt;/servlet-mapping<span style="font-weight: bold; color: black">&gt;</span></span></span><br />
&nbsp;</pre>
<dl>
<dd>3、一个示例页面 </dd></dl>
<pre class="html4strict">&nbsp;<br />
<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;html&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;head&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;title&gt;</span></span>Say Hello<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;/title&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;META</span><span style="color: rgb(0,0,102)">HTTP-EQUIV</span>=<span style="color: rgb(255,0,0)">"Content-Type"</span><span style="color: rgb(0,0,102)">CONTENT</span>=<span style="color: rgb(255,0,0)">"text/html; charset=utf-8"</span><span style="font-weight: bold; color: rgb(0,0,0)">&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;/head&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;body&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;h1&gt;</span></span>Hello ${user}!<span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;/h1&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;/body&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;/html&gt;</span></span><br />
&nbsp;</pre>
<p>我们完全可以用freemarker的模板取代JSP页面。用freemarker的模板看起更简洁，可读性更强。比如现在struts2的UI标签就是用freemarker做的。 </p>
<a name="freemarker.E7.94.A8struts.E6.A0.87.E7.AD.BE.E5.81.9A.E5.9B.BD.E9.99.85.E5.8C.96"></a>
<h2>freemarker用struts标签做国际化</h2>
<ul>
    <li>示例模板<br />
    </li>
</ul>
<pre class="html4strict"><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;</span>#assign  html =JspTaglibs<span style="color: rgb(102,204,102)">[</span><span style="color: rgb(255,0,0)">"/WEB-INF/struts-html.tld"</span><span style="color: rgb(102,204,102)">]</span><span style="font-weight: bold; color: rgb(0,0,0)">&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;</span>#assign  bean =JspTaglibs<span style="color: rgb(102,204,102)">[</span><span style="color: rgb(255,0,0)">"/WEB-INF/struts-bean.tld"</span><span style="color: rgb(102,204,102)">]</span><span style="font-weight: bold; color: rgb(0,0,0)">&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;</span>#assign  logic =JspTaglibs<span style="color: rgb(102,204,102)">[</span><span style="color: rgb(255,0,0)">"/WEB-INF/struts-logic.tld"</span><span style="color: rgb(102,204,102)">]</span><span style="font-weight: bold; color: rgb(0,0,0)">&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;html&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;head&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;title&gt;</span></span> FreeMarker Struts Example <span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;/title&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;meta</span><span style="color: rgb(0,0,102)">http-equiv</span> =<span style="color: rgb(255,0,0)">"Content-type"</span><span style="color: rgb(0,0,102)">content</span> =<span style="color: rgb(255,0,0)">"text/html; charset=utf-8"</span><span style="font-weight: bold; color: rgb(0,0,0)">&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;</span>/ head <span style="font-weight: bold; color: rgb(0,0,0)">&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;body&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;</span>@bean.message key =<span style="color: rgb(255,0,0)">"hello"</span>  arg0 =<span style="color: rgb(255,0,0)">"hermit"</span>/<span style="font-weight: bold; color: rgb(0,0,0)">&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;/body&gt;</span></span><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;/html&gt;</span></span> </pre>
<p>主要是引入标签的时候要这样写：<br />
</p>
<pre class="html4strict"><span style="color: rgb(0,153,0)"><span style="font-weight: bold; color: rgb(0,0,0)">&lt;</span>#assign  html =JspTaglibs<span style="color: rgb(102,204,102)">[</span><span style="color: rgb(255,0,0)">"/WEB-INF/struts-html.tld"</span><span style="color: rgb(102,204,102)">]</span><span style="font-weight: bold; color: rgb(0,0,0)">&gt;</span></span> </pre>
<a name="freemarker.E7.9B.B4.E6.8E.A5.E4.BD.BF.E7.94.A8.E8.B5.84.E6.BA.90.E6.96.87.E4.BB.B6.E8.BF.9B.E8.A1.8C.E5.A4.9A.E8.AF.AD.E8.A8.80.E5.9B.BD.E9.99.85.E5.8C.96"></a>
<h2>freemarker直接使用资源文件进行多语言国际化</h2>
<ul>
    <li>程序<br />
    </li>
</ul>
<pre class="java"><span style="color: rgb(161,161,0)">import java.io.StringWriter;</span><span style="color: rgb(161,161,0)">import java.util.HashMap;</span><span style="color: rgb(161,161,0)">import java.util.Locale;</span><span style="color: rgb(161,161,0)">import java.util.ResourceBundle;</span><br />
&nbsp;<br />
<span style="color: rgb(161,161,0)">import freemarker.ext.beans.BeansWrapper;</span><span style="color: rgb(161,161,0)">import freemarker.ext.beans.ResourceBundleModel;</span><span style="color: rgb(161,161,0)">import freemarker.template.Configuration;</span><span style="color: rgb(161,161,0)">import freemarker.template.Template;</span><br />
&nbsp;<br />
<span style="font-weight: bold; color: rgb(0,0,0)">public</span><span style="font-weight: bold; color: rgb(0,0,0)">class</span> FreeMarkerTest <span style="color: rgb(102,204,102)">{</span><br />
&nbsp;<br />
<span style="font-weight: bold; color: rgb(0,0,0)">public</span><span style="font-weight: bold; color: rgb(0,0,0)">static</span><span style="color: rgb(153,51,51)">void</span> main<span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(170,170,221)">String</span><span style="color: rgb(102,204,102)">[</span><span style="color: rgb(102,204,102)">]</span> args<span style="color: rgb(102,204,102)">)</span><span style="color: rgb(102,204,102)">{</span><br />
FreeMarkerTest test = <span style="font-weight: bold; color: rgb(0,0,0)">new</span> FreeMarkerTest<span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>;<br />
test.<span style="color: rgb(0,102,0)">sayHello</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(255,0,0)">"hermit"</span>,<span style="font-weight: bold; color: rgb(170,170,221)">Locale</span>.<span style="color: rgb(0,102,0)">CHINA</span><span style="color: rgb(102,204,102)">)</span>;<br />
test.<span style="color: rgb(0,102,0)">sayHello</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(255,0,0)">"hermit"</span>,<span style="font-weight: bold; color: rgb(170,170,221)">Locale</span>.<span style="color: rgb(0,102,0)">ENGLISH</span><span style="color: rgb(102,204,102)">)</span>;<br />
<span style="color: rgb(102,204,102)">}</span><br />
&nbsp;<br />
<span style="font-weight: bold; color: rgb(0,0,0)">public</span><span style="color: rgb(153,51,51)">void</span> sayHello<span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(170,170,221)">String</span> name,<span style="font-weight: bold; color: rgb(170,170,221)">Locale</span> locale<span style="color: rgb(102,204,102)">)</span><span style="color: rgb(102,204,102)">{</span><br />
Configuration freemarkerCfg = <span style="font-weight: bold; color: rgb(0,0,0)">new</span> Configuration<span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>;<br />
freemarkerCfg.<span style="color: rgb(0,102,0)">setClassForTemplateLoading</span><span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(0,0,0)">this</span>.<span style="color: rgb(0,102,0)">getClass</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>, <span style="color: rgb(255,0,0)">"/"</span><span style="color: rgb(102,204,102)">)</span>;<br />
&nbsp;<br />
freemarkerCfg.<span style="color: rgb(0,102,0)">setEncoding</span><span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(170,170,221)">Locale</span>.<span style="color: rgb(0,102,0)">getDefault</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>, <span style="color: rgb(255,0,0)">"UTF-8"</span><span style="color: rgb(102,204,102)">)</span>;<br />
Template template;<br />
<span style="font-weight: bold; color: rgb(170,170,221)">Locale</span>.<span style="color: rgb(0,102,0)">setDefault</span><span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(170,170,221)">Locale</span>.<span style="color: rgb(0,102,0)">ENGLISH</span><span style="color: rgb(102,204,102)">)</span>;<br />
<span style="font-weight: bold; color: rgb(0,0,0)">try</span><span style="color: rgb(102,204,102)">{</span><br />
template = freemarkerCfg.<span style="color: rgb(0,102,0)">getTemplate</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(255,0,0)">"Hello.ftl"</span><span style="color: rgb(102,204,102)">)</span>;<br />
template.<span style="color: rgb(0,102,0)">setEncoding</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(255,0,0)">"UTF-8"</span><span style="color: rgb(102,204,102)">)</span>;<br />
<span style="font-weight: bold; color: rgb(170,170,221)">HashMap</span> root = <span style="font-weight: bold; color: rgb(0,0,0)">new</span><span style="font-weight: bold; color: rgb(170,170,221)">HashMap</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>;<br />
root.<span style="color: rgb(0,102,0)">put</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(255,0,0)">"user"</span>, name<span style="color: rgb(102,204,102)">)</span>;<br />
<span style="font-weight: bold; color: rgb(170,170,221)">ResourceBundle</span> RESOURCE_BUNDLE = <span style="font-weight: bold; color: rgb(170,170,221)">ResourceBundle</span>.<span style="color: rgb(0,102,0)">getBundle</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(255,0,0)">"ApplicationResources"</span>,locale<span style="color: rgb(102,204,102)">)</span>;<br />
ResourceBundleModel rsbm = <span style="font-weight: bold; color: rgb(0,0,0)">new</span> ResourceBundleModel<span style="color: rgb(102,204,102)">(</span>RESOURCE_BUNDLE,<span style="font-weight: bold; color: rgb(0,0,0)">new</span> BeansWrapper<span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span><span style="color: rgb(102,204,102)">)</span>;<br />
root.<span style="color: rgb(0,102,0)">put</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(255,0,0)">"bundle"</span>, rsbm<span style="color: rgb(102,204,102)">)</span>;<br />
<span style="font-weight: bold; color: rgb(170,170,221)">StringWriter</span> writer = <span style="font-weight: bold; color: rgb(0,0,0)">new</span><span style="font-weight: bold; color: rgb(170,170,221)">StringWriter</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>;<br />
template.<span style="color: rgb(0,102,0)">process</span><span style="color: rgb(102,204,102)">(</span>root, writer<span style="color: rgb(102,204,102)">)</span>;<br />
<span style="font-weight: bold; color: rgb(170,170,221)">System</span>.<span style="color: rgb(0,102,0)">out</span>.<span style="color: rgb(0,102,0)">println</span><span style="color: rgb(102,204,102)">(</span>writer.<span style="color: rgb(0,102,0)">toString</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span><span style="color: rgb(102,204,102)">)</span>;<br />
<span style="color: rgb(102,204,102)">}</span><span style="font-weight: bold; color: rgb(0,0,0)">catch</span><span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(170,170,221)">Exception</span> e<span style="color: rgb(102,204,102)">)</span><span style="color: rgb(102,204,102)">{</span><br />
e.<span style="color: rgb(0,102,0)">printStackTrace</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>;<br />
<span style="color: rgb(102,204,102)">}</span><span style="color: rgb(102,204,102)">}</span><br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />
<span style="color: rgb(102,204,102)">}</span> <br />
<br />
模板<br />
</pre>
<pre class="html4strict">${bundle("hello","hermit")} <br />
<br />
默认语言资源文件 </pre>
<pre class="html4strict">hello=Hello {0}\! <br />
<br />
中文资源文件 <br />
<br />
hello=你好 {0}\!</pre>
<ul>
    <li>输出<br />
    </li>
</ul>
<pre class="html4strict">你好 hermit!<br />
Hello hermit!</pre>
<p>关键的地方就是用ResourceBundleModel把ResourceBundle转换一下。 </p>
<a name=".E5.B8.B8.E7.94.A8.E7.9A.842.E7.A7.8D.E5.8A.A0.E8.BD.BD.E6.A8.A1.E6.9D.BF.E7.9A.84.E6.96.B9.E5.BC.8F"></a>
<h2>常用的2种加载模板的方式</h2>
<ul>
    <li>普通java类根据当前class上下文环境加载模板<br />
    </li>
</ul>
<pre class="java">cfg.<span style="color: rgb(0,102,0)">setClassForTemplateLoading</span><span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(0,0,0)">this</span>.<span style="color: rgb(0,102,0)">getClass</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>, <span style="color: rgb(255,0,0)">"/"</span><span style="color: rgb(102,204,102)">)</span>;</pre>
<ul>
    <li>在web项目中根据servlet上下文环境加载模板<br />
    </li>
</ul>
<pre class="java">cfg.<span style="color: rgb(0,102,0)">setServletContextForTemplateLoading</span><span style="color: rgb(102,204,102)">(</span><span style="font-weight: bold; color: rgb(0,0,0)">this</span>.<span style="color: rgb(0,102,0)">getServlet</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>.<span style="color: rgb(0,102,0)">getServletContext</span><span style="color: rgb(102,204,102)">(</span><span style="color: rgb(102,204,102)">)</span>, <span style="color: rgb(255,0,0)">"/"</span><span style="color: rgb(102,204,102)">)</span>;</pre>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/200266.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-05-13 18:40 <a href="http://www.blogjava.net/xyzroundo/articles/200266.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>freemarker 基本指令 </title><link>http://www.blogjava.net/xyzroundo/articles/freemarker.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Tue, 13 May 2008 10:22:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/freemarker.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/200262.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/freemarker.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/200262.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/200262.html</trackback:ping><description><![CDATA[<p>一：if指令：<br />
&lt;#if condition&gt;...<br />
&lt;#elseif condition2&gt;...<br />
&lt;#elseif condition3&gt;...<br />
...&lt;#else&gt;...<br />
&lt;/#if&gt; </p>
<p>二：switch<br />
&lt;#switch value&gt;<br />
&lt;#case refValue1&gt;...&lt;#break&gt;<br />
&lt;#case refValue2&gt;...&lt;#break&gt;...<br />
&lt;#case refValueN&gt;...&lt;#break&gt;<br />
&lt;#default&gt;...&lt;/#switch&gt;</p>
<p>三：list，break<br />
&lt;#list sequence as item&gt;<br />
...<br />
&lt;/#list&gt;<br />
两个特殊的循环变量：<br />
item_index: 当前变量的索引值。<br />
item_has_next: 是否存在下一个对象。</p>
<p>可以用&lt;#break/&gt;指令离开loop循环。</p>
<p>四：include指令<br />
&lt;#include filename&gt;或者<br />
&lt;#include filenameoptions&gt;<br />
filename: 表达式转换为字符串<br />
options: encoding=encoding, parse=parse encoding: 表达式转换为字符串<br />
parse: 表达式转换为逻辑值，是否作为ftl文件解析。<br />
&lt;#include "/common/navbar.html" parse=false encoding="Shift_JIS"&gt;</p>
<p>&lt;#include "*/footer.ftl"&gt;表示当前目录下以及所有父目录下的文件。如果当前模版在/foo/bar/template.ftl ，那么查找footer.ftl的顺序为：/foo/bar/footer.ftl<br />
/foo/footer.ftl/footer.ftl这种方式讲允许设计者将通用的模版放在父文件夹里面。<br />
也可以只指定部分路径：&lt;#include "*/commons/footer.ftl"&gt;</p>
<p>五：import指令&lt;#import path as hash&gt;<br />
六：noparse<br />
&lt;#noparse&gt;<br />
...<br />
&lt;/#noparse&gt;</p>
<p>七：compress<br />
&lt;#compress&gt;<br />
...<br />
&lt;/#compress&gt;<br />
八：escape，noescape<br />
&lt;#escape identifier as expression&gt;<br />
...<br />
&lt;#noescape&gt;...&lt;/#noescape&gt;<br />
...<br />
&lt;/#escape&gt;</p>
<p>escape指令body区的ftl的interpolations都会被自动加上escape表达式。但是不会影响字符串内的interpolations。而且也只会影响到body内出现的interpolations，比如不会影响到include的ftl的interpolations。<br />
&lt;#escape x as x?html&gt;<br />
First name: ${firstName}<br />
Last name: ${lastName}<br />
Maiden name: ${maidenName}&lt;/#escape&gt;<br />
等同于：</p>
<p>First name: ${firstName?html}<br />
Last name: ${lastName?html}<br />
Maiden name: ${maidenName?html}</p>
<p>escape指令在解析模版时起作用，而不是运行时起作用。</p>
<p>escape指令还能嵌套使用，子继承父的escape规则。</p>
<p>&lt;#escape x as x?html&gt;<br />
Customer Name: ${customerName}<br />
Items to ship:<br />
&lt;#escape x as itemCodeToNameMap[x]&gt;<br />
${itemCode1}<br />
${itemCode2}<br />
${itemCode3}<br />
${itemCode4}<br />
&lt;/#escape&gt;&lt;/#escape&gt;<br />
等同于：Customer Name: ${customerName?html}<br />
Items to ship:<br />
${itemCodeToNameMap[itemCode1]?html}<br />
${itemCodeToNameMap[itemCode2]?html}<br />
${itemCodeToNameMap[itemCode3]?html}<br />
${itemCodeToNameMap[itemCode4]?html}</p>
<p>九：assign指令<br />
&lt;#assign name=value&gt;or&lt;#assign name1=value1name2=value2... nameN=valueN&gt;or&lt;#assign same as above... in namespacehash&gt;or&lt;#assign name&gt;&nbsp; capture this&lt;/#assign&gt;or&lt;#assign name in namespacehash&gt;&nbsp; capture this&lt;/#assign&gt;创建或者替换一个已经存在的变量，只能作用于顶层变量。不好的做法：&lt;#assign x&gt;Hello ${user}!&lt;/#assign&gt;更改为：&lt;#assign x="Hello ${user}!"&gt;<br />
十：global指令<br />
&lt;#global name=value&gt;<br />
or<br />
&lt;#global name1=value1name2=value2... nameN=valueN&gt;or&lt;#global name&gt;<br />
capture this<br />
&lt;/#global&gt;<br />
十一：local指令<br />
&lt;#local name=value&gt;<br />
or<br />
&lt;#local name1=value1name2=value2... nameN=valueN&gt;or&lt;#local name&gt;<br />
capture this<br />
&lt;/#local&gt;只能用于macro的定义body中。</p>
<p><br />
十二：setting指令：</p>
<p>&lt;#setting name=value&gt;<br />
name的取值范围：<br />
local：number_format：<br />
boolean_format:缺省值为"true,false"<br />
date_format, time_format, datetime_format<br />
time_zone：url_escaping_charset<br />
classic_compatible</p>
<p>十三：用户自定义指令<br />
&lt;@macro_or_transfparam1=val1param2=val2...paramN=valN/&gt;&lt;@macro_or_transfparam1=val1param2=val2...paramN=valN ; lv1, lv2, ..., lvN/&gt;&lt;@macro_or_transf...&gt;&nbsp; ...&lt;<a>/@macro_or_transf&gt;&lt;@macro_or_transf</a>...&gt;&nbsp; ...&lt;<a>/@&gt;&lt;@macro_or_transfval1</a>, val2, ..., valN/&gt;<br />
十四：macro,nested,return<br />
&lt;#macro nameparam1param2... paramN&gt;<br />
...<br />
&lt;#nested loopvar1, loopvar2, ..., loopvarN&gt;<br />
...<br />
&lt;#return&gt;<br />
...<br />
&lt;/#macro&gt;</p>
<p>十五：function, return<br />
&lt;#function nameparam1param2... paramN&gt;<br />
... &lt;#return returnValue&gt;<br />
...<br />
&lt;/#function&gt;</p>
<p>&lt;#function avg x y&gt;<br />
&lt;#return (x + y) / 2&gt;<br />
&lt;/#function&gt;<br />
${avg(10, 20)}</p>
<p>十六：flush<br />
&lt;#flush&gt;</p>
<p>十七：stop<br />
&lt;#stop&gt;<br />
or<br />
&lt;#stop reason&gt;取消处理模版。</p>
<p>十八：ftl指令<br />
&lt;#ftl param1=value1param2=value2...paramN=valueN&gt;<br />
ftl指令必须放在ftl文件的最上面。</p>
<p>参数范围：<br />
encoding：<br />
strip_whitespace<br />
strip_text<br />
strict_syntax</p>
<p>十九：t, lt, rt<br />
二十：attempt, recover<br />
&lt;#attempt&gt;<br />
attempt block&lt;#recover&gt; <br />
recover block<br />
&lt;/#attempt&gt;</p>
<p>&lt;#attempt&gt;<br />
Optional content: ${thisMayFails}<br />
&lt;#recover&gt;<br />
Ops! The optional content is not available.<br />
&lt;/#attempt&gt;</p>
 <img src ="http://www.blogjava.net/xyzroundo/aggbug/200262.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-05-13 18:22 <a href="http://www.blogjava.net/xyzroundo/articles/freemarker.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习FreeMarker（一） </title><link>http://www.blogjava.net/xyzroundo/articles/200112.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Mon, 12 May 2008 15:51:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/200112.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/200112.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/200112.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/200112.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/200112.html</trackback:ping><description><![CDATA[<div class="postTitle">来源：http://www.blogjava.net/pepsixp/archive/2005/03/11/1685.html<br />
FreeMarker是一个用Java编写的模板引擎，主要用来生成HTML Web页面，特别是基于MVC模式的应用程序。虽然FreeMarker具有一些编程的能力，但不像PHP，通常由Java程序准备要显示的数据，由FreeMarker模板生成页面。&nbsp; FreeMarker可以作为Web应用框架一个组件，但它与容器无关，在非Web应用程序环境也能工作的很好。 FreeMarker适合作为MVC的视图组件，还能在模板中使用JSP标记库。</div>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">html</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">head</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">title</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">Welcome!</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">title</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">head</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">body</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">h1</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">Welcome&nbsp;${user}!</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">h1</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">p</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">Our&nbsp;latest&nbsp;product:<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">a&nbsp;</span><span style="color: #ff0000">href</span><span style="color: #0000ff">="${latestProduct.url}"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">${latestProduct.name}</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">a</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">!<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">body</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">html</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
</div>
<p>上面的例子中，在简单的HTML中加入了一些由${&#8230;}包围的特定FreeMarker的指令，这个文件就称为模板了。而user、latestProduct.url和latestProduct.name来自于数据模型，由Java程序提供，模板设计者就不用关心数据从哪来的。</p>
<p>FreeMarker模板中可以包括下面四种特定部分：<br />
一.) <strong>文本</strong>：直接输出<br />
二.) <strong>FTL标记</strong>(FreeMarker模板语言标记)：类似于HTML标记，名字前加#(有些以@开始，用户自定义标记)予以区分，不会输出。<br />
<strong>字符串</strong>－ 使用单引号或双引号限定；如果包含特殊字符需要转义符：${"It's \"quoted\" andthis is a backslash: \\"}<br />
有一类特殊的字符串:${r"C:\foo\bar"}，输出结构为：C:\foo\bar，在引号前面加r被认为是纯文本。 <br />
数字－直接输入，不需要引号。${08}, ${+8}, ${8.00} and ${8} 都是相同的 <br />
<strong>布尔值</strong>－true和false，不使用引号<br />
<strong>Sequences(序列)</strong>－由逗号分隔的变量列表，由方括号限定，类似java中的一维数组：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">#list&nbsp;</span><span style="color: #ff0000"><font color="#000000">["winter",&nbsp;"spring",&nbsp;"summer",&nbsp;"autumn"]&nbsp;as&nbsp;x</font></span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />${x}<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">#list</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
</div>
<p>输出结果：<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />winter<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />spring<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />summer<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />autumn<br />
<br />
例二：[2 + 2, [1, 2, 3, 4], "whatnot"]<br />
例三：2..5，等同于[2, 3, 4, 5]；5..2，等同于[5,4,3,2]。注意方括号是不需要的。<br />
<br />
<strong>Hashes(散列)</strong>－由逗号分隔的键-值列表，由大括号限定，键和值之间用冒号分隔：{"name":"green mouse", "price":150}，键和值都是表达式，但是键必须是字符串。</p>
<p><strong>获取变量</strong>－${variable}，变量名只能是字母、数字、下划线、$、@和#的组合，且不能以数字开头。下列表达式是等价的：<br />
book.author.name<br />
book["author"].name<br />
book.author.["name"]<br />
book["author"]["name"]<br />
<br />
获取Sequence(序列)片断－使用[startindex..endindex]，例如：seq中存储了"a", "b", "c", "d","e"，那么seq[1..2]包含了b和c两个值。<br />
<br />
可以使用.variablename语法访问FreeMarker内置变量。</p>
<p><strong>字符串操作</strong><br />
{"Hello ${user}!"} &lt;==&gt; ${"Hello " + user + "!"}<br />
${"${user}${user}${user}${user}"} &lt;==&gt; ${user + user + user + user}</p>
<p>${&#8230;}只能在文本中使用，下面是错误的代码：<br />
&lt;#if ${isBig}&gt;Wow!&lt;/#if&gt; <br />
&lt;#if "${isBig}"&gt;Wow!&lt;/#if&gt;&nbsp; //此处的代码也是错误的，因为if指令需要的是boolean，实际的却是个字符串</p>
<p>子字符串的操作，假设user的值为"Big Joe"：<br />
${user[0]}${user[4]}&nbsp; &lt;==&gt;&nbsp; BJ<br />
${user[1..4]}&nbsp; &lt;==&gt; ig J </p>
<p><strong>Sequences(序列)操作</strong></p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">#list&nbsp;</span><span style="color: #ff0000"><font color="#000000">["Joe",&nbsp;"Fred"]&nbsp;+&nbsp;["Julia",&nbsp;"Kate"]&nbsp;as&nbsp;user</font></span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />-&nbsp;${user}<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">#list</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
</div>
<p>结果：<br />
- Joe<br />
- Fred<br />
- Julia<br />
- Kate</p>
<p><strong>Hashes(散列)操作</strong></p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><strong><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /></strong><span style="color: #0000ff">&lt;</span><span style="color: #800000">#assign&nbsp;</span><span style="color: #ff0000"><font color="#000000">ages</font>&nbsp;</span><span style="color: #0000ff">=&nbsp;<font color="#000000">{"Joe":23,&nbsp;</font></span><span style="color: #ff0000"><font color="#000000">"Fred":25}&nbsp;+&nbsp;{"Joe":30,&nbsp;"Julia":18}</font></span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />-&nbsp;Joe&nbsp;is&nbsp;${ages.Joe}<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />-&nbsp;Fred&nbsp;is&nbsp;${ages.Fred}<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />-&nbsp;Julia&nbsp;is&nbsp;${ages.Julia}&nbsp;&nbsp;</span></div>
</div>
<p>结果：<br />
- Joe is 30<br />
- Fred is 25<br />
- Julia is 18&nbsp; </p>
<p><strong>算术运算</strong></p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><strong><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /></strong><span style="color: #0000ff">&lt;</span><span style="color: #800000">#--&nbsp;</span><span style="color: #ff0000"><font color="#000000">x的值设定为5</font>&nbsp;--</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />${x&nbsp;*&nbsp;x&nbsp;-&nbsp;100}<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />${x&nbsp;/&nbsp;2}<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />${12&nbsp;%&nbsp;10}</span></div>
</div>
<p>结果：<br />
-75<br />
2.5<br />
2 <br />
<br />
注意： 操作符两边必须是数字；使用"+"时，如果一边是数字，一边是字符串，就会自动将数字转换为字符串。<br />
<br />
使用内建的指令int<strong>获得整数部分</strong>：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div>${(x/2)?int}<br />
${1.1?int}<br />
${1.999?int}<br />
${-1.1?int}<br />
${-1.999?int}</div>
</div>
<p>结果：<br />
2<br />
1<br />
1<br />
-1<br />
-1</p>
<p><strong>比较操作符</strong>－&lt;#if expression&gt;...&lt;/#if&gt;<br />
1.)使用=（或==，完全相等）测试两个值是否相等，使用!= 测试两个值是否不相等<br />
2.)=和!=两边必须是相同类型的值，否则会产生错误，例如&lt;#if 1 = "1"&gt;会引起错误<br />
3.)Freemarker是精确比较，所以"x"、"x&nbsp; "和"X"是不相等的<br />
4.)对数字和日期可以使用&lt;、&lt;=、&gt;和&gt;=，但不能用于字符串<br />
5.)由于Freemarker会将&gt;解释成FTL标记的结束字符，所以对于&gt;和&gt;=可以使用括号来避免这种情况，例如&lt;#if (x &gt; y)&gt;，另一种替代的方法是，使用lt、lte、gt和gte来替代&lt;、&lt;=、&gt;和&gt;=</p>
<p><strong>逻辑操作符</strong>－&amp;&amp;(and)、||(or)、!(not)，只能用于布尔值，否则会产生错误<br />
&lt;#if x &lt; 12 &amp;&amp; color = "green"&gt;<br />
&nbsp; We have less than 12 things, and they are green.<br />
&lt;/#if&gt;<br />
&lt;#if !hot&gt; &lt;#-- here hot must be a boolean --&gt;<br />
&nbsp; It's not hot.<br />
&lt;/#if&gt;&nbsp; </p>
<p><strong>内置函数</strong>－用法类似访问hash(散列)的子变量，只是使用"?"替代"."，例如：user?upper_case<br />
下面列出常用的一些函数：<br />
<u>对于字符串</u><br />
html－对字符串进行HTML编码<br />
cap_first－使字符串第一个字母大写<br />
lower_case－将字符串转换成小写<br />
trim－去掉字符串前后的空白字符<br />
<u>对于Sequences(序列)<br />
</u>size－获得序列中元素的数目<br />
<u>对于数字<br />
</u>int－取得数字的整数部分（如-1.9?int的结果是-1）<br />
<br />
例一：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">#--&nbsp;</span><span style="color: #ff0000"><font color="#000000">test的值为Tom&nbsp;&amp;&nbsp;Jerry</font>&nbsp;--</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />${test?html}<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />${test?upper_case?html}</span></div>
</div>
<p>结果：<br />
Tom &amp;amp; Jerry<br />
TOM &amp;amp; JERRY <br />
<br />
例二：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">#--&nbsp;</span><span style="color: #ff0000"><font color="#000000">seasons的值为"winter",&nbsp;"spring",&nbsp;"summer",&nbsp;"autumn"</font>&nbsp;--</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />${seasons?size}<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />${seasons[1]?cap_first}&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">#--&nbsp;</span><span style="color: #ff0000"><font color="#000000">left&nbsp;side&nbsp;can&nbsp;by&nbsp;any&nbsp;expression</font>&nbsp;--</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />${"horse"?cap_first}&nbsp;&nbsp;</span></div>
</div>
<p>结果：<br />
4<br />
Spring<br />
Horse&nbsp; </p>
<p><strong>方法的调用</strong><br />
${repeat("What", 3)} <br />
${repeat(repeat("x", 2), 3) + repeat("What", 4)?upper_case} <br />
结果：<br />
WhatWhatWhat<br />
xxxxxxWHATWHATWHATWHAT </p>
<p><strong>操作符优先顺序</strong><br />
后缀&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [subvarName] [subStringRange] . (methodParams)<br />
一元&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +expr、-expr、!<br />
内建&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;?<br />
乘法&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; *、 / 、%<br />
加法&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; +、-<br />
关系&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&lt;、&gt;、&lt;=、&gt;=（lt、lte、gt、gte）<br />
相等&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; =、!=<br />
逻辑&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &amp;&amp;<br />
逻辑&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;||<br />
数字范围&nbsp;&nbsp; &nbsp;&nbsp; ..</p>
<p>三.) <strong>Interpolation</strong>：由${...}或#{...}两种类型，输出计算值，可以定义输出的格式<br />
例一：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">#setting&nbsp;</span><span style="color: #ff0000">number_format</span><span style="color: #0000ff">="currency"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">#assign&nbsp;</span><span style="color: #ff0000">answer</span><span style="color: #0000ff">=42/&gt;<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #ff0000"><font color="#000000">${answer}<br />
</font><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /><font color="#000000">${answer?string}</font>&nbsp;&nbsp;<font color="#000000">&lt;#--&nbsp;the&nbsp;same&nbsp;as&nbsp;${answer}&nbsp;--</font></span><span style="color: #0000ff"><font color="#000000">&gt;</font></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />${answer?string.number}<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />${answer?string.currency}<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />${answer?string.percent}&nbsp;</span></div>
</div>
<p>结果：<br />
$42.00<br />
$42.00<br />
42<br />
$42.00<br />
4,200%</p>
<p>例二：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">${lastUpdated?string("yyyy-MM-dd&nbsp;HH:mm:ss&nbsp;zzzz")}<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />${lastUpdated?string("EEE,&nbsp;MMM&nbsp;d,&nbsp;''yy")}<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />${lastUpdated?string("EEEE,&nbsp;MMMM&nbsp;dd,&nbsp;yyyy,&nbsp;hh:mm:ss&nbsp;a&nbsp;'('zzz')'")}&nbsp;&nbsp;</span></div>
</div>
<p>结果：<br />
2003-04-08 21:24:44 Pacific Daylight Time<br />
Tue, Apr 8, '03<br />
Tuesday, April 08, 2003, 09:24:44 PM (PDT)</p>
<p>例三：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">#assign&nbsp;</span><span style="color: #ff0000">foo</span><span style="color: #0000ff">=true/&gt;<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #ff0000"><font color="#000000">${foo?string("yes",&nbsp;"no")}</font></span></div>
</div>
<p>结果：<br />
yes</p>
<p>例四：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">#--&nbsp;</span><span style="color: #ff0000"><font color="#000000">x&nbsp;is&nbsp;2.582&nbsp;and&nbsp;y&nbsp;is&nbsp;4</font>&nbsp;--</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />#{x;&nbsp;M2}&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">#--<font color="#0000ff">&nbsp;</font></span><span style="color: #ff0000"><font color="#0000ff">2.58</font>&nbsp;--</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />#{y;&nbsp;M2}&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">#--&nbsp;</span><span style="color: #ff0000"><font color="#0000ff">4&nbsp;</font>&nbsp;&nbsp;&nbsp;--</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />#{x;&nbsp;m1}&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">#--&nbsp;</span><span style="color: #ff0000"><font color="#0000ff">2.6</font>&nbsp;--</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />#{y;&nbsp;m1}&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">#--&nbsp;</span><span style="color: #ff0000"><font color="#0000ff">4.0</font>&nbsp;--</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />#{x;&nbsp;m1M2}&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">#--&nbsp;</span><span style="color: #ff0000"><font color="#0000ff">2.58</font>&nbsp;--</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />#{y;&nbsp;m1M2}&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">#--&nbsp;</span><span style="color: #ff0000"><font color="#0000ff">4.0</font>&nbsp;&nbsp;--</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;&nbsp;</span></div>
</div>
<p>说明：mX－小数部分最小X位；MX－小数部分最大X位。</p>
<p>四.) <strong>注释</strong>：&lt;#--和--&gt; </p>
<p>下面是一个常用的模板例子：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">p</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">We&nbsp;have&nbsp;these&nbsp;animals:<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">table&nbsp;</span><span style="color: #ff0000">border</span><span style="color: #0000ff">=1&gt;<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #ff0000">&lt;tr</span><span style="color: #0000ff">&gt;&lt;</span><span style="color: #800000">th</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">Name</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">th</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">Price<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">#list&nbsp;</span><span style="color: #ff0000">animals&nbsp;as&nbsp;being</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">tr</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">td</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">#if&nbsp;</span><span style="color: #ff0000">being.size&nbsp;</span><span style="color: #0000ff">=&nbsp;"large"</span><span style="color: #0000ff">&gt;&lt;</span><span style="color: #800000">b</span><span style="color: #0000ff">&gt;&lt;/</span><span style="color: #800000">#if</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${being.name}<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">#if&nbsp;</span><span style="color: #ff0000">being.size</span><span style="color: #0000ff">="large"</span><span style="color: #0000ff">&gt;&lt;/</span><span style="color: #800000">b</span><span style="color: #0000ff">&gt;&lt;/</span><span style="color: #800000">#if</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">td</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">${being.price}&nbsp;Euros<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">#list</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">table</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">#include&nbsp;</span><span style="color: #ff0000">"/copyright_footer.html"</span><span style="color: #0000ff">&gt;</span></div>
</div>
<p><strong>注意点</strong>：<br />
1.) FreeMarker是区分大小写的；<br />
2.) FTL标记不能位于另一个FTL标记内部，例如：&lt;#if &lt;#include 'foo'&gt;='bar'&gt;...&lt;/if&gt;；<br />
3.) ${&#8230;}只能在文本中使用；<br />
4.) 多余的空白字符会在模板输出时去除；<br />
5.) 如果使用的指令不存在，会产生一个错误消息。</p>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/200112.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-05-12 23:51 <a href="http://www.blogjava.net/xyzroundo/articles/200112.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>acegi初体验</title><link>http://www.blogjava.net/xyzroundo/articles/194566.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Mon, 21 Apr 2008 09:57:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/194566.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/194566.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/194566.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/194566.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/194566.html</trackback:ping><description><![CDATA[来源：http://www.blogjava.net/baputista<br />
还以我传统的例子为例:<br />
毕业设计选题系统,三种角色:教师,学生,管理员,我想让他们的登陆都在一个界面下自动识别,而无需进行身份选择,登陆后,他们将分别到各自的admin.jsp,stu.jsp,teacher.jsp<br />
在数据库中的表结构如下(很多属性略):<br />
id--- user---password--type---about<br />
<br />
type是用来存储用户的类别,分别有a,t,s分别对应三种角色<br />
about对应的是acegi里所需要的enable,用户是否可用
<p>在model里,我们采用了继承关系:<br />
<br />
父类user:<br />
package subject.model;</p>
<p>public abstract class User extends BaseObject<br />
{<br />
&nbsp;private Integer id;<br />
&nbsp;private String user;<br />
&nbsp;private String password;<br />
&nbsp;private String name;<br />
&nbsp;private String telphone;</p>
<p>//set and get method&nbsp;<br />
&nbsp;<br />
&nbsp;public abstract String getType(); //这个是用来反映用户角色的关键函数,在子类实现,从而实现多态<br />
}<br />
<br />
子类的实现:<br />
======================<br />
package subject.model;</p>
<p>import subject.Constants;</p>
<p>public class Teacher extends User<br />
{<br />
&nbsp;private String level;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //教师的职称<br />
<br />
//set and get method</p>
<p>&nbsp;public String getType()<br />
&nbsp;{<br />
&nbsp;&nbsp;return Constants.TEACHER;<br />
&nbsp;}<br />
}<br />
================<br />
package subject.model;</p>
<p>import subject.Constants;</p>
<p>public class Student extends User<br />
{<br />
&nbsp;private static final long serialVersionUID = 1L;</p>
<p>&nbsp;private SchoolClass schoolClass;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //学生的班级<br />
&nbsp;private String sn;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //学生的学号</p>
<p>//set and get method<br />
&nbsp;<br />
&nbsp;public String getType()<br />
&nbsp;{<br />
&nbsp;&nbsp;return Constants.STUDENT;<br />
&nbsp;}<br />
}<br />
=================<br />
package subject.model;</p>
<p>import subject.Constants;</p>
<p>public class Admin extends User<br />
{<br />
&nbsp;private String grade;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //管理员的级别<br />
//set and get method</p>
<p>&nbsp;public String getType()<br />
&nbsp;{<br />
&nbsp;&nbsp;return Constants.ADMIN;<br />
&nbsp;}<br />
}<br />
<br />
对于三者所共有的属性在数据库里,都存在一个字段,而依据不同的角色拥有不同的含义,学生的班级则存放在了about里,只要学生有班级,他就able,否则就enable了!而管理员和教师则默认为1!<br />
<br />
这种是属于一个继承树存放在一个表的情况,Hibernate的配置如下:<br />
&lt;hibernate-mapping&gt;</p>
<p>&nbsp;&lt;class name="subject.model.User" discriminator-value="not null"&gt;</p>
<p>&nbsp;&nbsp;&lt;id name="id"&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;generator class="increment" /&gt;<br />
&nbsp;&nbsp;&lt;/id&gt;<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&lt;discriminator column="type" type="character" /&gt;<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&lt;property name="user" /&gt;<br />
&nbsp;&nbsp;&lt;property name="password" /&gt;<br />
&nbsp;&nbsp;&lt;property name="name" /&gt;<br />
&nbsp;&nbsp;&lt;property name="telphone" /&gt;</p>
<p>&nbsp;&nbsp;&lt;subclass name="subject.model.Admin" discriminator-value="a"&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;property name="grade" column="sn" /&gt;<br />
&nbsp;&nbsp;&lt;/subclass&gt;<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&lt;subclass name="subject.model.Teacher" discriminator-value="t"&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;property name="level" column="sn" /&gt;<br />
&nbsp;&nbsp;&lt;/subclass&gt;<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&lt;subclass name="subject.model.Student" discriminator-value="s"&gt;<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&lt;property name="sn" /&gt;<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&lt;many-to-one name="schoolClass" class="subject.model.SchoolClass" <br />
&nbsp;&nbsp;&nbsp;&nbsp;column="about" update="false" insert="false" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&lt;/subclass&gt;</p>
<p>&nbsp;&lt;/class&gt;</p>
<p>&lt;/hibernate-mapping&gt;<br />
<br />
=============================================<br />
上面的这些都是模型的基础,下面再讲怎么样配合Spring和Acegi实现系统的安全与登陆<br />
在Spring中Hibernate的配置只介绍不说明:<br />
&lt;!-- 定义DBCP数据源 --&gt;<br />
&nbsp;&lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"&gt;<br />
&nbsp;&nbsp;&lt;property name="driverClassName" value="com.mysql.jdbc.Driver" /&gt;<br />
&nbsp;&nbsp;&lt;property name="url" value="jdbc:mysql://localhost/subject?useUnicode=true&amp;amp;characterEncoding=gbk" /&gt;<br />
&nbsp;&nbsp;&lt;property name="username" value="root" /&gt;<br />
&nbsp;&nbsp;&lt;property name="password" value="" /&gt;<br />
&nbsp;&nbsp;&lt;property name="maxActive" value="100" /&gt;<br />
&nbsp;&nbsp;&lt;property name="maxIdle" value="30" /&gt;<br />
&nbsp;&nbsp;&lt;property name="maxWait" value="1000" /&gt;<br />
&nbsp;&nbsp;&lt;property name="defaultAutoCommit" value="true" /&gt;<br />
&nbsp;&nbsp;&lt;property name="removeAbandoned" value="true" /&gt;<br />
&nbsp;&nbsp;&lt;property name="removeAbandonedTimeout" value="60" /&gt;<br />
&nbsp;&lt;/bean&gt;</p>
<p>&nbsp;&lt;!-- Hibernate --&gt;<br />
&nbsp;&lt;bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"&gt;<br />
&nbsp;&nbsp;&lt;property name="dataSource" ref="dataSource" /&gt;<br />
&nbsp;&nbsp;&lt;property name="mappingResources"&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;list&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;subject/model/User.hbm.xml&lt;/value&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;/list&gt;<br />
&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&nbsp;&lt;property name="hibernateProperties"&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;props&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="hibernate.dialect"&gt;org.hibernate.dialect.MySQLInnoDBDialect&lt;/prop&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;/props&gt;<br />
&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&lt;/bean&gt;</p>
<p>&nbsp;&lt;bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"&gt;<br />
&nbsp;&nbsp;&lt;property name="sessionFactory" ref="sessionFactory" /&gt;<br />
&nbsp;&lt;/bean&gt;<br />
<br />
&lt;!-- Dao对象 --&gt;<br />
&lt;bean id="userDao" class="subject.dao.hibernate.UserDaoImpl"&gt;<br />
&nbsp;&nbsp;&lt;property name="sessionFactory" ref="sessionFactory" /&gt;<br />
&nbsp;&lt;/bean&gt;<br />
<br />
&lt;!-- 业务逻辑 --&gt;<br />
&nbsp;&lt;bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"&gt;<br />
&nbsp;&nbsp;&lt;property name="transactionManager" ref="transactionManager" /&gt;<br />
&nbsp;&nbsp;&lt;property name="transactionAttributes"&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;props&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="save*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="remove*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="get*"&gt;PROPAGATION_REQUIRED,readOnly&lt;/prop&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;/props&gt;<br />
&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&lt;/bean&gt;<br />
<br />
&lt;bean id="userManager" parent="txProxyTemplate"&gt;<br />
&nbsp;&nbsp;&lt;property name="target"&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;bean class="subject.service.impl.UserManagerImpl"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="userDao" ref="userDao" /&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;/bean&gt;<br />
&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&lt;/bean&gt;<br />
<br />
&lt;!-- Struts --&gt;<br />
&nbsp;&lt;bean name="/user" class="subject.web.action.UserAction" singleton="false"&gt;<br />
&nbsp;&nbsp;&lt;property name="userManager"&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;ref bean="userManager" /&gt;<br />
&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&lt;/bean&gt;<br />
==================<br />
上面具体的不用了解,无非就是调用和数据库的操作,<br />
下面就要对Acegi进行声明了:<br />
我不用Ctrl+c和Ctrl+V的方式对Acegi进行介绍,没有意义,随便google就一大堆<br />
我们想主要在这样的系统中需要的安全策略都有哪些?<br />
1.用户的登陆<br />
2.防止多个用户登陆一个帐号<br />
3.用户的注销<br />
4.防止非法用户的访问<br />
<br />
我这个程序所涉及到的只有这些,下面就进行说明:<br />
<br />
在web.xml的声明:<br />
&lt;!-- Acegi安全控制 Filter 配置 --&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;filter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;securityFilter&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-class&gt;org.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;init-param&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;targetClass&lt;/param-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;org.acegisecurity.util.FilterChainProxy&lt;/param-value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/init-param&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/filter&gt;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;filter-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;securityFilter&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/filter-mapping&gt;<br />
<br />
Acegi通过实现了Filter接口的FilterToBeanProxy提供一种特殊的使用Servlet Filter的方式，它委托Spring中的Bean -- FilterChainProxy来完成过滤功能，这样就简化了web.xml的配置，并且利用Spring IOC的优势。FilterChainProxy包含了处理认证过程的filter列表，每个filter都有各自的功能。<br />
<br />
&lt;!-- ======================== FILTER CHAIN ======================= --&gt;<br />
&nbsp;&lt;bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy"&gt;<br />
&nbsp;&nbsp;&lt;property name="filterInvocationDefinitionSource"&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON <br />
&nbsp;&nbsp;&nbsp;&nbsp;PATTERN_TYPE_APACHE_ANT<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;/**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;securityContextHolderAwareRequestFilter,exceptionTranslationFilter,filterInvocationInterceptor<br />
&nbsp;&nbsp;&nbsp;&lt;/value&gt;<br />
&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&lt;/bean&gt;<br />
<br />
大体上先介绍一下:<br />
httpSessionContextIntegrationFilter:每次request前 HttpSessionContextIntegrationFilter从Session中获取Authentication对象，在request完后, 又把Authentication对象保存到Session中供下次request使用,此filter必须其他Acegi filter前使用，使之能跨越多个请求。<br />
logoutFilter:用户的注销<br />
authenticationProcessingFilter:处理登陆请求<br />
exceptionTranslationFilter:异常转换过滤器<br />
filterInvocationInterceptor:在访问前进行权限检查<br />
<br />
这些就犹如在web.xml声明一系列的过滤器,不过当把他们都声明在spring中就可以享受Spring给我们带来的方便了。<br />
<br />
下面就是对这些过滤器的具体声明：<br />
只对有用的地方进行声明，别的地方几乎都是默许的<br />
&lt;!-- ======================== FILTER ======================= --&gt;<br />
&nbsp;&lt;bean id="httpSessionContextIntegrationFilter" <br />
&nbsp;&nbsp;class="org.acegisecurity.context.HttpSessionContextIntegrationFilter" /&gt;</p>
<p>&nbsp;&lt;bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter"&gt;<br />
&nbsp;&nbsp;&lt;constructor-arg value="/index.htm" /&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 离开后所转向的位置<br />
&nbsp;&nbsp;&lt;constructor-arg&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;list&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/list&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/constructor-arg&gt;<br />
&nbsp;&nbsp;&lt;property name="filterProcessesUrl" value="/logout.htm" /&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 定义用户注销的地址，<br />
&nbsp;&lt;/bean&gt;<br />
<br />
下面的这个过滤器，我们根据自己的需求有了自己的实现：</p>
<p>&nbsp;&lt;bean id="authenticationProcessingFilter" class="subject.web.filter.UserAuthenticationProcessingFilter"&gt;<br />
&nbsp;&nbsp;&lt;property name="authenticationManager" ref="authenticationManager"/&gt;&nbsp;&nbsp;下面会介绍的用来起到认证管理的作用<br />
&nbsp;&nbsp;&lt;property name="authenticationFailureUrl" value="/login.htm?error=wrong"/&gt;&nbsp; 登陆失败的地址<br />
&nbsp;&nbsp;&lt;property name="defaultTargetUrl" value="/login.htm"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 登陆成功的地址<br />
&nbsp;&nbsp;&lt;property name="filterProcessesUrl" value="/j_security_check"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 登陆请求的地址<br />
&nbsp;&nbsp;&lt;property name="userManager" ref="userManager"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 自己添加的属性，这样就可以访问到我们的业务逻辑<br />
&nbsp;&nbsp;&lt;property name="exceptionMappings"&gt;&nbsp;&nbsp; 出现异常所对应的地址<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; org.acegisecurity.AuthenticationException=/login.htm?error=fail&nbsp;&nbsp;&nbsp;&nbsp; 登陆失败&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; org.acegisecurity.concurrent.ConcurrentLoginException=/login.htm?error=too&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 已登陆了<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br />
&nbsp;&lt;/bean&gt;<br />
&nbsp;<br />
&nbsp;&lt;bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/&gt;</p>
<p>&nbsp;&lt;bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter"&gt;<br />
&nbsp;&nbsp;&lt;property name="authenticationEntryPoint"&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="loginFormUrl" value="/login.htm?error=please"/&gt;//如果用户没登陆就想访问，先到这里登陆吧<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="forceHttps" value="false"/&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;/bean&gt;<br />
&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&lt;/bean&gt;<br />
&nbsp;<br />
&nbsp;&lt;bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor"&gt;<br />
&nbsp;&nbsp;&lt;property name="authenticationManager" ref="authenticationManager"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;认证服务<br />
&nbsp;&nbsp;&lt;property name="accessDecisionManager"&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;bean class="org.acegisecurity.vote.AffirmativeBased"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="allowIfAllAbstainDecisions" value="false"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="decisionVoters"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;list&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean class="org.acegisecurity.vote.RoleVoter"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="rolePrefix" value=""/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //这里定义数据库中存放的角色和我们在这里声明的角色间是否需要加个前缀？我没加<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/list&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;/bean&gt;<br />
&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&nbsp;&lt;property name="objectDefinitionSource"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PATTERN_TYPE_APACHE_ANT<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /admin.htm*=a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这里就是数据库中对应的tyep a<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /student*=s&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 由于没有前缀和数据库里一样<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /teacher*=t<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br />
&nbsp;&lt;/bean&gt;<br />
&nbsp;<br />
&nbsp;&lt;bean id="loggerListener"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.acegisecurity.event.authentication.LoggerListener"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 记录事件<br />
<br />
下面就要说明我们的认证服务了，其起到的关键作用就是用来保证用户登陆身份的验证：<br />
<br />
它将验证的功能委托给多个Provider，并通过遍历Providers, 以保证获取不同来源的身份认证，若某个Provider能成功确认当前用户的身份，authenticate()方法会返回一个完整的包含用户授权信息的Authentication对象，否则会抛出一个AuthenticationException。<br />
<br />
先声明一个管理器吧，在上面的过滤器中都已经用到过了<br />
&lt;!-- ======================== AUTHENTICATION ======================= --&gt;<br />
&nbsp;&lt;bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager"&gt;<br />
&nbsp;&nbsp;&lt;property name="providers"&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;list&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;ref local="daoAuthenticationProvider" /&gt;&nbsp;&nbsp;&nbsp;我仅仅用到 从数据库中读取用户信息验证身份<br />
&nbsp;&nbsp;&nbsp;&lt;/list&gt;<br />
&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&nbsp;&lt;property name="sessionController"&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;bean id="concurrentSessionController" <br />
&nbsp;&nbsp;&nbsp;&nbsp;class="org.acegisecurity.concurrent.ConcurrentSessionControllerImpl"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="maximumSessions"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;1&lt;/value&gt;每个用户同时登陆一位<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="sessionRegistry"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean id="sessionRegistry" class="org.acegisecurity.concurrent.SessionRegistryImpl" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="exceptionIfMaximumExceeded" value="true" /&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;/bean&gt;<br />
&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&lt;/bean&gt;<br />
&nbsp;来实现唯一的一个Provider，从数据库验证身份<br />
&nbsp;&lt;bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider"&gt;<br />
&nbsp;&nbsp;&lt;property name="userDetailsService"&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;bean id="jdbcDaoImpl"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="dataSource" ref="dataSource"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="usersByUsernameQuery"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select user,password,about from user where user = ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查找用户的查询语句，只需要把你数据库中的用户和密码以及enable相对应上就行<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="authoritiesByUsernameQuery"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select user,type from user where user = ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这里就是把用户和权限对应上，在appfuse中用的两个表，我都放一个表里了，所以就用这一个就行问题的关键是要让它能找到两个字段，构成一个对象<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />
&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&nbsp;&lt;property name="userCache"&gt; 缓存都这么写：<br />
&nbsp;&nbsp;&nbsp;&lt;bean class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="cache"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean class="org.springframework.cache.ehcache.EhCacheFactoryBean"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="cacheManager"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="cacheName" value="userCache"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/bean&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;/bean&gt;<br />
&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&lt;/bean&gt;<br />
<br />
==============<br />
对于上面登陆请求的处理器我借鉴了springSide，实现的方法如下：<br />
package subject.web.filter;</p>
<p>import javax.servlet.http.HttpServletRequest;<br />
import javax.servlet.http.HttpServletResponse;<br />
import javax.servlet.http.HttpSession;</p>
<p>import org.acegisecurity.Authentication;<br />
import org.acegisecurity.context.SecurityContext;<br />
import org.acegisecurity.context.SecurityContextHolder;<br />
import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter;<br />
import org.acegisecurity.userdetails.UserDetails;</p>
<p>import subject.Constants;<br />
import subject.model.User;<br />
import subject.service.UserManager;</p>
<p>public class UserAuthenticationProcessingFilter extends<br />
&nbsp;&nbsp;AuthenticationProcessingFilter<br />
{<br />
&nbsp;private UserManager userManager;</p>
<p>&nbsp;public void setUserManager( UserManager userManager )<br />
&nbsp;{<br />
&nbsp;&nbsp;this.userManager = userManager;<br />
&nbsp;}</p>
<p>&nbsp;protected boolean requiresAuthentication( HttpServletRequest request ,<br />
&nbsp;&nbsp;&nbsp;HttpServletResponse response )<br />
&nbsp;{<br />
&nbsp;&nbsp;boolean requiresAuth = super.requiresAuthentication( request, response );<br />
&nbsp;&nbsp;HttpSession httpSession = null;<br />
&nbsp;&nbsp;try<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;httpSession = request.getSession( false );<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;catch ( IllegalStateException ignored )<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;if ( httpSession != null )<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;if ( httpSession.getAttribute( Constants.USER ) == null )<br />
&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;if ( !requiresAuth )<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SecurityContext sc = SecurityContextHolder.getContext();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Authentication auth = sc.getAuthentication();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( auth != null<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp; auth.getPrincipal() instanceof UserDetails )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UserDetails ud = (UserDetails) auth.getPrincipal();//上面声明的sql无非就是要包装成这个对象<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User user = userManager.getUser( ud.getUsername() );从业务逻辑里找到用户，放到session里<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;httpSession.setAttribute( Constants.USER, user );<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;return requiresAuth;<br />
&nbsp;}<br />
}<br />
<br />
在看看我的login.htm在登陆成功时是怎么工作的吧？<br />
public class UserAction extends BaseAction<br />
{<br />
&nbsp;private UserManager mgr;</p>
<p>&nbsp;public void setUserManager( UserManager mgr )<br />
&nbsp;{<br />
&nbsp;&nbsp;this.mgr = mgr;<br />
&nbsp;}</p>
<p>&nbsp;public ActionForward login( ActionMapping mapping , ActionForm form ,<br />
&nbsp;&nbsp;&nbsp;HttpServletRequest request , HttpServletResponse response )<br />
&nbsp;&nbsp;&nbsp;throws Exception<br />
&nbsp;{<br />
&nbsp;&nbsp;User user = (User) getSessionObject( request, Constants.USER );<br />
&nbsp;&nbsp;ActionMessages msg = new ActionMessages();<br />
&nbsp;&nbsp;if ( user != null )<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;return new ActionForward(&nbsp; user.getType() + ".htm", true );成功就去type.htm<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;else<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;String error = getParameter( request, Constants.ERROR );<br />
&nbsp;&nbsp;&nbsp;if ( error != null )对于不同的错误，都加以提示<br />
&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;if ( error.equalsIgnoreCase( "wrong" ) )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg.add( "msg", new ActionMessage( "fail.login.wrong" ) );<br />
&nbsp;&nbsp;&nbsp;&nbsp;else if ( error.equalsIgnoreCase( "too" ) )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg.add( "msg", new ActionMessage( "fail.login.too" ) );<br />
&nbsp;&nbsp;&nbsp;&nbsp;else if ( error.equalsIgnoreCase( "fail" ) )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg.add( "msg", new ActionMessage( "fail.login.fail" ) );<br />
&nbsp;&nbsp;&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg.add( "msg", new ActionMessage( "fail.login.please" ) );<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;msg.add( "msg", new ActionMessage( "fail.login.please" ) );<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;saveErrors( request, msg );<br />
&nbsp;&nbsp;return mapping.findForward( "fail" );<br />
&nbsp;}</p>
<p>}<br />
<br />
当然，Acegi需要介绍的东西太多了，我只把我这次认为有必要解释的东西写在了上面让大家来参考，作为能google到的东西，比如对于认证的方式还有很多，我就没有详细的介绍，在学习Acegi过程中，把它自带的例子弄清楚很关键，希望大家一起学习一起共勉！<br />
</p>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/194566.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-04-21 17:57 <a href="http://www.blogjava.net/xyzroundo/articles/194566.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSTL详解--EL表达式</title><link>http://www.blogjava.net/xyzroundo/articles/192953.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Mon, 14 Apr 2008 16:15:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/192953.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/192953.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/192953.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/192953.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/192953.html</trackback:ping><description><![CDATA[<br />
&nbsp;&nbsp;&nbsp; 在 JSP 页面中，使用标签库代替传统的 Java 片段语言来实现页面的显示逻辑已经不是新技术了，然而，由自定义标签很容易造成重复定义和非标准的实现。鉴于此，出现了 JSTL （ JSP Standard Tag Library ）。大多数 JSP 页面逻辑提供了实现的 JSTL 技术，该技术本身就是一个标签库。<br />
Sun 公司 Java 规范标准的 JSTL 由 apache jakarta 组织负责维护。作为开源的标准技术，它一直在不断地完善。 JSTL 的发布包有两个版本： Standard-1.0 Taglib 、 Standard-1.1 Taglib ，它们在使用时是不同的。<br />
q&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Standard-1.0 Taglib （ JSTL1.0 ）支持 Servlet2.3 和 JSP1.2 规范， Web 应用服务器 Tomcat4 支持这些规范，而它的发布也在 Tomcat 4.1.24 测试通过了。<br />
q&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Standard-1.1 Taglib （ JSTL1.1 ）支持 Servlet2.4 和 JSP2.0 规范， Web 应用服务器 Tomcat5 支持这些规范，它的发布在 Tomcat 5.0.3 测试通过了。<br />
在本章的介绍中，将以由 Sun 发布的 Standard-1.1 Taglib 标签库为主，而 apache jakarta 组织发布的开源标签库，可以从 http://jakarta.apache.org/taglibs/ 找到所需要的帮助。 Sun 发布的标准 JSTL1.1 标签库有以下几个标签：<br />
q&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 核心标签库：包含 Web 应用的常见工作，比如：循环、表达式赋值、基本输入输出等。<br />
q&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 国际化标签库：用来格式化显示数据的工作，比如：对不同区域的日期格式化等。<br />
q&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 数据库标签库：可以做访问数据库的工作。<br />
q&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XML 标签库：用来访问 XML 文件的工作，这是 JSTL 标签库的一个特点。<br />
q&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 函数标签库：用来读取已经定义的某个函数。<br />
此外， JSTL 还提供了 EL 表达式语言（ Expression Language ）来进行辅助的工作。<br />
<br />
JSTL 标签 库由标签库和 EL 表达式语言两个部分组成。 EL 在 JSTL 1.0 规范中被引入，当时用来作为 Java 表达式来工作，而该表达式必须配合 JSTL 的标签库才能得到需要的结果。<br />
说明：在 JSTL 1.1 规范中， JSP2.0 容器已经能够独立的理解任何 EL 表达式。 EL 可以独立出现在 JSP 页面的任何角落。本文随后的内容将以 JSTL 1.1 规范作为介绍的重点。<br />
一 JSTL EL表达式语言简介<br />
EL 是从 JavaScript 脚本语言得到启发的一种表达式语言，它借鉴了 JavaScript 多类型转换无关性的特点。在使用 EL 从 scope 中得到参数时可以自动转换类型，因此对于类型的限制更加宽松。 Web 服务器对于 request 请求参数通常会以 String 类型来发送，在得到时使用的 Java 语言脚本就应该是 request.getParameter(&#8220;XXX&#8221;) ，这样的话，对于实际应用还必须进行强制类型转换。而 EL 就将用户从这种类型转换的繁琐工作脱离出来，允许用户直接使用 EL 表达式取得的值，而不用关心它是什么类型。<br />
下面的示例就是一个 EL 表达式，见例 1 。<br />
例 1 ：简单 EL 表达式<br />
&lt;%@ page contentType="text/html; charset=UTF-8"%&gt;<br />
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;<br />
&lt;html&gt;<br />
&nbsp;&lt;body&gt;<br />
&nbsp;&nbsp;&nbsp; ${sampleValue + 1} &lt;br&gt;<br />
&nbsp;&lt;/body&gt;<br />
&lt;/html&gt;<br />
这个示例将在 JSP 页面显示为&#8220; 1 &#8221;， EL 表达式必须以&#8220; ${XXX} &#8221;来表示，其中&#8220; XXX &#8221;部分就是具体表达式内容，&#8220; ${} &#8221;将这个表达式内容包含在其中作为 EL 表达式的定义。本示例可以在满足 JSP2.0 规范的任何 Web 应用服务器中使用。<br />
二 EL表达式的默认变量<br />
一个 EL 表达式包含变量和操作符两个内容。任何存在于 JSP 作用范围的 JavaBean 都可以被转化成 EL 表达式来使用，它所包含的默认变量如下：<br />
1 ．默认变量 pageScope 、 requestScope 、 sessionScope 、 applicationScope<br />
这 4 个默认变量包含 Scope 作用范围的参数集合，相当于被保存在 java.util.Map 中的某个参数。下面看简单的示例 2 ：<br />
例 2 ：使用 sessionScope 变量的 EL 表达式<br />
&lt;%request.getSession().setAttribute("sampleValue", new Integer(10));%&gt;<br />
${sessionScope.sampleValue}<br />
取得保存在 Session 中参数的 sessionScope 变量的 EL 表达式，&#8220; . &#8221;是 property 访问操作符，在这里表示从 Session 中取得&#8220;键&#8221;为&#8220; sampleValue &#8221;的参数，并显示出来。显示结果为&#8220; 10 &#8221;。<br />
2 ．默认变量 param 、 paramValues<br />
这两个默认变量包含请求参数的集合， param 表明请求包含的参数为单一控件， paramValues 表明请求包含的参数为控件数组。下面看一个简单示例 3 ：<br />
例 3 ：提交请求的页面和接受的页面<br />
&lt;%@ page contentType="text/html; charset=UTF-8"%&gt;<br />
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;<br />
&lt;html&gt;<br />
&nbsp;&lt;body&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;form action="SampleJsp.jsp"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;input type="text" name="sampleValue" value="10"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;input type="text" name="sampleValue" value="11"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;input type="text" name="sampleValue" value="12"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;input type="text" name="sampleSingleValue" value="SingleValue"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;input type="submit" value="Submit"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/form&gt;<br />
&nbsp;&lt;/body&gt;<br />
&lt;/html&gt;<br />
在这个页面中定义了两组控件，控件名为&#8220; sampleValue &#8221;的是一套控件数组，控件名为&#8220; sampleSingleValue &#8221;的是单一控件，通过递交将请求参数传送到 SampleJsp.jsp 。<br />
&lt;%@ page contentType="text/html; charset=UTF-8"%&gt;<br />
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;<br />
&lt;html&gt;<br />
&nbsp;&lt;body&gt;<br />
&nbsp;&nbsp;&nbsp; ${paramValues.sampleValue[2]} &lt;br&gt;<br />
&nbsp;&nbsp;&nbsp; ${param.sampleSingleValue} &lt;br&gt;<br />
&nbsp;&lt;/body&gt;<br />
&lt;/html&gt;<br />
这是请求转发到的页面，通过 EL 表达式的 paramValues 变量得到控件数组中最后一个控件的递交参数，通过 EL 表达式的 param 变量得到单一控件的递交参数。控件数组参数的 EL 表达式使用&#8220; [] &#8221;来指定数组下标。本示例将显示控件数组中最后一个控件的值&#8220; 12 &#8221;和单一控件的值&#8220; SingleValue &#8221;。<br />
3 ．默认变量 header 、 headerValues<br />
这两个默认变量包含请求参数头部信息的集合， header 变量表示单一头部信息， headerValues 则表示数组型的头部信息。<br />
4 ．默认变量 cookie<br />
包含所有请求的 cookie 集合，集合中的每个对象对应 javax.servlet.http.Cookie 。<br />
5 ．默认变量 initParam<br />
包含所有应用程序初始化参数的集合。<br />
6 ．默认变量 pageContext<br />
等价于 page 环境类 javax.servlet.jsp.PageContext 的实例，用来提供访问不同的请求参数。<br />
11 个默认变量几乎包含了 Web 应用的所有基本操作，若一个表达式不使用这些变量而直接使用参数名，那么就采用就近原则。该表达式将使用最近取得的参数值。<br />
三.EL表达式的操作符<br />
EL 表达式中还有许多操作符可以帮助完成各种所需的操作，之前的示例中&#8220; . &#8221;、&#8220; [] &#8221;就是其中的两个，下面将用表 9.1 来展示所有操作符及它们各自的功能。<br />
表 9.1 EL 表达式的操作符<br />
<br />
操作符<br />
&nbsp;&nbsp;&nbsp; <br />
功能和作用<br />
.<br />
&nbsp;&nbsp;&nbsp; <br />
访问一个 bean 属性或者 Map entry<br />
[]<br />
&nbsp;&nbsp;&nbsp; <br />
访问一个数组或者链表元素<br />
()<br />
&nbsp;&nbsp;&nbsp; <br />
对子表达式分组，用来改变赋值顺序<br />
? :<br />
&nbsp;&nbsp;&nbsp; <br />
条件语句，比如：条件 ?ifTrue:ifFalse<br />
如果条件为真，表达式值为前者，反之为后者<br />
+<br />
&nbsp;&nbsp;&nbsp; <br />
数学运算符，加操作<br />
-<br />
&nbsp;&nbsp;&nbsp; <br />
数学运算符，减操作或者对一个值取反<br />
*<br />
&nbsp;&nbsp;&nbsp; <br />
数学运算符，乘操作<br />
/ 或 div<br />
&nbsp;&nbsp;&nbsp; <br />
数学运算符，除操作<br />
% 或 mod<br />
&nbsp;&nbsp;&nbsp; <br />
数学运算符，模操作 ( 取余 )<br />
== 或 eq<br />
&nbsp;&nbsp;&nbsp; <br />
逻辑运算符，判断符号左右两端是否相等，如果相等返回 true ，否则返回 false<br />
!= 或 ne<br />
&nbsp;&nbsp;&nbsp; <br />
逻辑运算符，判断符号左右两端是否不相等，如果不相等返回 true ，否则返回 false<br />
&lt; 或 lt<br />
&nbsp;&nbsp;&nbsp; <br />
逻辑运算符，判断符号左边是否小于右边，如果小于返回 true ，否则返回 false<br />
&gt; 或 gt<br />
&nbsp;&nbsp;&nbsp; <br />
逻辑运算符，判断符号左边是否大于右边，如果大于返回 true ，否则返回 false<br />
&lt;= 或 le<br />
&nbsp;&nbsp;&nbsp; <br />
逻辑运算符，判断符号左边是否小于或者等于右边，如果小于或者等于返回 true ，否则返回 false<br />
&gt;= 或 ge<br />
&nbsp;&nbsp;&nbsp; <br />
逻辑运算符，判断符号左边是否大于或者等于右边，如果大于或者等于返回 true ，否则返回 false<br />
&amp;&amp; 或 and<br />
&nbsp;&nbsp;&nbsp; <br />
逻辑运算符，与操作赋。如果左右两边同为 true 返回 true ，否则返回 false<br />
|| 或 or<br />
&nbsp;&nbsp;&nbsp; <br />
逻辑运算符，或操作赋。如果左右两边有任何一边为 true 返回 true ，否则返回 false<br />
! 或 not<br />
&nbsp;&nbsp;&nbsp; <br />
逻辑运算符，非操作赋。如果对 true 取运算返回 false ，否则返回 true<br />
empty<br />
&nbsp;&nbsp;&nbsp; <br />
用来对一个空变量值进行判断 : null 、一个空 String 、空数组、 空 Map 、没有条目的 Collection 集合<br />
func(args)<br />
&nbsp;&nbsp;&nbsp; <br />
调用方法 , func 是方法名， args 是参数，可以没有，或者有一个、多个参数 . 参数间用逗号隔开<br />
这些操作符都是极其有用的，下面通过几个示例来演示它们的使用方法：<br />
例 4 ：几组操作符的示例<br />
${pageScope.sampleValue + 12} &lt;br&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 显示 12<br />
${(pageScope.sampleValue + 12)/3} &lt;br&gt;&nbsp;&nbsp;&nbsp;&nbsp; // 显示 4.0<br />
${(pageScope.sampleValue + 12) /3==4} &lt;br&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 显示 true<br />
${(pageScope.sampleValue + 12) /3&gt;=5} &lt;br&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 显示 false<br />
&lt;input type="text" name="sample1" value="${pageScope.sampleValue + 10}"&gt; // 显示值为 10 的 Text 控件<br />
可以看到，对于这些示例，程序设计者完全无需管理它们的类型转换，在表达式内部都已经处理了。有了 EL 表达式，在 JSP 页面的编程变得更灵活，也更容易。<br />
<br />
<img src ="http://www.blogjava.net/xyzroundo/aggbug/192953.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-04-15 00:15 <a href="http://www.blogjava.net/xyzroundo/articles/192953.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jstl之foreach循环</title><link>http://www.blogjava.net/xyzroundo/articles/189529.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Sat, 29 Mar 2008 13:18:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/189529.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/189529.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/189529.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/189529.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/189529.html</trackback:ping><description><![CDATA[<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&lt;%</span><span style="color: #000000">@&nbsp;page&nbsp;contentType</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">text/html;&nbsp;charset=GBK</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">%&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&lt;%</span><span style="color: #000000">@&nbsp;page&nbsp;</span><span style="color: #0000ff">import</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">java.util.*</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">%&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&lt;%</span><span style="color: #000000">@&nbsp;taglib&nbsp;uri</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">http://java.sun.com/jstl/core</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;prefix</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">c</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">%&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&lt;</span><span style="color: #000000">html</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">head</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">title</span><span style="color: #000000">&gt;</span><span style="color: #000000">JSTL测试1</span><span style="color: #000000">--</span><span style="color: #000000">c:forEach循环</span><span style="color: #000000">&lt;/</span><span style="color: #000000">title</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">head</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">body</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />一、整数&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">c:forEach&nbsp;var</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">i</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;begin</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">1</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;end</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">10</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;step</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">1</span><span style="color: #800000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">c:out&nbsp;value</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">/&gt;</span><span style="color: #000000">,&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">c:forEach</span><span style="color: #000000">&gt;&lt;</span><span style="color: #000000">p</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />二、计算x的平方&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">table</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">tr</span><span style="color: #000000">&gt;&lt;</span><span style="color: #000000">th</span><span style="color: #000000">&gt;</span><span style="color: #000000">Value</span><span style="color: #000000">&lt;/</span><span style="color: #000000">th</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">th</span><span style="color: #000000">&gt;</span><span style="color: #000000">Square</span><span style="color: #000000">&lt;/</span><span style="color: #000000">th</span><span style="color: #000000">&gt;&lt;/</span><span style="color: #000000">tr</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">c:forEach&nbsp;var</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">x</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;begin</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">0</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;end</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">10</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;step</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">2</span><span style="color: #800000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">tr</span><span style="color: #000000">&gt;&lt;</span><span style="color: #000000">td</span><span style="color: #000000">&gt;&lt;</span><span style="color: #000000">c:out&nbsp;value</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">/&gt;&lt;/</span><span style="color: #000000">td</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">td</span><span style="color: #000000">&gt;&lt;</span><span style="color: #000000">c:out&nbsp;value</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">0</span><span style="color: #800000">"</span><span style="color: #000000">/&gt;&lt;/</span><span style="color: #000000">td</span><span style="color: #000000">&gt;&lt;/</span><span style="color: #000000">tr</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">c:forEach</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">table</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">p</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />三、字符串</span><span style="color: #800000">"</span><span style="color: #800000">47,52,53,55,46,22,16,2</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;分隔.&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">table&nbsp;border</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">1</span><span style="color: #800000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">c:forTokens&nbsp;items</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">47,52,53,55,46,22,16,2</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;delims</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">,</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;var</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">dailyPrice</span><span style="color: #800000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">tr</span><span style="color: #000000">&gt;&lt;</span><span style="color: #000000">td</span><span style="color: #000000">&gt;&lt;</span><span style="color: #000000">c:out&nbsp;value</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">/&gt;&lt;/</span><span style="color: #000000">td</span><span style="color: #000000">&gt;&lt;/</span><span style="color: #000000">tr</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">c:forTokens</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">table</span><span style="color: #000000">&gt;&lt;</span><span style="color: #000000">p</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />四、使用步长&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">table</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">tr</span><span style="color: #000000">&gt;&lt;</span><span style="color: #000000">th</span><span style="color: #000000">&gt;</span><span style="color: #000000">second</span><span style="color: #000000">&lt;/</span><span style="color: #000000">th</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">th</span><span style="color: #000000">&gt;</span><span style="color: #000000">second</span><span style="color: #000000">&lt;/</span><span style="color: #000000">th</span><span style="color: #000000">&gt;&lt;/</span><span style="color: #000000">tr</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">c:forEach&nbsp;var</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">seconds</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;begin</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">0</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;end</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">1800</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;step</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">60</span><span style="color: #800000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">tr</span><span style="color: #000000">&gt;&lt;</span><span style="color: #000000">td</span><span style="color: #000000">&gt;&lt;</span><span style="color: #000000">c:out&nbsp;value</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">/&gt;&lt;/</span><span style="color: #000000">td</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">td</span><span style="color: #000000">&gt;&lt;</span><span style="color: #000000">c:out&nbsp;value</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">/&gt;&lt;/</span><span style="color: #000000">td</span><span style="color: #000000">&gt;&lt;/</span><span style="color: #000000">tr</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">c:forEach</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">table</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">p</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />五、对数组进行循环</span><span style="color: #000000">&lt;</span><span style="color: #000000">p</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;%</span><span style="color: #000000">&nbsp;int&nbsp;ai[]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;{</span><span style="color: #000000">10</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">20</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">30</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">40</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">50</span><span style="color: #000000">};&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;pageContext.setAttribute(</span><span style="color: #800000">"</span><span style="color: #800000">ary</span><span style="color: #800000">"</span><span style="color: #000000">,&nbsp;ai);&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">%&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">c:forEach&nbsp;var</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">i</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;items</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">c:out&nbsp;value</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">/&gt;*</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">c:forEach</span><span style="color: #000000">&gt;&lt;</span><span style="color: #000000">p</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">&lt;%</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;Cookie&nbsp;c</span><span style="color: #000000">=</span><span style="color: #000000">new&nbsp;Cookie(</span><span style="color: #800000">"</span><span style="color: #800000">cookie1</span><span style="color: #800000">"</span><span style="color: #000000">,</span><span style="color: #800000">"</span><span style="color: #800000">one</span><span style="color: #800000">"</span><span style="color: #000000">);&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;response.addCookie(c);&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">%&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">&lt;%</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;Cookie&nbsp;cookies[]</span><span style="color: #000000">=</span><span style="color: #000000">request.getCookies();&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;Cookie&nbsp;sCookie</span><span style="color: #000000">=</span><span style="color: #000000">null;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;String&nbsp;sname</span><span style="color: #000000">=</span><span style="color: #000000">null;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;String&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">null;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(cookies</span><span style="color: #000000">==</span><span style="color: #000000">null)&nbsp;</span><span style="color: #000000">//</span><span style="color: #000000">&nbsp;如果没有任何cookie&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;out.</span><span style="color: #0000ff">print</span><span style="color: #000000">(</span><span style="color: #800000">"</span><span style="color: #800000">none&nbsp;any&nbsp;cookie</span><span style="color: #800000">"</span><span style="color: #000000">);&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;{&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">//</span><span style="color: #000000">out.</span><span style="color: #0000ff">print</span><span style="color: #000000">(cookies.length&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">&lt;br&gt;</span><span style="color: #800000">"</span><span style="color: #000000">);&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">(int&nbsp;i</span><span style="color: #000000">=</span><span style="color: #000000">0;i</span><span style="color: #000000">&lt;</span><span style="color: #000000">cookies.length;&nbsp;i</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;</span><span style="color: #000000">//</span><span style="color: #000000">&nbsp;循环列出所有可用的Cookie&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sCookie</span><span style="color: #000000">=</span><span style="color: #000000">cookies[i];&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sname</span><span style="color: #000000">=</span><span style="color: #000000">sCookie.getName();&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;sCookie.getValue();&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(sname&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">-&gt;</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;name&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">&lt;br&gt;</span><span style="color: #800000">"</span><span style="color: #000000">);&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">%&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&lt;</span><span style="color: #000000">table&nbsp;border</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">1</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;align</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">center</span><span style="color: #800000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">tr</span><span style="color: #000000">&gt;&lt;</span><span style="color: #000000">th</span><span style="color: #000000">&gt;</span><span style="color: #000000">Cookie&nbsp;Name</span><span style="color: #000000">&lt;/</span><span style="color: #000000">th</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">th</span><span style="color: #000000">&gt;</span><span style="color: #000000">Cookie&nbsp;Value</span><span style="color: #000000">&lt;/</span><span style="color: #000000">th</span><span style="color: #000000">&gt;&lt;/</span><span style="color: #000000">tr</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">c:forEach&nbsp;var</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">cook</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;items</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">tr</span><span style="color: #000000">&gt;&lt;</span><span style="color: #000000">td</span><span style="color: #000000">&gt;&lt;</span><span style="color: #000000">c:out&nbsp;value</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">/&gt;&lt;/</span><span style="color: #000000">td</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">td</span><span style="color: #000000">&gt;&lt;</span><span style="color: #000000">c:out&nbsp;value</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">/&gt;&lt;/</span><span style="color: #000000">td</span><span style="color: #000000">&gt;&lt;/</span><span style="color: #000000">tr</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">c:forEach</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">table</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">p</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />六、字符串数组循环&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">&lt;%</span><span style="color: #000000">&nbsp;String&nbsp;as[]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;{&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">A&nbsp;first&nbsp;string</span><span style="color: #800000">"</span><span style="color: #000000">,&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">La&nbsp;deuxieme&nbsp;string</span><span style="color: #800000">"</span><span style="color: #000000">,&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">Ella&nbsp;troisiemo&nbsp;stringo</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;request.setAttribute(</span><span style="color: #800000">"</span><span style="color: #800000">stringArray</span><span style="color: #800000">"</span><span style="color: #000000">,&nbsp;as);&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">%&gt;&lt;</span><span style="color: #000000">p</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">c:forEach&nbsp;var</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">string</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;items</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">c:out&nbsp;value</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">/&gt;&lt;</span><span style="color: #000000">br</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">c:forEach</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />七、枚举&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">&lt;%</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;Hashtable&nbsp;hashtable1&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;new&nbsp;Hashtable();&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pageContext.setAttribute(</span><span style="color: #800000">"</span><span style="color: #800000">numberMap</span><span style="color: #800000">"</span><span style="color: #000000">,&nbsp;hashtable1);&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hashtable1.put(new&nbsp;Integer(</span><span style="color: #000000">1</span><span style="color: #000000">),&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">uno</span><span style="color: #800000">"</span><span style="color: #000000">);&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hashtable1.put(new&nbsp;Integer(</span><span style="color: #000000">2</span><span style="color: #000000">),&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">dos</span><span style="color: #800000">"</span><span style="color: #000000">);&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hashtable1.put(new&nbsp;Integer(</span><span style="color: #000000">3</span><span style="color: #000000">),&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">tres</span><span style="color: #800000">"</span><span style="color: #000000">);&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hashtable1.put(new&nbsp;Integer(</span><span style="color: #000000">4</span><span style="color: #000000">),&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">cuatro</span><span style="color: #800000">"</span><span style="color: #000000">);&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hashtable1.put(new&nbsp;Integer(</span><span style="color: #000000">5</span><span style="color: #000000">),&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">cinco</span><span style="color: #800000">"</span><span style="color: #000000">);&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hashtable1.put(new&nbsp;Integer(</span><span style="color: #000000">6</span><span style="color: #000000">),&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">seis</span><span style="color: #800000">"</span><span style="color: #000000">);&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hashtable1.put(new&nbsp;Integer(</span><span style="color: #000000">7</span><span style="color: #000000">),&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">siete</span><span style="color: #800000">"</span><span style="color: #000000">);&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hashtable1.put(new&nbsp;Integer(</span><span style="color: #000000">8</span><span style="color: #000000">),&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">ocho</span><span style="color: #800000">"</span><span style="color: #000000">);&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hashtable1.put(new&nbsp;Integer(</span><span style="color: #000000">9</span><span style="color: #000000">),&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">nueve</span><span style="color: #800000">"</span><span style="color: #000000">);&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hashtable1.put(new&nbsp;Integer(</span><span style="color: #000000">10</span><span style="color: #000000">),&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">diez</span><span style="color: #800000">"</span><span style="color: #000000">);&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;java.util.Enumeration&nbsp;enumeration&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;hashtable1.keys();&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pageContext.setAttribute(</span><span style="color: #800000">"</span><span style="color: #800000">enumeration</span><span style="color: #800000">"</span><span style="color: #000000">,&nbsp;enumeration);&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">%&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">c:forEach&nbsp;var</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">item</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;items</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">&nbsp;begin</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">2</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;end</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">10</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;step</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">2</span><span style="color: #800000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">c:out&nbsp;value</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">/&gt;&lt;</span><span style="color: #000000">br</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">c:forEach</span><span style="color: #000000">&gt;&lt;</span><span style="color: #000000">p</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />八、map</span><span style="color: #000000">&lt;</span><span style="color: #000000">p</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">c:forEach&nbsp;var</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">prop</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;items</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">&nbsp;begin</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">1</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;end</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">5</span><span style="color: #800000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">c:out&nbsp;value</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">/&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">c:out&nbsp;value</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">/&gt;&lt;</span><span style="color: #000000">br</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">c:forEach</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">body</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&lt;/</span><span style="color: #000000">html</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/189529.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-03-29 21:18 <a href="http://www.blogjava.net/xyzroundo/articles/189529.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSP页面EL表达式无效的问题</title><link>http://www.blogjava.net/xyzroundo/articles/186803.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Mon, 17 Mar 2008 09:14:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/186803.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/186803.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/186803.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/186803.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/186803.html</trackback:ping><description><![CDATA[<h3><a href="http://gimgen1026.javaeye.com/blog/155354"></a>&nbsp;来源：http://gimgen1026.javaeye.com/category/</h3>
<strong>关键字</strong>: el, web.xml
<div class="blog_content">以前用WSAD wizard做的，都可以在JSP页面中解析到EL表达式，当然前提是JSP2.0的情况下。 <br />
今天遇到了一个莫名其妙的问题。刚下载Eclipse3.3+MyEclipse6.0体验的过程中，遇上了解析不到EL表达式的问题。经过好几个小时的琢磨终于发现了，给大家share一下： <br />
问题就出在建Web Project的时候web.xml声明上。 <br />
web.xml声明部分一般分为如下版本的xsd, <br />
web-app_2_2.xsd <br />
web-app_2_3.xsd <br />
web-app_2_4.xsd <br />
web-app_2_5.xsd <br />
<br />
更详细的列出各版本web.xml声明部分吧，如下： <br />
web-app_2_2.xsd <br />
<pre class="java" name="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/dtd/web-app_2_2.dtd"&gt;</pre>
<br />
web-app_2_3.xsd <br />
<pre class="java" name="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</pre>
<br />
web-app_2_4.xsd <br />
<pre class="java" name="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"&gt;</pre>
<br />
web-app_2_5.xsd <br />
<pre class="java" name="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&gt;</pre>
<br />
<br />
确定web.xml里的xsd版本之后一定要在JSP的声明(&lt;%@page %&gt;)部分加一行，如下： <br />
&lt;%@ page isELIgnored="false" %&gt; <br />
这样设为false才能解析EL表达式。 <br />
经过各版本的test之后.... <br />
注意!! 其中servlets 2.4(我没记错的话JSP 2.0出来之后的第一个版本)，这个版本的isELIgnored默认设置为false。所以使用web.xml里用web-app_2_4.xsd声明的时候在JSP页面不用特意声明。 <br />
<br />
下面是官方Documention中isELIgnored Attribute的详解： <br />
<strong><span style="color: brown">The isELIgnored Attribute</span></strong> <br />
<strong>&#8226; Format</strong> <br />
&#8211; &lt;%@ page isELIgnored="false" %&gt; <br />
&#8211; &lt;%@ page isELIgnored="true" %&gt; <br />
<strong>Purpose</strong> <br />
&#8211; To control whether the JSP 2.0 Expression Language <br />
(EL) is ignored (true) or evaluated normally (false). <br />
<strong>&#8226; Notes</strong> <br />
&#8211; If your web.xml specifies servlets 2.3 (corresponding to <br />
JSP 1.2) or earlier, the default is true <br />
&#8226; But it is still legal to change the default—you are permitted <br />
to use this attribute in a JSP-2.0-compliant server <br />
regardless of the web.xml version. <br />
&#8211; If your web.xml specifies servlets 2.4 (corresponding to <br />
JSP 2.0) or earlier, the default is false </div>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/186803.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-03-17 17:14 <a href="http://www.blogjava.net/xyzroundo/articles/186803.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate级联保存和更新</title><link>http://www.blogjava.net/xyzroundo/articles/186552.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Sat, 15 Mar 2008 15:56:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/186552.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/186552.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/186552.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/186552.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/186552.html</trackback:ping><description><![CDATA[来源：http://www.tianxiaboke.com/u/lyeerwy<br />
<p><strong><font color="#ff0000">级联保存和更新</font></strong><br />
当Hibernate持久化一个临时对象时，在默认情下，他不会自动持久化所关联的其他临时对象，如果希望当持久化对象时把他所关联的所有临时对象进行持久化的话：可以把&nbsp;<many-to-one></many-to-one>的cascade属性设置为"save-update"&nbsp;,cascade的默认属性值为none。<br />
cascade:设置操作对象时的级联操作，即层级之间的连锁操作<br />
值&nbsp;save-update&nbsp;：表示当保存和更新当前对象(即insert和update语句时)，会级联保存和更新与他关联的对象<br />
值&nbsp;all&nbsp;：表示任何情况下都会进行级联操作，即对一个对象进行操作，也会对和他关联的其他对象进行同样的操作<br />
值&nbsp;delete&nbsp;：表示在执行delete时，进行级联操作，删除和他关联的对象<br />
值&nbsp;none&nbsp;：表示任何情况下，都不会进行级联操作<br />
<strong><font color="#0000ff">&lt;set&gt;元素的inverse属性</font></strong></p>
<p>在运行上面的程序时，如果hibernate的"show-sql"设置为true时，就会看到Hibernate会生成很多sql语句，其实很多sql语句都是重复的<br />
eg：&nbsp;<br />
insert&nbsp;into&nbsp;&nbsp;test.order(o_name,c_id)values(?,?)<br />
insert&nbsp;into&nbsp;&nbsp;test.order(o_name,c_id)values(?,?)<br />
insert&nbsp;into&nbsp;&nbsp;test&nbsp;order&nbsp;&nbsp;&nbsp;set&nbsp;c_id=?&nbsp;where&nbsp;id=?<br />
insert&nbsp;into&nbsp;&nbsp;test&nbsp;order&nbsp;&nbsp;&nbsp;set&nbsp;c_id=?&nbsp;where&nbsp;id=?</p>
<p>为了解决这个问题，我们可以利用在&lt;set&gt;标签中加上inverse属性。术语：inverse是指反转的意思，在Hibernate中，表示关联关系中的方向关联关系中，inverse="false"的主控方，由主动方负责维护对象关系我们&nbsp;在customer对象的对象配置文件中加上</p>
<p>&lt;set&nbsp;name="orders"&nbsp;&nbsp;cascade="save-update"&nbsp;inverse="true"&gt;<br />
&lt;key&nbsp;&nbsp;column="c_id"&nbsp;&gt;&nbsp;&lt;/key&gt;<br />
&lt;one-to-many&nbsp;class="net.mbs.mypack.Order&nbsp;"&nbsp;/&gt;<br />
&lt;/set&gt;</p>
<p>声明在Customer和Order的双向关联关系中，Customer端的关联只是Order端关联的镜象（即Order端是主空端，负责维护Customer和order对象之间的关联关系），当hibernate探测到持久化对象Customer或Order的状态发生变化时(主要是关联关系的改变),仅按照Order对象的状态的变化来同步更新数据库。<br />
按次配置，如果在程序中，我们仅仅使用Customer.getOrder().add(order)（涉及了和Order的关联关系的改变），是不能让数据库跟对象的变化来进行数据库同步更新的，只有利用Order对象的方法改变的Order对象状态(eg：order.setCustomer(customer)----涉及到了和Customer的关联关系的改变)时，数据库才会根据变化来同步更新数据库，即只有主控方的状态（涉及到了和另一方面的关联关系的改变）发生了变化后，才会触发对象和数据库的同步更新。</p>
<p><strong><font color="#0000ff">映射一对多双向关联关系<br />
</font></strong>当类与类之间建立了关联，就可以方便的从一个对象导航到另一个对象或一组与他关联的对象当中，根据上面的程序，对于一个给定的Order对象，如果想获取与他关联的Customer对象，我们只需要调用入下方法：<br />
Customer&nbsp;c=order.geCustomer();&nbsp;那么当我们得到一个Customer对象后，想查出和这个Customer对象关联的所有Order对象时，应该怎么办呢？由于在Customer中没有建立对Order对象的关联，所以，不能通过加载Customer对象来自动加载和他关联的所有Order对象，唯一的方法只能通过JDBC或SQL语言人工写出代码来查询数据库Order表来返回所需要的信息<br />
上面的问题虽然解决，但不能算是最好，因为这样性能会有所下降，对象位于内存中，在内存中从一个对象导航到另一个对象显然比到数据库中查询数据要快得多<br />
</p>
<p>具体实现&lt;br&gt;<br />
1：由于Customer和Order是一对多，即一个Customer要对应多个Order，所以在Customer中应该建立一个Set对象，用于存放和本Customer对象关联的所有Order对象。<br />
2：在customer.hbm.xml通过&lt;one-to-many&gt;建立对Order表的关联关系<br />
注意：&lt;one-to-many&gt;应该放置在&lt;set&gt;标签中&nbsp;<br />
我们先来看看Customer类的设计和customer.hbm.xml文件的内容<br />
&lt;br&gt;&lt;br&gt;&lt;br&gt;------------------------------------------------------<br />
<font color="#0000ff">Customer&nbsp;Order&nbsp;双向一对多</font><br />
1：Customer类中建立一个容器对象，包含关联的所有Order对象<br />
2：Order类中建立一个Customer对象，关联Customer<br />
inverse="true"表示将维护关联的权利交给引起Hibernate语句的生成</p>
<p>customer.getOrders().add(order);<br />
customer.setName("dddddd");<br />
<br />
inverse="true"（设置此属性的一方----是被控方）<br />
当主控方修改对象之间的关联关系时，让Hibernate生成sql语句<br />
</p>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/186552.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-03-15 23:56 <a href="http://www.blogjava.net/xyzroundo/articles/186552.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>优化程序之前，可用Jamon来监测你的Spring应用</title><link>http://www.blogjava.net/xyzroundo/articles/186293.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Fri, 14 Mar 2008 06:40:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/186293.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/186293.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/186293.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/186293.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/186293.html</trackback:ping><description><![CDATA[** <br />
*作者：张荣华(ahuaxuan) <br />
*2007-8-15 <br />
*转载请注明出处及作者 <br />
*/ <br />
<br />
前两天在看Spring内置的拦截器的时候，发现了一个之前没有注意的类：org.springframework.aop.interceptor.<span class="hilite1"><span class="hilite1">Jamon</span></span>PerformanceMonitorInterceptor，好奇心促使我上网查了一下这个<span class="hilite1"><span class="hilite1">jamon</span></span>。大概看了一下之后发现这个玩意还真挺好用的而且挺重要的，而且现在国内对它的介绍也很少，所以写了一篇文章和大家分享。 <br />
<br />
一，<span class="hilite1"><span class="hilite1">Jamon</span></span>简介： <br />
<span class="hilite1"><span class="hilite1">Jamon</span></span>的全名是：Java Application Monitor。它是一个小巧的，免费的，高性能的，线程安全的性能监测工具。它可以用来测定系统的性能瓶颈，也可以用来监视用户和应用程序之间的交互情况。 <span class="hilite1"><span class="hilite1">Jamon</span></span>主要是用来检测jee的应用程序。它最新的版本是2.1，可以用在1.4以上的jdk上。 <br />
<br />
二，将<span class="hilite1"><span class="hilite1">jamon</span></span>导入到你的应用程序中去 <br />
首先下载<span class="hilite1"><span class="hilite1">jamon</span></span>的开发包，见我的附件，同时你也可以去Sourceforge上自己下载。Sourceforge的下载地址为http://<span class="hilite1"><span class="hilite1">jamon</span></span>api.sourceforge.net。解压之后可以得到一个jar包和一个war包。jar包是自己会用到的，而war包是一个例子（不要小看这个例子，待会也要把它导入到项目中）。把war包之间丢到服务器上，访问：localhost:8080/<span class="hilite1"><span class="hilite1">jamon</span></span>就可以看到这个例子了，这个例子是一个简单的性能监控系统。 <br />
<br />
接着把例子中的所有的包都导入到项目中，并把war包中的jsp和images还有css都考到项目中，比如新建一个目录叫monitor（它和WEB-INF是同级目录）。 <br />
<br />
三，正确配置自己的应用 <br />
我们在性能监测的时候最监测的就是页面的访问率和类中方法的访问率。所以在这一部分主要讲解一下如何监测自己的页面和类中方法的访问。 <br />
<br />
1， 检测自己的页面访问率 <br />
首先我们需要在web.xml中添加一个filter，这个filter就是用来判断哪些页面需要被监视的，如下所示： <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/topic/112172#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>&lt;filter&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;filter-name&gt;<span class="hilite1"><span class="hilite1">JAMon</span></span>Filter&lt;/filter-name&gt; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;filter-</span><span class="keyword">class</span><span>&gt;com.easywebwork.filter.EasyPageMonFilter&lt;/filter-</span><span class="keyword">class</span><span>&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/filter&gt; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;filter-mapping&gt; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;filter-name&gt;<span class="hilite1"><span class="hilite1">JAMon</span></span>Filter&lt;/filter-name&gt; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;url-pattern&gt;/*&lt;/url-pattern&gt; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/filter-mapping&gt;&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none" name="code">&lt;filter&gt;
&lt;filter-name&gt;<span class="hilite1"><span class="hilite1">JAMon</span></span>Filter&lt;/filter-name&gt;
&lt;filter-class&gt;com.easywebwork.filter.EasyPageMonFilter&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
&lt;filter-name&gt;<span class="hilite1"><span class="hilite1">JAMon</span></span>Filter&lt;/filter-name&gt;
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
</pre>
接下来我们看看这个filter的写法： <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/topic/112172#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*&nbsp;@author&nbsp;张荣华（ahuaxuan） </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;* </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*&nbsp;@since&nbsp;2007-8-13 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;PageMonFilter&nbsp;</span><span class="keyword">extends</span><span>&nbsp;<span class="hilite1"><span class="hilite1">JAMon</span></span>Filter{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">final</span><span>&nbsp;</span><span class="keyword">long</span><span>&nbsp;serialVersionUID&nbsp;=&nbsp;5746197114960908454L; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;doFilter(ServletRequest&nbsp;request,&nbsp;ServletResponse&nbsp;response,&nbsp;FilterChain&nbsp;filterChain)&nbsp;</span><span class="keyword">throws</span><span>&nbsp;IOException,&nbsp;ServletException&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Monitor&nbsp;allPages&nbsp;=&nbsp;MonitorFactory.start(</span><span class="keyword">new</span><span>&nbsp;MonKeyImp(</span><span class="string">"org.easywebwork.allPages"</span><span>,getURI(request),</span><span class="string">"ms."</span><span>)); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//这里就是我们要监视的所有的页面的配置 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Monitor&nbsp;monitor&nbsp;=&nbsp;MonitorFactory.start(getURI(request)); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//这里就是我们要监视的某个页面的配置 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filterChain.doFilter(request,&nbsp;response); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">finally</span><span>&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;monitor.stop(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;allPages.stop(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">protected</span><span>&nbsp;String&nbsp;getURI(ServletRequest&nbsp;request)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(request&nbsp;</span><span class="keyword">instanceof</span><span>&nbsp;HttpServletRequest)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;((HttpServletRequest)&nbsp;request).getRequestURI(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span><span class="keyword">else</span><span>&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="string">"Not&nbsp;an&nbsp;HttpServletRequest"</span><span>; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;FilterConfig&nbsp;filterConfig&nbsp;=&nbsp;</span><span class="keyword">null</span><span>; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>}}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none" name="code">/**
* @author 张荣华（ahuaxuan）
*
* @since 2007-8-13
*/
public class PageMonFilter extends <span class="hilite1"><span class="hilite1">JAMon</span></span>Filter{
private static final long serialVersionUID = 5746197114960908454L;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
Monitor allPages = MonitorFactory.start(new MonKeyImp("org.easywebwork.allPages",getURI(request),"ms."));
//这里就是我们要监视的所有的页面的配置
Monitor monitor = MonitorFactory.start(getURI(request));
//这里就是我们要监视的某个页面的配置
try {
filterChain.doFilter(request, response);
} finally {
monitor.stop();
allPages.stop();
}
}
protected String getURI(ServletRequest request) {
if (request instanceof HttpServletRequest) {
return ((HttpServletRequest) request).getRequestURI();
} 	else {
return "Not an HttpServletRequest";
}
}
private FilterConfig filterConfig = null;
}}
</pre>
<br />
这个类看上去很简单，其实也挺简单的，就是得到uri，然后把它注册到MonitorFactory类中。这样只要我们去访问刚才创建的monitor目录下的jsp就可以看到性能监测页面了。 <br />
<br />
2， ，接下来我们看看在使用spring的情况下如何监测一个bean的方法调用。Spring也提供了对<span class="hilite1"><span class="hilite1">Jamon</span></span>的支持(spring支持的东西还真多啊)，也就是文章开头提出的那个拦截器，为了给我们的bean加上拦截器，我们在spring的applicationcontext配置文件中加入如下语句： <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/topic/112172#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>&lt;bean&nbsp;</span><span class="keyword">class</span><span>=</span><span class="string">"org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"</span><span>&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name=</span><span class="string">"beanNames"</span><span>&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;list&gt; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;userService&lt;/value&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/list&gt; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name=</span><span class="string">"interceptorNames"</span><span>&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;list&gt; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;<span class="hilite1"><span class="hilite1">jamon</span></span>Interceptor&lt;/value&gt; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/list&gt; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/bean&gt; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean&nbsp;id=</span><span class="string">"<span class="hilite1"><span class="hilite1">jamon</span></span>Interceptor"</span><span>&nbsp;</span><span class="keyword">class</span><span>=</span><span class="string">"org.springframework.aop.interceptor.<span class="hilite1"><span class="hilite1">Jamon</span></span>PerformanceMonitorInterceptor"</span><span>&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&lt;/bean&gt;&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none" name="code">&lt;bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"&gt;
&lt;property name="beanNames"&gt;
&lt;list&gt;
&lt;value&gt;userService&lt;/value&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;property name="interceptorNames"&gt;
&lt;list&gt;
&lt;value&gt;<span class="hilite1"><span class="hilite1">jamon</span></span>Interceptor&lt;/value&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="<span class="hilite1"><span class="hilite1">jamon</span></span>Interceptor" class="org.springframework.aop.interceptor.<span class="hilite1"><span class="hilite1">Jamon</span></span>PerformanceMonitorInterceptor"&gt;
&lt;/bean&gt;</pre>
<br />
上面这个是典型的spring的aop的配置，如果对spring的aop配置不了解的可以去看一下spring中文文档，当然如果不想了解的话即使直接把这段配置拷到自己的项目中也是可以直接使用的。 <br />
<br />
还有一个步骤就是在你的log4j.properties中加入这句代码： <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/topic/112172#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>log4j.logger.org.springframework.aop.interceptor.<span class="hilite1"><span class="hilite1">Jamon</span></span>PerformanceMonitorInterceptor&nbsp;=&nbsp;TRACE&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre class="java" style="display: none" name="code">log4j.logger.org.springframework.aop.interceptor.<span class="hilite1"><span class="hilite1">Jamon</span></span>PerformanceMonitorInterceptor = TRACE</pre>
<br />
如果没有这一行，那么这个拦截器是不会把方法调用的信息向MonitorFactory注册的。 <br />
<br />
只需要这些步骤，userservice中的方法在调用的时候就可以被拦截，然后将其注册到MonitorFactory中去了。 <br />
<br />
所有的配置完成之后我们来看一下效果吧: <br />
<a href="http://www.javaeye.com/topics/download/b2bac96e-6c18-4340-b7e0-f84c7bb6adca" target="_blank">http://www.javaeye.com/topics/download/b2bac96e-6c18-4340-b7e0-f84c7bb6adca</a>从这个图上我们可以看到，所有页面被访问的次数，UserService中的getAllUsers被调用的次数，最右边的是访问时间。这只是整个图的一部分，当然这个页面中也包括每一个页面被访问的次数和第一次访问的时间等等。下载附件运行，就可以看到所有的页面了。 <br />
<br />
三，总结 <br />
根据以上的步骤，我们就可以监测我们的程序了，应用程序中哪些页面被访问的多，哪些页面被访问的少，哪些方法被访问的多，哪些方法被访问的少，以及访问高峰期集中在什么时间等等，有了这些参数，我们更可以有针对性的对应用程序进行优化了，比如说某个页面访问比较频繁，我就可以用ehcache或oscache给这个页面做一个缓存。如果某个方法的访问比较频繁那就看看这个方法能否进一步优化，是需要异步，还是需要缓存，还是需要其他等等，总之有了<span class="hilite1"><span class="hilite1">jamon</span></span>可以给我们带来更多的便捷，既可以让我们知道我们的客户的行为，也可以让我们知道我们开发的程序的&#8220;能力&#8221;。 <br />
<br />
其实本文提供的只是对页面和方法调用的监控，但是<span class="hilite1"><span class="hilite1">jamon</span></span>可以提供更多功能，比如说sql语句的监控等等，这就需要我们共同去发掘了。 <br />
<br />
附件中包括了一个easywebwork的例子，我把<span class="hilite1"><span class="hilite1">jamon</span></span>导入到这个例子工程中去，大家可以直接下载运行观看效果。Easywebwork是一个旨在减少webwork2.2.x系列的xml配置文件的项目， <br />
如果对这个主题感兴趣请到 <br />
<a href="http://www.javaeye.com/topic/91614" target="_blank">http://www.javaeye.com/topic/91614</a> <br />
<a href="http://www.javaeye.com/topic/93814" target="_blank">http://www.javaeye.com/topic/93814</a> <br />
参加讨论。 <br />
<img src ="http://www.blogjava.net/xyzroundo/aggbug/186293.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-03-14 14:40 <a href="http://www.blogjava.net/xyzroundo/articles/186293.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>由DWR1.0到DWR2.0常出现的问题</title><link>http://www.blogjava.net/xyzroundo/articles/183820.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Tue, 04 Mar 2008 16:22:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/183820.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/183820.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/183820.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/183820.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/183820.html</trackback:ping><description><![CDATA[<p>在1.0的时候是好使的 换成2.0的时候 就出现 Missing method or missing parameter converters 这个错误了 </p>
<p>2007-11-29 17:44:14 org.directwebremoting.util.CommonsLoggingOutput warn<br />
警告: Marshalling exception: Missing method or missing parameter converters:</p>
<p>主要原因就是DWR2中更新了的内容，原文如下：</p>
<p>The callback-as-first-parameter system has been deprecated since version 0.9 in favor of the callback-as-last-parameter system. In version 2.0 we removed support for the first-parameter option because it caused some hard to detect bugs with null parameters. From version 2.0 the callback must be the last parameter, and can not be the first parameter.</p>
<p>就是说以前版本callback参数是放在参数列表第一个参数，而在0.9版本中callback参数改为参数列表最后一个参数。到2.0版本取消了对callback参数前置的支持。</p>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/183820.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-03-05 00:22 <a href="http://www.blogjava.net/xyzroundo/articles/183820.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DWR总结</title><link>http://www.blogjava.net/xyzroundo/articles/183805.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Tue, 04 Mar 2008 14:29:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/183805.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/183805.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/183805.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/183805.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/183805.html</trackback:ping><description><![CDATA[这两天学了下DWR，现在总结一下。<br />
DWR是方便使用AJAX连接JS和JAVA的的一个框架,<font size="2"><span ;="" mso-hansi-font-family:="" times="" new="" roman="">把服务器端</span><span lang="EN-US"><font face="Times New Roman"> Java </font></span><span ;="" mso-hansi-font-family:="" times="" new="" roman="">对象的方法公开给</span><span lang="EN-US"><font face="Times New Roman"> JavaScript </font></span><span ;="" mso-hansi-font-family:="" times="" new="" roman="">代码</span>。</font><br />
如果是用dwr2.0的jar包，还需要同时导入<span style="color: rgb(255,1,2)">log4j.jar和commons-loggin.jar</span>,勿忘!!<br />
web.xml和dwr.xml放在WEB-INF下!<br />
-----------------------------<br />
<font style="color: rgb(102,1,153)" size="4">配置web.xml</font>:WEB工程启动的时候会在这个里面找到具体所用到的类的路径，由此进行加载<br />
<br />
<span style="color: rgb(0,1,255)">&lt;servlet&gt;</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt; dwr-invoke &lt;/servlet-name&gt;</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; &lt;servlet-class&gt; uk.ltd.getahead.dwr.DWRServlet &lt;/servlet&gt;</span><br />
&nbsp;&nbsp;&nbsp; <span style="color: rgb(0,1,255)">&lt;init-param&gt; </span>//这个是调试用，如果正式发布请该为false，不过听说2.0就默认为true了<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <span style="color: rgb(0,1,255)">&lt;param-name&gt; debug &lt;/param-value&gt;</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &lt;param-value&gt; true &lt;/param-value&gt;</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; &lt;/init-param&gt;</span><br />
&nbsp;&nbsp;&nbsp;<span style="color: rgb(0,1,255)"> &lt;init-param&gt; </span>//这个是DWR2.0必须的,不然会报java.lang.IllegalArgumentException<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <span style="color: rgb(0,1,255)">&lt;param-name&gt; classes &lt;/param-value&gt;</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &lt;param-value&gt; java.lang.Object &lt;/param-value&gt;</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&lt;/servlet&gt;</span><br style="color: rgb(0,1,255)" />
<br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&lt;servlet-mapping&gt;</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt; dwr-invoke &lt;/servlet-name&gt;</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt; /dwr/* &lt;/url-pattern&gt;</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&lt;/servlet-mapping&gt;</span><br />
<br />
-----------------------------<br />
<font style="color: rgb(102,1,153)" size="4">配置dwr.xml</font>: dwr.xml的作用是让你告诉DWR哪些class中的哪些方法你需要暴露给前台使用，当DWR启动时候根据dwr.xml这个文件把java类中的方法转成js中可用的类中方法，使前台可以使用。<br />
<br />
注:以下是不全按dwr2.0写的，如果用的是DWR2.0，那java里暴露类(蓝字显示)不能写在&lt;create&gt;属性里，应删除后写在&lt;include method="" /&gt;前，&lt;param name="class" value="***java里暴露的class,必须写完整路径***" /&gt;。<br />
<br />
<br />
<span style="color: rgb(0,1,255)">&lt;dwr&gt;</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; &lt;allow&gt;</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &lt;create creator="new" javascript="***js调用的class***"</span> <span style="color: rgb(51,153,153)">class="***java里暴露的class,必须写完整路径***"</span>&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: rgb(0,1,255)">&lt;include method="***java暴露类里要公开的方法，如果不写默认全部公开***" /&gt;</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &lt;/create&gt;</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; &lt;/allow&gt;</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&lt;/dwr&gt;</span><br />
<br />
-----------------------------<br />
在html或js页面中加入<br />
<span style="color: rgb(0,1,255)">&lt;script src="<span style="color: rgb(255,153,2)">&lt;%=basePath %&gt;</span>dwr/interface/java里暴露的class"&gt;&lt;/script&gt;&nbsp; <span style="color: rgb(0,1,2)">//切记不能&lt;script *** /&gt;这样写</span></span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&lt;script src="</span><span style="color: rgb(0,1,255)"><span style="color: rgb(255,153,2)">&lt;%=basePath %&gt;</span></span><span style="color: rgb(0,1,255)">dwr/engine.js"&gt;&lt;/script&gt; &nbsp; <span style="color: rgb(0,1,2)">//<span><span><span><span><span><span><span><span><span><span><span><span>Dwr的脚本驱动Js,</span></span></span></span></span></span></span></span></span></span></span></span>以上两个必写</span></span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&lt;script src="</span><span style="color: rgb(0,1,255)"><span style="color: rgb(255,153,2)">&lt;%=basePath %&gt;</span></span><span style="color: rgb(0,1,255)">dwr/util.js"&gt;&lt;/script&gt;&nbsp;&nbsp; <span style="color: rgb(0,1,2)">//这是个工具包，可以不调用</span></span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&lt;script type="text/javascript"&gt;</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; function doMethod()</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; {</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: rgb(0,1,2)">//调用方法:若公开的类是AAA,公开的AAA里的方法是bbb([参数]);</span></span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; AAA.bbb([参数],callBack);<span style="color: rgb(0,1,2)">//回调函数callBack()</span></span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; }</span><br style="color: rgb(0,1,255)" />
<br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; function callBack(data)//data是后台返回的值，名字自取，也可省略，因为JS允许</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; {</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)" dragover="true">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 处理方法&#8230;&#8230;;<span style="color: rgb(0,1,2)">//如果callBack()没有写明返回值，可以通过argments[0]拿到</span></span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; }</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&lt;/script&gt;</span><br style="color: rgb(0,1,255)" />
<br />
<br />
其实我们调用AAA.bbb([参数],callBack);就是做了以下这一步：<br />
(下面红字是包装好的，不在前台，所以即使你没有创建html或者jsp来调用，也可以通过localhost:8080/工程名/dwr 来看到你暴露的java类进行测试)<br />
&nbsp;&nbsp;&nbsp;<span style="color: rgb(255,1,2)"> function AAA() { };</span><br style="color: rgb(255,1,2)" />
<span style="color: rgb(255,1,2)">&nbsp;&nbsp;&nbsp; AAA.bbb = function([参数], callback) </span><br style="color: rgb(255,1,2)" />
<span style="color: rgb(255,1,2)">&nbsp;&nbsp;&nbsp; { </span><br style="color: rgb(255,1,2)" />
<span style="color: rgb(255,1,2)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; DWREngine._execute('/dwr/dwr', 'AAA', 'bbb', [参数], callback); </span><br style="color: rgb(255,1,2)" />
<span style="color: rgb(255,1,2)">&nbsp;&nbsp;&nbsp; }</span><br />
<br />
通过在dwr.xml暴露的方法得到js里的方法，当我们调用AAA.bbb时候再通过/dwr/dwr转到DWRServlet中去用JAVA里的AAA.bbb方法，然后返回值到callback中(中间经过dwr.xml的convert)<br />
<br />
<br />
----------------------------<br />
上面对dwr的工作大致分析了下，现在对于参数类型的不同，对dwr.xml也要进行修正。<br />
<br />
DWR自动地在Java和JavaScript表示之间调整简单数据类型,这些类型包括Java原生类型和它们各自的封装类表示，还有String、Date、数组和集合类型。但如果参数类型非简单数据类型，则要通过转换。<br />
<br />
<font size="4"><font size="3"><strong style="color: rgb(102,1,153)">调</strong><strong style="color: rgb(102,1,153)">用返回</strong><strong style="color: rgb(102,1,153)">JavaBean</strong><strong style="color: rgb(102,1,153)">的</strong><strong style="color: rgb(102,1,153)">java</strong></font><strong style="color: rgb(102,1,153)"><font size="3"><span style="font-weight: normal"><span style="font-weight: bold">方法</span><br />
<br />
</span></font></strong></font>
<div style="margin-left: 40px"><font size="4"><strong style="color: rgb(102,1,153)"><font size="3"><span style="font-weight: normal"><font style="color: rgb(0,1,2)" size="2">在dwr.xml的&lt;allow&gt;标签中加入</font></span></font></strong></font><br />
<font size="4"><strong style="color: rgb(102,1,153)"><font size="3"></font></strong></font><br />
<font size="4"><strong style="color: rgb(102,1,153)"><font size="3"></font></strong></font><span style="color: rgb(0,1,255)">&lt;convert converter="bean" match="***一般来说是javabean***"&gt;</span>&nbsp; //int,String,list等不需要显式的转换就可以被js拿到<br />
&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: rgb(0,1,255)">&lt;param name="include" value="***javabean中的属性，用','隔开***" /&gt;&nbsp; <span style="color: rgb(0,1,2)">//这句可以不写</span></span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&lt;/convert&gt;</span><br />
<br />
&lt;creator&gt;标签负责公开用于Web远程的类和类的方法，&lt;convertor&gt;标签则负责这些方法的参数和返回类型。<span style="color: rgb(255,1,255)">convert元素的作用是告诉DWR在服务器端Java 对象表示和序列化的JavaScript之间如何转换数据类型</span>。<br />
<font size="4"><strong style="color: rgb(102,1,153)"></strong></font><br />
<font size="4"><strong style="color: rgb(102,1,153)"><font style="font-weight: normal" size="2"><span style="color: rgb(0,1,2)">这样在js端回调函数直接拿到的data就是一个javabean,可以直接通过data.xxx拿到bean的属性xxx。</span></font></strong></font><br />
<font size="4"><strong style="color: rgb(102,1,153)"><font style="font-weight: normal" size="2"></font></strong></font></div>
<font size="4"><strong style="color: rgb(102,1,153)"><font style="font-weight: normal" size="2"><span style="color: rgb(0,1,2)"><br />
<br />
</span></font></strong></font><font size="4"><font size="3"><strong style="color: rgb(102,1,153)">调</strong><strong style="color: rgb(102,1,153)">用有</strong><strong style="color: rgb(102,1,153)">JavaBean参数</strong><strong style="color: rgb(102,1,153)">的</strong><strong style="color: rgb(102,1,153)">java</strong></font><strong style="color: rgb(102,1,153)"><font size="3"><span style="font-weight: normal"><span style="font-weight: bold">方法<br />
<br />
</span></span></font></strong></font>
<div style="margin-left: 40px"><font size="4"><strong style="color: rgb(102,1,153)"><font size="3"><span style="font-weight: normal"><font size="2"><span style="color: rgb(0,1,2)">dwr.xml配置同上。</span></font></span></font></strong></font><br />
<font size="4"><strong style="color: rgb(102,1,153)"><font size="3"><span style="font-weight: normal"><font size="2"></font></span></font></strong></font><br />
<font size="4"><strong style="color: rgb(102,1,153)"><font size="3"><span style="font-weight: normal"><font size="2"><span style="color: rgb(0,1,2)">在JS端，把要传入的参数写成javabean方式，例：要传入一个名为student的javabean,参数有name,password,则</span></font></span></font></strong></font><br />
<font size="4"><strong style="color: rgb(102,1,153)"><font size="3"><span style="font-weight: normal"><font size="2"><span style="color: rgb(0,1,2)"><span style="color: rgb(0,1,255)">var stu = {name:"zhangsan",password:"zspassword"};</span> //这是json的表示方法</span></font></span></font></strong></font><br />
<font size="4"><strong style="color: rgb(102,1,153)"><font size="3"><span style="font-weight: normal"><font size="2"><span style="color: rgb(0,1,2)"><span style="color: rgb(0,1,255)">AAA.bbb(stu,callBack);</span></span></font></span></font></strong></font><br />
<font size="4"><strong style="color: rgb(102,1,153)"><font size="3"><span style="font-weight: normal"><font size="2"><span style="color: rgb(0,1,2)"></span></font></span></font></strong></font></div>
<font size="4"><strong style="color: rgb(102,1,153)"><font size="3"><span style="font-weight: normal"><font size="2"><span style="color: rgb(0,1,2)"><span style="color: rgb(0,1,255)"><br />
<br />
</span></span></font></span></font></strong></font><strong></strong><font size="3"><strong style="color: rgb(102,1,153)">调</strong><strong style="color: rgb(102,1,153)">用返回</strong><strong style="color: rgb(102,1,153)">List</strong><strong style="color: rgb(102,1,153)">、</strong><strong style="color: rgb(102,1,153)">Set</strong><strong style="color: rgb(102,1,153)">或者</strong><strong style="color: rgb(102,1,153)">Map</strong><strong style="color: rgb(102,1,153)">的</strong><strong style="color: rgb(102,1,153)">java</strong><strong style="color: rgb(102,1,153)">方法</strong></font><br />
<font size="4"><strong style="color: rgb(102,1,153)"><br />
</strong></font>
<div style="margin-left: 40px">dwr.xml配置同上。如果Collection里的数据是简单数据类型，则可不需要写&lt;convert&gt;<br />
<br />
在JS端，以<font size="3"><span style="font-weight: bold">List</span></font>，里面数据是bean为例，data是一个List型，只要用for循环就可以依次拿到数据。<br />
遍历方法1:<br />
<span style="color: rgb(0,1,255)">for(var i=0;i&lt;data.length;i++)&nbsp; <br />
<span style="color: rgb(0,1,2)">&nbsp;&nbsp;&nbsp; /*</span></span>对于java方法的返回值为List(Set)的情况，DWR将其转&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; 化为Object数组，传递个javascript*/<br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">{</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; alert(data[i].name+":"+data[i].password);</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">}<br />
<br />
<span style="color: rgb(0,1,2)">遍历方法2:<br />
<span style="color: rgb(0,1,255)">for(var </span></span></span><span style="color: rgb(0,1,255)">property</span><span style="color: rgb(0,1,255)"><span style="color: rgb(0,1,2)"><span style="color: rgb(0,1,255)"> in data) <span style="color: rgb(0,1,2)">//property为序号,从0开始</span></span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">{</span></span></span><span style="color: rgb(0,1,255)"><span style="color: rgb(0,1,2)"><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp; &nbsp; var bean = data[</span></span></span><span style="color: rgb(0,1,255)">property</span><span style="color: rgb(0,1,255)"><span style="color: rgb(0,1,2)"><span style="color: rgb(0,1,255)">];</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp; &nbsp; alert(bean.name+":"+bean.password);</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">}</span><br style="color: rgb(0,1,255)" />
</span><br />
<span style="color: rgb(0,1,2)">相比返回为javabean多了一个遍历而已。<br />
<br />
</span></span>如果java方法的返回值为<font size="3"><span style="font-weight: bold">Map</span><font style="font-family: 宋体" size="2">,则如下<br />
<br />
</font></font><span style="color: rgb(0,1,255)">for(var property in data) <span style="color: rgb(0,1,2)">//property为key值</span><br />
</span>&nbsp;&nbsp;&nbsp; /*对于 java方法的返回值为Map的情况，DWR将其转化为一个Object，<br />
&nbsp;&nbsp;&nbsp;&nbsp; 其中Object的属性为原Map的key值，属性值为原Map相应的 value值*/<br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">{</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp; var bean = data[property];</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp; alert(bean.username);</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp; alert(bean.password);</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">}<br />
<br />
<span style="color: rgb(0,1,2)">如果知道key值，则可直接用:data.key拿到value</span><br />
</span><span style="color: rgb(0,1,255)"><span style="color: rgb(0,1,2)"><br />
<br />
</span></span></div>
<font size="3"><strong style="color: rgb(102,1,153)"></strong><strong style="color: rgb(102,1,153)">调</strong><strong style="color: rgb(102,1,153)">用有</strong><strong style="color: rgb(102,1,153)">List</strong><strong style="color: rgb(102,1,153)">、</strong><strong style="color: rgb(102,1,153)">Set</strong><strong style="color: rgb(102,1,153)">或者</strong><strong style="color: rgb(102,1,153)">Map</strong><strong style="color: rgb(102,1,153)">参数的</strong><strong style="color: rgb(102,1,153)">java</strong><strong style="color: rgb(102,1,153)">方法<br />
</strong></font>
<div style="margin-left: 40px"><br />
在dwr.xml的&lt;dwr&gt;标签内加入:&lt;signatures&gt;标签。<br />
<p style="color: rgb(0,1,255); font-family: Times New" align="left"><span style="color: rgb(255,1,255)">&lt;signatures&gt;标签是用来声明java方法中List、Set或者Map参数所包含的确切类，以便java代码作出判断，是<span style="color: rgb(0,1,2)">js--&gt;java</span>的。</span><br />
</p>
<span style="color: rgb(255,1,255)"><span style="color: rgb(0,1,2)">例参数是javabean的<font size="4"><span style="font-weight: bold">List</span></font>,则只要在参数为javabean的例子里构造时候加上[]即可，如下：<br />
<br />
</span></span><font size="4"><strong style="color: rgb(102,1,153)"><font size="3"><span style="font-weight: normal"><font size="2"><span style="color: rgb(0,1,2)"><span style="color: rgb(0,1,255)">var stu = [{name:"zhangsan",password:"zspassword"},{name:"lisi",password:"lspassword"}];</span></span></font></span></font></strong></font><br />
//把List当作数组来处理<br />
<font size="4"><strong style="color: rgb(102,1,153)"><font size="3"><span style="font-weight: normal"><font size="2"><span style="color: rgb(0,1,2)"><span style="color: rgb(0,1,255)">AAA.bbb(stu,callBack);<br />
<br />
</span></span></font></span></font></strong></font>并且在dwr.xml中增加如下的配置段<span style="color: rgb(255,153,2)">(刚才试验了下，不加也可以)</span><br />
<br />
<span style="color: rgb(0,1,255)">&lt;signatures&gt;<br />
&nbsp;&lt;![CDATA[<br />
&nbsp; import java.util.List;<br />
&nbsp; import com.dwr.AAA;&nbsp;&nbsp;&nbsp;&nbsp; //AAA的包路径要写完整<br />
&nbsp; import com.dwr.TestBean;&nbsp; //javabean<br />
&nbsp; AAA.bbb(<span style="color: rgb(0,1,2)">List&lt;TestBean&gt;</span>); <br />
&nbsp;]]&gt;<br />
&lt;/signatures&gt;</span><br />
<font size="4"><strong style="color: rgb(102,1,153)"><font size="3"><span style="font-weight: normal"><font size="2"><span style="color: rgb(0,1,2)"><span style="color: rgb(0,1,255)"><br />
</span></span></font></span></font></strong></font><span style="color: rgb(255,1,255)"><span style="color: rgb(0,1,2)">例参数是javabean的<font size="4"><span style="font-weight: bold">Map</span><font size="2">,</font></font></span></span><span style="color: rgb(255,1,255)"><span style="color: rgb(0,1,2)"><font size="4"><font size="2">key是String,value是javabean,</font></font></span></span><span style="color: rgb(255,1,255)"><span style="color: rgb(0,1,2)"><font size="4"><font size="2">如下:<br />
<span style="color: rgb(0,1,255)">var stu =</span><br style="color: rgb(0,1,255)" />
</font></font></span></span>
<div style="margin-left: 40px"><span style="color: rgb(0,1,255)">{</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; "key1":{name:"zhangsan",password:"zspassword"},</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">&nbsp;&nbsp;&nbsp; "key2":{name:"lisi",password:"lspassword"}</span><br style="color: rgb(0,1,255)" />
<span style="color: rgb(0,1,255)">};</span><br />
</div>
<font size="4"><strong style="color: rgb(102,1,153)"><font size="3"><span style="font-weight: normal"><font size="2"><span style="color: rgb(0,1,2)"><span style="color: rgb(0,1,255)">AAA.bbb(stu,callBack);</span></span></font></span></font></strong></font>
<div style="margin-left: 40px"><br />
</div>
并且在dwr.xml中增加如下的配置段<span style="color: rgb(255,153,2)">(刚才试验了下，不加也可以)</span><br />
<font size="2"><strong></strong></font><br />
<span style="color: rgb(0,1,255)">&lt;signatures&gt;<br />
&nbsp;&lt;![CDATA[<br />
&nbsp; import java.util.List;<br />
&nbsp; import com.dwr.AAA;&nbsp;&nbsp;&nbsp;&nbsp; //AAA的包路径要写完整<br />
&nbsp; import com.dwr.TestBean;&nbsp; //javabean<br />
&nbsp; AAA.bbb(<span style="color: rgb(0,1,2)">Map&lt;String,TestBean&gt;</span>); <br />
&nbsp;]]&gt;<br />
&lt;/signatures&gt;</span><br />
</div>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/183805.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-03-04 22:29 <a href="http://www.blogjava.net/xyzroundo/articles/183805.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struts+spring+hibernate+DWR</title><link>http://www.blogjava.net/xyzroundo/articles/183800.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Tue, 04 Mar 2008 14:13:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/183800.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/183800.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/183800.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/183800.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/183800.html</trackback:ping><description><![CDATA[<p>做了一个<span class="hilite1">DWR</span>的验证和<font face="Arial">eXtremeTable的应用的例子</font></p>
<p>前期的系统创建、struts、hibernate、<span class="hilite2">spring</span>的集成工作就不用说了，一路下来&#8230;&#8230;&#8230;&#8230;</p>
<p>主要看<span class="hilite1">DWR</span>的应用，它用于表单验证：</p>
<p>1、先看它的配置：</p>
<p>（1）在web.xml里加上：</p>
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span>&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">servlet</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span><span class="hilite1">dwr</span>-invoker</span><span class="tag"><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp; &nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">servlet-class</span><span class="tag">&gt;</span><span>uk.ltd.getahead.<span class="hilite1">dwr</span>.<span class="hilite1">DWR</span>Servlet</span><span class="tag"><span class="tag-name">servlet-class</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">init-param</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">param-name</span><span class="tag">&gt;</span><span>debug</span><span class="tag"><span class="tag-name">param-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">param-value</span><span class="tag">&gt;</span><span>true</span><span class="tag"><span class="tag-name">param-value</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">init-param</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">load-on-startup</span><span class="tag">&gt;</span><span>1</span><span class="tag"><span class="tag-name">load-on-startup</span><span class="tag">&gt;</span><span>&nbsp; &nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;</span><span class="tag"><span class="tag-name">servlet</span><span class="tag">&gt;</span><span>&nbsp;&nbsp; &nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp; &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">servlet-mapping</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span><span class="hilite1">dwr</span>-invoker</span><span class="tag"><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>/<span class="hilite1">dwr</span>/*</span><span class="tag"><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span class="tag"><span class="tag-name">servlet-mapping</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>&nbsp;</p>
<p>（2）再建一个类，用于获取验证输出信息的属性文件，这个文件是参考了良葛格 的<strong><font color="#ff0000"><span class="hilite1">DWR</span> 入門與應用（一）</font></strong></p>
<p>里的Book代码</p>
<p>java 代码</p>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">package</span><span>&nbsp;test.common; &nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;</span>
    <li class="alt"><span class="keyword">import</span><span>&nbsp;java.util.ResourceBundle; &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;</span>
    <li class="alt"><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;GetProperties{ &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;ResourceBundle&nbsp;resource; &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;GetProperties() &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resource&nbsp;=&nbsp;ResourceBundle.getBundle(</span><span class="string">"<span class="hilite1">dwr</span>Pro"</span><span>); &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;getDescription(String&nbsp;key)&nbsp; &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;resource.getString(key); &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>}&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>（3）编写属性文件<span class="hilite1">dwr</span>Pro_zh_CN.propertie（中文）和<span class="hilite1">dwr</span>_en.properties（英文）</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<ol class="dp-j">
    <li class="alt"><span><span>username_hasUsed&nbsp;=&nbsp;用户名已用，请选择别的用户名 &nbsp;&nbsp;</span></span>
    <li class=""><span>username_canUse&nbsp;&nbsp;=&nbsp;恭喜！用户名可以使用 &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;</span>
    <li class=""><span>username_hasUsed&nbsp;=username&nbsp;has&nbsp;used! &nbsp;&nbsp;</span>
    <li class="alt"><span>username_canUse&nbsp;&nbsp;=&nbsp;username&nbsp;can&nbsp;use!&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>&nbsp;</p>
<p>（4）配置<span class="hilite1">dwr</span>.xml，里面用了<span class="hilite2">spring</span>的bean 和java类</p>
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span class="tag">&lt;</span><span class="tag-name"><span class="hilite1">dwr</span></span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">allow</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">create</span><span>&nbsp;</span><span class="attribute">creator</span><span>=</span><span class="attribute-value">"<span class="hilite2">spring</span>"</span><span>&nbsp;</span><span class="attribute">javascript</span><span>=</span><span class="attribute-value">"userManager"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">param</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"beanName"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"userManager"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">include</span><span>&nbsp;</span><span class="attribute">method</span><span>=</span><span class="attribute-value">"findUserIsExist"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">create</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">create</span><span>&nbsp;</span><span class="attribute">creator</span><span>=</span><span class="attribute-value">"new"</span><span>&nbsp;</span><span class="attribute">javascript</span><span>=</span><span class="attribute-value">"User"</span><span>&nbsp;</span><span class="attribute">scope</span><span>=</span><span class="attribute-value">"application"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">param</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"class"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"test.common.GetProperties"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">create</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">allow</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span class="tag"><span class="tag-name"><span class="hilite1">dwr</span></span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
</ol>
</div>
<p><span class="hilite2">spring</span> beanName&nbsp; 的value =&#8220;userManager&#8221;从applicationContext.xml里取得</p>
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><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">"userManagerTarget"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"test.<span class="hilite2">spring</span>.serviceImpl.UserServiceImpl"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=""><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">"userDao"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">ref</span><span>&nbsp;</span><span class="attribute">bean</span><span>=</span><span class="attribute-value">"userDao"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span class="tag"><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span class="tag"><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;</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">"userManager"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"org.<span class="hilite2">spring</span>framework.aop.framework.ProxyFactoryBean"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</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">"proxyInterfaces"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>test.<span class="hilite2">spring</span>.service.IUserService</span><span class="tag"><span class="tag-name">value</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</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">"interceptorNames"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">list</span><span class="tag">&gt;</span><span>&nbsp; &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">idref</span><span>&nbsp;</span><span class="attribute">bean</span><span>=</span><span class="attribute-value">"transactionInterceptor"</span><span class="tag">/&gt;</span><span>&nbsp; &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">idref</span><span>&nbsp;</span><span class="attribute">bean</span><span>=</span><span class="attribute-value">"userManagerTarget"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">list</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;</span><span class="tag"><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;&nbsp;</span> </span></li>
</ol>
</div>
<p>这里应该大家都懂，就不罗嗦了</p>
<p>&nbsp;</p>
<p>（5）配好了这些，就可以在页面里用了</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span><!--page&#160;language=</span><span class="string">"java"</span><span>&#160;pageEncoding=</span><span class="string">"UTF-8"</span><span-->&nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;</span>
    <li class=""><span><!--ctype&#160;html&#160;public&#160;</sp--><span class="string">"-//W3C//DTD&nbsp;HTML&nbsp;4.01&nbsp;Transitional//EN"</span><span>&gt; &nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<script&#160;type='text javascript?&#160; src="dwr/</span"><span class="keyword">interface</span><span>/userManager.js'&gt;</script> &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<script&#160;type='text javascript?&#160; src="dwr/engine.js"></script> &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<script&#160;type='text javascript?&#160; src="dwr/</span"><span class="keyword">interface</span><span>/GetProperties.js'&gt;</script> &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<script&#160;type='text javascript?> 
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> 
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> 
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> 
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> 
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</script> &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">"0"</span><span>&gt; &nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <tr>
    </tr>
    &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <td>&nbsp;</td>
    Login: &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <td>&nbsp;</td>
    <span class="string">"text"</span><span>&nbsp;name=</span><span class="string">"user.name"</span><span>&nbsp;id=</span><span class="string">"username"</span><span>&nbsp;onblur=</span><span class="string">"checkName()"</span><span>/&gt;<span class="string">"check_username"</span><span>&gt;</span> &nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <tr>
    </tr>
    &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <td>&nbsp;</td>
    Password: &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <td>&nbsp;</td>
    <span class="string">"password"</span><span>&nbsp;name=</span><span class="string">"user.password"</span><span>&nbsp;id=</span><span class="string">"username"</span><span>&nbsp;onblur=</span><span class="string">"checkpassword()"</span><span>/&gt;<span class="string">"check_password"</span><span>&gt;</span> &nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <tr>
    </tr>
    &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">"2"</span><span>&nbsp;align=</span><span class="string">"center"</span><span>&gt; &nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class="alt"></li>
</ol>
</div>
<p>&nbsp;</p>
<p>这里当填了Login框，当光标从输入框移开时就实行了</p>
<div class="code_title">js 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-c">
    <li class="alt"><span><span class="keyword">function</span><span>&nbsp;checkName() &nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">var</span><span>&nbsp;username&nbsp;=&nbsp;document.userForm.username.value; &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;userManager.findUserIsExist(username,callback); &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>&nbsp;</p>
<p><font face="Arial">userManager.findUserIsExist(username,callback)时关键，这里就用了</font></p>
<p><font face="Arial">&nbsp; <script src="dwr/interface/userManager.js" type="text/javascript"></script></font></p>
<p>读取<span class="hilite1">dwr</span>.xml的<font face="Arial">userManager，然后读取applicationContext.xml里<font face="Arial">userManager&nbsp; bean ，进而实行<font face="Arial">findUserIsExist方法。</font></font></font></span></span></span></p>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/183800.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-03-04 22:13 <a href="http://www.blogjava.net/xyzroundo/articles/183800.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>代码重构 </title><link>http://www.blogjava.net/xyzroundo/articles/182511.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Wed, 27 Feb 2008 08:32:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/182511.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/182511.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/182511.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/182511.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/182511.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 来源：http://www.blogjava.net/martinx今天无意中在springframework中见到这个函数this.getHibernateTemplate().findByExampl(Object&nbsp;obj)以前没注意到，看了一下源码，原来就是Criteria中的Example.以前代码如下package&nbsp;martin.xpost...&nbsp;&nbsp;<a href='http://www.blogjava.net/xyzroundo/articles/182511.html'>阅读全文</a><img src ="http://www.blogjava.net/xyzroundo/aggbug/182511.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-02-27 16:32 <a href="http://www.blogjava.net/xyzroundo/articles/182511.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate+Spring 对DAO的处理实列!</title><link>http://www.blogjava.net/xyzroundo/articles/182492.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Wed, 27 Feb 2008 07:44:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/182492.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/182492.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/182492.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/182492.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/182492.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 引用"Spring"手册上的话说: Hibernate+Spring显然是天生的结合.下面是我用spring处理的一个HibernateDAO实例,可以看到,代码量大大减少了.                        java代码:&nbsp;                                                 ...&nbsp;&nbsp;<a href='http://www.blogjava.net/xyzroundo/articles/182492.html'>阅读全文</a><img src ="http://www.blogjava.net/xyzroundo/aggbug/182492.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-02-27 15:44 <a href="http://www.blogjava.net/xyzroundo/articles/182492.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何使用Log4j？ </title><link>http://www.blogjava.net/xyzroundo/articles/178934.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Sat, 02 Feb 2008 01:36:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/178934.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/178934.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/178934.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/178934.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/178934.html</trackback:ping><description><![CDATA[<font size="2"><strong>来源:java涂鸦<br />
<br />
1、 Log4j是什么？<br />
</strong>&nbsp; Log4j可以帮助调试（有时候debug是发挥不了作 用的）和分析，要下载和了解更详细的内容，还是访问其官方网站吧：</font> <a href="http://jakarta.apache.org/log4j"><font size="2">http://jakarta.apache.org/log4j</font> </a><font size="2">。<br />
<br />
<strong>2、Log4j的概念</strong><br />
&nbsp;&nbsp;<!--startfragment --> Log4j中有三个主要的组件，它们分别是</font> <font size="2">Logger、Appender和Layout，L<!--startfragment -->og4j 允许开发人员定义多个Logger，每个Logger拥有自己的名字，Logger之间通过名字来表明隶属关系。有一个Logger称为Root，它永远存在，且不能通过名字检索或引用，可以通过Logger.getRootLogger()方法获得，其它Logger通过 Logger.getLogger(String name)方法。<br />
&nbsp;&nbsp; Appender则是用来指明将所有的log信息存放到什么地方，Log4j中支持多种appender，如<!--startfragment --></font> <font size="3"></font><font size="2">console、files、GUI components、NT Event Loggers等，一个Logger可以拥有多个Appender，也就是你既可以将Log信息输出到屏幕，同时存储到一个文件中。<br />
&nbsp;&nbsp; Layout的作用是控制Log信息的输出方式，也就是格式化输出的信息。<br />
&nbsp;&nbsp; Log4j中将要输出的Log信息定义了5种级别，依次为DEBUG、INFO、WARN、ERROR和FATAL，当输出时，只有级别高过配置中规定的级别的信息才能真正的输出，这样就很方便的来配置不同情况下要输出的内容，而不需要更改代码，这点实在是方便啊。<br />
<br />
<strong>3、Log4j的配置文件</strong><br />
&nbsp; 虽然可以不用配置文件，而在程序中实现配置，但这种方法在如今的系统开发中显然是不可取的，能采用配置文件的地方一定一定要用配置文件。Log4j支持两种格式的配置文件：XML格式和Java的property格式，本人更喜欢后者，首先看一个简单的例子吧，如下：<br />
<br />
</font><font color="#614db3"><font size="2">&nbsp; log4j.rootLogger=debug, <strong>stdout, R</strong><br />
&nbsp; log4j.appender.<strong>stdout</strong>=org.apache.log4j.ConsoleAppender<br />
&nbsp; log4j.appender.stdout.layout=org.apache.log4j.PatternLayout<br />
<br />
&nbsp; # Pattern to output the caller's file name and line number.<br />
&nbsp; log4j.appender.stdout.layout.ConversionPattern=%5p [%t] <strong>(%F:%L)</strong> - %m%n<br />
<br />
&nbsp; log4j.appender.<strong>R</strong>=org.apache.log4j.RollingFileAppender<br />
&nbsp; log4j.appender.R.File=example.log<br />
&nbsp; log4j.appender.R.MaxFileSize=</font> <font size="2"><strong>100KB<br />
</strong><br />
&nbsp; # Keep one backup file<br />
&nbsp; log4j.appender.R.MaxBackupIndex=1<br />
<br />
&nbsp; log4j.appender.R.layout=org.apache.log4j.PatternLayout<br />
&nbsp; log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
</font><font color="#000000"><font size="2">&nbsp; 首先，是设置root，格式为<!--startfragment --> log4j.rootLogger=[level],appenderName,&nbsp;...，其中level就是设置需要输出信息的级别，后面是appender的输出的目的地，<!--startfragment -->appenderName就是指定日志信息输出到哪个地方。您可以同时指定多个输出目的地。</font> <font size="2">配置日志信息输出目的地Appender，其语法为<br />
</font><font size="2">&nbsp; log4j.appender.appenderName = fully.qualified.name.of.appender.class<br />
&nbsp; log4j.appender.appenderName.option1 = value1<br />
&nbsp; ...<br />
&nbsp; log4j.appender.appenderName.option = valueN</font> <br />
<font size="2">Log4j提供的appender有以下几种：<br />
&nbsp; org.apache.log4j.ConsoleAppender（控制台）<br />
&nbsp; org.apache.log4j.FileAppender（文件）<br />
&nbsp; org.apache.log4j.DailyRollingFileAppender（每天产生一个日志文件）<br />
&nbsp; org.apache.log4j.RollingFileAppender（文件大小到达指定尺寸的时候产生新文件）<br />
&nbsp; org.apache.log4j.WriterAppender（将日志信息以流格式发送到任意指定的地方）<br />
</font></font></font><font color="#614db3"><font color="#000000"><font size="2">配置日志信息的格式（布局），其语法为：<br />
</font><font size="2">&nbsp; log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class<br />
&nbsp; log4j.appender.appenderName.layout.option1 = value1<br />
&nbsp; ....<br />
&nbsp; log4j.appender.appenderName.layout.option = valueN</font> <br />
<font size="2">Log4j提供的layout有以下几种：<br />
&nbsp; org.apache.log4j.HTMLLayout（以HTML表格形式布局），<br />
&nbsp; org.apache.log4j.PatternLayout（可以灵活地指定布局模式），<br />
&nbsp; org.apache.log4j.SimpleLayout（包含日志信息的级别和信息字符串），<br />
&nbsp; org.apache.log4j.TTCCLayout（包含日志产生的时间、线程、类别等等信息） <br />
<br />
</font></font></font><font color="#000000"><span style="font-size: 10.5pt"><font size="2"><span lang="EN-US">Log4J采用类似C语言中的printf函数的打印格式格式化日志信息，打印参数如下： %m 输出代码中指定的消息<O:P></O:P></span> </font></span></font>
<p><font color="#000000"><span style="font-size: 10.5pt"><font size="2">　　</font> <span lang="EN-US"><font size="2">%p 输出优先级，即DEBUG，INFO，WARN，ERROR，FATAL <br />
　　%r 输出自应用启动到输出该log信息耗费的毫秒数 <br />
　　%c 输出所属的类目，通常就是所在类的全名 <br />
　　%t 输出产生该日志事件的线程名 <br />
　　%n 输出一个回车换行符，Windows平台为&#8220;\r\n&#8221;，Unix平台为&#8220;\n&#8221; <br />
　　%d 输出日志时间点的日期或时间，默认格式为ISO8601，也可以在其后指定格式，比如：%d{yyy MMM dd HH:mm:ss,SSS}，输出类似：</font> </span></span><ST1:CHSDATE isrocdate="False" islunardate="False" day="18" month="10" year="2002"><span lang="EN-US" style="font-size: 10.5pt"><font size="2">2002年10月18日</font> </span></ST1:CHSDATE><span lang="EN-US" style="font-size: 10.5pt"><font size="2">22：10：28，921 <br />
　　%l 输出日志事件的发生位置，包括类目名、发生的线程，以及在代码中的行数。举例：Testlog4.main(TestLog4.java:10)</font> </span></font></p>
<br />
<font color="#614db3"><font color="#000000"><font size="2"><br />
<strong>4、Log4j在程序中的使用</strong> </font></font></font><font color="#614db3"><font color="#000000"><br />
</font><font color="#a0a0a0"><font color="#090909" size="2">&nbsp; 要在自己的程序中使用Log4j，首先需要将commons-logging.jar和logging-log4j-1.2.9.jar导入到构建路径中。然后再将log4j.properties放到src根目录下。这样就可以在程序中使用log4j了。在类中使用log4j，</font> </font></font><font color="#614db3"><font color="#a0a0a0"><font color="#090909" size="2">首先声明一个静态变量</font> </font></font><font color="#614db3"><font color="#a0a0a0"><font color="#090909" size="2">Logger logger=Logger.getLog("classname")；现在就可以使用了，用法如下：logger.debug("debug message")或者logger.info("info message")，看下面一个小例子：</font> </font></font><font color="#614db3"><font color="#a0a0a0"><br />
</font><br />
<font size="2">&nbsp; import com.foo.Bar;<br />
&nbsp; import org.apache.log4j.Logger;<br />
&nbsp;&nbsp;import org.apache.log4j.PropertyConfigurator;<br />
&nbsp;&nbsp;public class MyApp {<br />
&nbsp; &nbsp; static Logger logger = Logger.getLogger(MyApp.class.getName());<br />
&nbsp;&nbsp; &nbsp;public static void main(String[] args) {<br />
&nbsp;&nbsp;&nbsp; &nbsp; // BasicConfigurator replaced with PropertyConfigurator.<br />
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;PropertyConfigurator.configure(args[0]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("Entering application.");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bar bar = new Bar();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bar.doIt();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("Exiting application.");<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;}<br />
</font></font>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/178934.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-02-02 09:36 <a href="http://www.blogjava.net/xyzroundo/articles/178934.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>史上最简单的struts+spring+hibernate配置实例[修订版]</title><link>http://www.blogjava.net/xyzroundo/articles/178015.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Sun, 27 Jan 2008 06:13:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/178015.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/178015.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/178015.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/178015.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/178015.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 作者:NetFetch&nbsp;&nbsp; http://www.ad0.cn/netfetch本文不关心必须的JAR包，这个东东在网上能够找到很多，本文只关心如何配置，才能够让STRUTS SPRING HIBERNATE和MYSQL相关连。 开发环境：wsad5.1 Spring-Version: 1.1.4 Struts Framework 1.1 Hiberna...&nbsp;&nbsp;<a href='http://www.blogjava.net/xyzroundo/articles/178015.html'>阅读全文</a><img src ="http://www.blogjava.net/xyzroundo/aggbug/178015.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-01-27 14:13 <a href="http://www.blogjava.net/xyzroundo/articles/178015.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在myeclipse下整合spring和hibernate（转载）</title><link>http://www.blogjava.net/xyzroundo/articles/177651.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Fri, 25 Jan 2008 01:37:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/177651.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/177651.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/177651.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/177651.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/177651.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 来源:互联网整合hibernate和spring这样的文章已经很多了,下面我们来看看如何利用myeclipse的功能为整合提速咯1.首先,创建工程,可以直接选创建J2EE web工程&nbsp;&nbsp; (这....就不用贴图了吧)2.导入spring, 选择myeclipse的add spring capabilities,注意把copy .....打勾(注,如果...&nbsp;&nbsp;<a href='http://www.blogjava.net/xyzroundo/articles/177651.html'>阅读全文</a><img src ="http://www.blogjava.net/xyzroundo/aggbug/177651.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-01-25 09:37 <a href="http://www.blogjava.net/xyzroundo/articles/177651.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 Spring 更好地处理 Struts 动作 三种整合 Struts 应用程序与 Spring 的方式</title><link>http://www.blogjava.net/xyzroundo/articles/177254.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Wed, 23 Jan 2008 05:53:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/177254.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/177254.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/177254.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/177254.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/177254.html</trackback:ping><description><![CDATA[<p><a name="IDA2EWW"><strong><font size="4">来源:http://www.blogjava.net/shmily432685<br />
</font></strong></a></p>
<p><a name="IDA2EWW"><strong><font size="4">整合 Struts 和 </font></strong></a><strong><font size="4"><a title="心得与体会" href="../../shmily432685">spring in action</a></font></strong></p>
<p>与 Struts 相似，Spring 可以作为一个 MVC 实现。这两种框架都具有自己的优点和缺点，尽管大部分人同意 Struts 在
MVC 方面仍然是最好的。很多开发团队已经学会在时间紧迫的时候利用 Struts 作为构造高品质软件的基础。Struts
具有如此大的推动力，以至于开发团队宁愿整合 <a title="心得与体会" href="../../shmily432685">spring in action</a> 框架的特性，而不愿意转换成 <a title="心得与体会" href="../../shmily432685">spring in action</a> MVC。没必要进行转换对您来说是一个好消息。Spring 架构允许您将 Struts 作为 Web 框架连接到基于 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的业务和持久层。最后的结果就是现在一切条件都具备了。</p>
<p>在接下来的小窍门中，您将会了解到三种将 Struts MVC 整合到 <a title="心得与体会" href="../../shmily432685">spring in action</a> 框架的方法。我将揭示每种方法的缺陷并且对比它们的优点。 一旦您了解到所有三种方法的作用，我将会向您展示一个令人兴奋的应用程序，这个程序使用的是这三种方法中我最喜欢的一种。</p>
<p><a name="IDADFWW"><strong><font size="4">三个小窍门</font></strong></a></p>
<p>接下来的每种整合技术（或者窍门）都有自己的优点和特点。我偏爱其中的一种，但是我知道这三种都能够加深您对 Struts 和 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的理解。在处理各种不同情况的时候，这将给您提供一个广阔的选择范围。方法如下：</p>
<ul>
    <li>使用 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的 <code><font face="Courier" size="2">ActionSupport</font></code> 类整合 Structs
    </li>
    <li>使用 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的 <code><font face="Courier" size="2">DelegatingRequestProcessor</font></code> 覆盖 Struts 的 <code><font face="Courier" size="2">RequestProcessor </font></code>
    </li>
    <li>将 Struts <code><font face="Courier" size="2">Action</font></code> 管理委托给 <a title="心得与体会" href="../../shmily432685">spring in action</a> 框架</li>
</ul>
<p><a name="IDAAGWW"><strong>装载应用程序环境</strong></a></p>
<p>无论您使用哪种技术，都需要使用 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的 <code><font face="Courier" size="2">ContextLoaderPlugin</font></code> 为 Struts 的 <code><font face="Courier" size="2">ActionServlet</font></code> 装载 <a title="心得与体会" href="../../shmily432685">spring in action</a> 应用程序环境。就像添加任何其他插件一样，简单地向您的 struts-config.xml 文件添加该插件，如下所示：</p>
<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>
            <pre><code><br />
            <font face="Lucida Console">&lt;plug-in className=<br />
            "org.springframework.web.struts.ContextLoaderPlugIn"&gt;<br />
            &lt;set-property property=<br />
            "contextConfigLocation" value="/WEB-INF/beans.xml"/&gt;<br />
            &lt;/plug-in&gt;<br />
            </font></code></pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>前面已经提到过，在 <a href="http://www-128.ibm.com/developerworks/cn/java/j-sr2.html#download"><font color="#996699">下载</font></a> 部分，您能够找到这三个完全可使用的例子的完整源代码。每个例子都为一个书籍搜索应用程序提供一种不同的 Struts 和 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的整合方法。您可以在这里看到例子的要点，但是您也可以下载应用程序以查看所有的细节。</p>
<p><a name="IDAZGWW"><strong><font size="4">窍门 1. 使用 </font></strong></a><strong><font size="4"><a title="心得与体会" href="../../shmily432685">spring in action</a> 的 ActionSupport</font></strong></p>
<p>手动创建一个 <a title="心得与体会" href="../../shmily432685">spring in action</a> 环境是一种整合 Struts 和 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的最直观的方式。为了使它变得更简单，Spring 提供了一些帮助。为了方便地获得 <a title="心得与体会" href="../../shmily432685">spring in action</a> 环境，<code><font face="Courier" size="2">org.springframework.web.struts.ActionSupport</font></code> 类提供了一个 <code><font face="Courier" size="2">getWebApplicationContext()</font></code> 方法。您所做的只是从 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的 <code><font face="Courier" size="2">ActionSupport</font></code> 而不是 Struts <code><font face="Courier" size="2">Action</font></code> 类扩展您的动作，如清单 1 所示：</p>
<br />
<a name="IDAUHWW"><strong>清单 1. 使用 ActionSupport 整合 Struts</strong></a><br />
<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>
            <pre><code><br />
            <font face="Lucida Console">package ca.nexcel.books.actions;<br />
            <br />
            import java.io.IOException;<br />
            <br />
            import javax.servlet.ServletException;<br />
            import javax.servlet.http.HttpServletRequest;<br />
            import javax.servlet.http.HttpServletResponse;<br />
            <br />
            import org.apache.struts.action.ActionError;<br />
            import org.apache.struts.action.ActionErrors;<br />
            import org.apache.struts.action.ActionForm;<br />
            import org.apache.struts.action.ActionForward;<br />
            import org.apache.struts.action.ActionMapping;<br />
            import org.apache.struts.action.DynaActionForm;<br />
            import org.springframework.context.ApplicationContext;<br />
            import org.springframework.web.struts.ActionSupport;<br />
            <br />
            import ca.nexcel.books.beans.Book;<br />
            import ca.nexcel.books.business.BookService;<br />
            <br />
            public class SearchSubmit extends ActionSupport {   <strong>|(1)</strong><br />
            <br />
            <br />
            public ActionForward execute(<br />
            ActionMapping mapping,<br />
            ActionForm form,<br />
            HttpServletRequest request,<br />
            HttpServletResponse response)<br />
            throws IOException, ServletException {<br />
            <br />
            DynaActionForm searchForm = (DynaActionForm) form;<br />
            String isbn = (String) searchForm.get("isbn");<br />
            <br />
            //the old fashion way<br />
            //BookService bookService = new BookServiceImpl();<br />
            <br />
            ApplicationContext ctx = <br />
            getWebApplicationContext();    <strong>|(2)</strong><br />
            BookService bookService = <br />
            (BookService) ctx.getBean("bookService");   <strong>|(3)</strong><br />
            <br />
            Book book = bookService.read(isbn.trim());<br />
            <br />
            if (null == book) {<br />
            ActionErrors errors = new ActionErrors();<br />
            errors.add(ActionErrors.GLOBAL_ERROR,new ActionError<br />
            ("message.notfound"));<br />
            saveErrors(request, errors);<br />
            return mapping.findForward("failure") ;<br />
            }<br />
            <br />
            request.setAttribute("book", book);<br />
            return mapping.findForward("success");<br />
            }<br />
            }<br />
            </font></code></pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>让我们快速思考一下这里到底发生了什么。在 (1) 处，我通过从 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的 <code><font face="Courier" size="2">ActionSupport</font></code> 类而不是 Struts 的 <code><font face="Courier" size="2">Action</font></code> 类进行扩展，创建了一个新的 <code><font face="Courier" size="2">Action</font></code>。在 (2) 处，我使用 <code><font face="Courier" size="2">getWebApplicationContext()</font></code> 方法获得一个 <code><font face="Courier" size="2">ApplicationContext</font></code>。为了获得业务服务，我使用在 (2) 处获得的环境在 (3) 处查找一个 <a title="心得与体会" href="../../shmily432685">spring in action</a> bean。</p>
<p>这种技术很简单并且易于理解。不幸的是，它将 Struts 动作与 <a title="心得与体会" href="../../shmily432685">spring in action</a> 框架耦合在一起。如果您想替换掉 <a title="心得与体会" href="../../shmily432685">spring in action</a>，那么您必须重写代码。并且，由于 Struts 动作不在 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的控制之下，所以它不能获得 <a title="心得与体会" href="../../shmily432685">spring in action</a> AOP 的优势。当使用多重独立的 <a title="心得与体会" href="../../shmily432685">spring in action</a> 环境时，这种技术可能有用，但是在大多数情况下，这种方法不如另外两种方法合适。</p>
<p><a name="IDA0A4W"><strong><font size="4">窍门 2. 覆盖 RequestProcessor</font></strong></a></p>
<p>将 <a title="心得与体会" href="../../shmily432685">spring in action</a> 从 Struts 动作中分离是一个更巧妙的设计选择。分离的一种方法是使用 <code><font face="Courier" size="2">org.springframework.web.struts.DelegatingRequestProcessor</font></code> 类来覆盖 Struts 的 <code><font face="Courier" size="2">RequestProcessor</font></code> 处理程序，如清单 2 所示：</p>
<br />
<a name="IDANB4W"><strong>清单 2. 通过 </strong></a><strong><a title="心得与体会" href="../../shmily432685">spring in action</a> 的 DelegatingRequestProcessor 进行整合</strong><br />
<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>
            <pre><code><br />
            <font face="Lucida Console">&lt;?xml version="1.0" encoding="ISO-8859-1" ?&gt;<br />
            <br />
            &lt;!DOCTYPE struts-config PUBLIC<br />
            "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"<br />
            "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"&gt;<br />
            <br />
            &lt;struts-config&gt;<br />
            &lt;form-beans&gt;<br />
            &lt;form-bean name="searchForm" <br />
            type="org.apache.struts.validator.DynaValidatorForm"&gt;<br />
            &lt;form-property name="isbn"    type="java.lang.String"/&gt;<br />
            &lt;/form-bean&gt;<br />
            <br />
            &lt;/form-beans&gt;<br />
            <br />
            &lt;global-forwards type="org.apache.struts.action.ActionForward"&gt;<br />
            &lt;forward   name="welcome"                path="/welcome.do"/&gt;<br />
            &lt;forward   name="searchEntry"            path="/searchEntry.do"/&gt;<br />
            &lt;forward   name="searchSubmit"           path="/searchSubmit.do"/&gt;<br />
            &lt;/global-forwards&gt;<br />
            <br />
            &lt;action-mappings&gt;<br />
            &lt;action    path="/welcome" forward="/WEB-INF/pages/welcome.htm"/&gt;<br />
            &lt;action    path="/searchEntry" forward="/WEB-INF/pages/search.jsp"/&gt;<br />
            &lt;action    path="/searchSubmit" <br />
            type="ca.nexcel.books.actions.SearchSubmit"<br />
            input="/searchEntry.do"<br />
            validate="true"<br />
            name="searchForm"&gt;<br />
            &lt;forward name="success" path="/WEB-INF/pages/detail.jsp"/&gt;<br />
            &lt;forward name="failure" path="/WEB-INF/pages/search.jsp"/&gt;<br />
            &lt;/action&gt;  <br />
            <br />
            &lt;/action-mappings&gt;<br />
            <br />
            &lt;message-resources parameter="ApplicationResources"/&gt;<br />
            <br />
            &lt;controller processorClass="org.springframework.web.struts.<br />
            DelegatingRequestProcessor"/&gt; <strong>|(1)</strong><br />
            <br />
            &lt;plug-in className="org.apache.struts.validator.ValidatorPlugIn"&gt;<br />
            &lt;set-property property="pathnames" <br />
            value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/&gt;<br />
            &lt;/plug-in&gt;<br />
            <br />
            <br />
            &lt;plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"&gt;<br />
            &lt;set-property property="csntextConfigLocation" value="/WEB-INF/beans.xml"/&gt;<br />
            &lt;/plug-in&gt;<br />
            <br />
            &lt;/struts-config&gt;<br />
            </font></code></pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>我利用了 <code><font face="Courier" size="2">&lt;controller&gt;</font></code> 标记来用 <code><font face="Courier" size="2">DelegatingRequestProcessor</font></code> 覆盖默认的 Struts <code><font face="Courier" size="2">RequestProcessor</font></code>。下一步是在我的 <a title="心得与体会" href="../../shmily432685">spring in action</a> 配置文件中注册该动作，如清单 3 所示：</p>
<br />
<a name="IDAGC4W"><strong>清单 3. 在 </strong></a><strong><a title="心得与体会" href="../../shmily432685">spring in action</a> 配置文件中注册一个动作</strong><br />
<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>
            <pre><code><br />
            <font face="Lucida Console">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
            &lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" <br />
            "http://www.springframework.org/dtd/spring-beans.dtd"&gt;<br />
            <br />
            &lt;beans&gt;<br />
            &lt;bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/&gt;<br />
            <br />
            &lt;bean name="/searchSubmit" <br />
            class="ca.nexcel.books.actions.SearchSubmit"&gt; <strong>|(1)</strong><br />
            &lt;property name="bookService"&gt;<br />
            &lt;ref bean="bookService"/&gt;<br />
            &lt;/property&gt;<br />
            &lt;/bean&gt;<br />
            &lt;/beans&gt;<br />
            </font></code></pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>注意：在 (1) 处，我使用名称属性注册了一个 bean，以匹配 struts-config 动作映射名称。<code><font face="Courier" size="2">SearchSubmit</font></code> 动作揭示了一个 JavaBean 属性，允许 <a title="心得与体会" href="../../shmily432685">spring in action</a> 在运行时填充属性，如清单 4 所示：</p>
<br />
<a name="IDAXC4W"><strong>清单 4. 具有 JavaBean 属性的 Struts 动作</strong></a><br />
<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>
            <pre><code><br />
            <font face="Lucida Console">package ca.nexcel.books.actions;<br />
            <br />
            import java.io.IOException;<br />
            <br />
            import javax.servlet.ServletException;<br />
            import javax.servlet.http.HttpServletRequest;<br />
            import javax.servlet.http.HttpServletResponse;<br />
            <br />
            import org.apache.struts.action.Action;<br />
            import org.apache.struts.action.ActionError;<br />
            import org.apache.struts.action.ActionErrors;<br />
            import org.apache.struts.action.ActionForm;<br />
            import org.apache.struts.action.ActionForward;<br />
            import org.apache.struts.action.ActionMapping;<br />
            import org.apache.struts.action.DynaActionForm;<br />
            <br />
            import ca.nexcel.books.beans.Book;<br />
            import ca.nexcel.books.business.BookService;<br />
            <br />
            public class SearchSubmit extends Action {<br />
            <br />
            private BookService bookService;<br />
            public BookService getBookService() {<br />
            return bookService;<br />
            }<br />
            <br />
            public void setBookService(BookService bookService) { <strong>| (1)</strong><br />
            this.bookService = bookService; <br />
            } <br />
            <br />
            public ActionForward execute(<br />
            ActionMapping mapping,<br />
            ActionForm form,<br />
            HttpServletRequest request,<br />
            HttpServletResponse response)<br />
            throws IOException, ServletException {<br />
            <br />
            DynaActionForm searchForm = (DynaActionForm) form;<br />
            String isbn = (String) searchForm.get("isbn");<br />
            <br />
            Book book = getBookService().read(isbn.trim());  <strong>|(2)</strong><br />
            <br />
            if (null == book) {<br />
            ActionErrors errors = new ActionErrors();<br />
            errors.add(ActionErrors.GLOBAL_ERROR,new ActionError("message.notfound"));<br />
            saveErrors(request, errors);<br />
            return mapping.findForward("failure") ;<br />
            }<br />
            <br />
            request.setAttribute("book", book);<br />
            return mapping.findForward("success");<br />
            }<br />
            <br />
            }<br />
            </font></code></pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>在清单 4 中，您可以了解到如何创建 Struts 动作。在 (1) 处，我创建了一个 JavaBean 属性。<code><font face="Courier" size="2">DelegatingRequestProcessor</font></code>自动地配置这种属性。这种设计使 Struts 动作并不知道它正被 <a title="心得与体会" href="../../shmily432685">spring in action</a> 管理，并且使您能够利用 Sping 的动作管理框架的所有优点。由于您的 Struts 动作注意不到 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的存在，所以您不需要重写您的 Struts 代码就可以使用其他控制反转容器来替换掉 <a title="心得与体会" href="../../shmily432685">spring in action</a>。</p>
<p><code><font face="Courier" size="2">DelegatingRequestProcessor</font></code> 方法的确比第一种方法好，但是仍然存在一些问题。如果您使用一个不同的 <code><font face="Courier" size="2">RequestProcessor</font></code>，则需要手动整合 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的 <code><font face="Courier" size="2">DelegatingRequestProcessor</font></code>。添加的代码会造成维护的麻烦并且将来会降低您的应用程序的灵活性。此外，还有过一些使用一系列命令来代替 Struts <code><font face="Courier" size="2">RequestProcessor</font></code> 的传闻。 这种改变将会对这种解决方法的使用寿命造成负面的影响。</p>
<p><a name="IDAYD4W"><strong><font size="4">窍门 3. 将动作管理委托给 </font></strong></a><strong><font size="4"><a title="心得与体会" href="../../shmily432685">spring in action</a></font></strong></p>
<p>一个更好的解决方法是将 Strut 动作管理委托给 <a title="心得与体会" href="../../shmily432685">spring in action</a>。您可以通过在 <code><font face="Courier" size="2">struts-config</font></code> 动作映射中注册一个代理来实现。代理负责在 <a title="心得与体会" href="../../shmily432685">spring in action</a> 环境中查找 Struts 动作。由于动作在 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的控制之下，所以它可以填充动作的 JavaBean 属性，并为应用诸如 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的 AOP 拦截器之类的特性带来了可能。 </p>
<p>清单 5 中的 <code><font face="Courier" size="2">Action</font></code> 类与清单 4 中的相同。但是 struts-config 有一些不同：</p>
<br />
<a name="IDANE4W"><strong>清单 5. </strong></a><strong><a title="心得与体会" href="../../shmily432685">spring in action</a> 整合的委托方法</strong><br />
<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>
            <pre><code><br />
            <font face="Lucida Console">&lt;?xml version="1.0" encoding="ISO-8859-1" ?&gt;<br />
            <br />
            &lt;!DOCTYPE struts-config PUBLIC<br />
            "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"<br />
            "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"&gt;<br />
            <br />
            &lt;struts-config&gt;<br />
            &lt;form-beans&gt;<br />
            &lt;form-bean name="searchForm" <br />
            type="org.apache.struts.validator.DynaValidatorForm"&gt;<br />
            &lt;form-property name="isbn"    type="java.lang.String"/&gt;<br />
            &lt;/form-bean&gt;<br />
            <br />
            &lt;/form-beans&gt;<br />
            <br />
            &lt;global-forwards type="org.apache.struts.action.ActionForward"&gt;<br />
            &lt;forward   name="welcome"                path="/welcome.do"/&gt;<br />
            &lt;forward   name="searchEntry"            path="/searchEntry.do"/&gt;<br />
            &lt;forward   name="searchSubmit"           path="/searchSubmit.do"/&gt;<br />
            &lt;/global-forwards&gt;<br />
            <br />
            &lt;action-mappings&gt;<br />
            &lt;action    path="/welcome" forward="/WEB-INF/pages/welcome.htm"/&gt;<br />
            &lt;action    path="/searchEntry" forward="/WEB-INF/pages/search.jsp"/&gt;<br />
            &lt;action    path="/searchSubmit" <br />
            type="org.springframework.web.struts.DelegatingActionProxy" <strong>|(1)</strong><br />
            input="/searchEntry.do"<br />
            validate="true"<br />
            name="searchForm"&gt;<br />
            &lt;forward name="success" path="/WEB-INF/pages/detail.jsp"/&gt;<br />
            &lt;forward name="failure" path="/WEB-INF/pages/search.jsp"/&gt;<br />
            &lt;/action&gt;  <br />
            <br />
            &lt;/action-mappings&gt;<br />
            <br />
            &lt;message-resources parameter="ApplicationResources"/&gt;<br />
            <br />
            <br />
            &lt;plug-in className="org.apache.struts.validator.ValidatorPlugIn"&gt;<br />
            &lt;set-property <br />
            property="pathnames" <br />
            value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/&gt;<br />
            &lt;/plug-in&gt;<br />
            <br />
            <br />
            &lt;plug-in <br />
            className="org.springframework.web.struts.ContextLoaderPlugIn"&gt;<br />
            &lt;set-property property="contextConfigLocation" value="/WEB-INF/beans.xml"/&gt;<br />
            &lt;/plug-in&gt;<br />
            <br />
            <br />
            &lt;/struts-config&gt;<br />
            </font></code></pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>清单 5 是一个典型的 struts-config.xml 文件，只有一个小小的差别。它注册 <a title="心得与体会" href="../../shmily432685">spring in action</a> 代理类的名称，而不是声明动作的类名，如（1）处所示。DelegatingActionProxy 类使用动作映射名称查找 <a title="心得与体会" href="../../shmily432685">spring in action</a> 环境中的动作。这就是我们使用 <code><font face="Courier" size="2">ContextLoaderPlugIn</font></code> 声明的环境。</p>
<p>将一个 Struts 动作注册为一个 <a title="心得与体会" href="../../shmily432685">spring in action</a> bean 是非常直观的，如清单 6 所示。我利用动作映射使用 <code><font face="Courier" size="2">&lt;bean&gt;</font></code> 标记的名称属性（在这个例子中是 "<code><font face="Courier" size="2">/searchSubmit</font></code>"）简单地创建了一个 bean。这个动作的 JavaBean 属性像任何 <a title="心得与体会" href="../../shmily432685">spring in action</a> bean 一样被填充： </p>
<br />
<a name="IDAIF4W"><strong>清单 6. 在 </strong></a><strong><a title="心得与体会" href="../../shmily432685">spring in action</a> 环境中注册一个 Struts 动作</strong><br />
<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>
            <pre><code><br />
            <font face="Lucida Console">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
            &lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" <br />
            "http://www.springframework.org/dtd/spring-beans.dtd"&gt;<br />
            <br />
            &lt;beans&gt;<br />
            &lt;bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/&gt;<br />
            <br />
            &lt;bean name="/searchSubmit"   <br />
            class="ca.nexcel.books.actions.SearchSubmit"&gt;<br />
            &lt;property name="bookService"&gt;<br />
            &lt;ref bean="bookService"/&gt;<br />
            &lt;/property&gt;<br />
            &lt;/bean&gt;<br />
            <br />
            &lt;/beans&gt;<br />
            </font></code></pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p><a name="IDAOF4W"><strong><font size="4">动作委托的优点</font></strong></a></p>
<p>动作委托解决方法是这三种方法中最好的。Struts 动作不了解 <a title="心得与体会" href="../../shmily432685">spring in action</a>，不对代码作任何改变就可用于非 <a title="心得与体会" href="../../shmily432685">spring in action</a> 应用程序中。<code><font face="Courier" size="2">RequestProcessor</font></code> 的改变不会影响它，并且它可以利用 <a title="心得与体会" href="../../shmily432685">spring in action</a> AOP 特性的优点。 </p>
<p>动作委托的优点不止如此。一旦让 <a title="心得与体会" href="../../shmily432685">spring in action</a> 控制您的 Struts 动作，您就可以使用 <a title="心得与体会" href="../../shmily432685">spring in action</a> 给动作补充更强的活力。例如，没有 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的话，所有的 Struts 动作都必须是线程安全的。如果您设置 <code><font face="Courier" size="2">&lt;bean&gt;</font></code> 标记的 singleton 属性为&#8220;false&#8221;，那么不管用何种方法，您的应用程序都将在每一个请求上有一个新生成的动作对象。您可能不需要这种特性，但是把它放在您的工具箱中也很好。您也可以利用 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的生命周期方法。例如，当实例化 Struts 动作时，<code><font face="Courier" size="2">&lt;bean&gt;</font></code> 标记的 init-method 属性被用于运行一个方法。类似地，在从容器中删除 bean 之前，destroy-method 属性执行一个方法。这些方法是管理昂贵对象的好办法，它们以一种与 Servlet 生命周期相同的方式进行管理。</p>
<p><a name="IDAEG4W"><strong><font size="4">拦截 Struts</font></strong></a></p>
<p>前面提到过，通过将 Struts 动作委托给 <a title="心得与体会" href="../../shmily432685">spring in action</a> 框架而整合 Struts 和 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的一个主要的优点是：您可以将 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的 AOP 拦截器应用于您的 Struts 动作。通过将 <a title="心得与体会" href="../../shmily432685">spring in action</a> 拦截器应用于 Struts 动作，您可以用最小的代价处理横切关注点。</p>
<p>虽然 <a title="心得与体会" href="../../shmily432685">spring in action</a> 提供很多内置拦截器，但是我将向您展示如何创建自己的拦截器并把它应用于一个 Struts 动作。为了使用拦截器，您需要做三件事：</p>
<ol>
    <li>创建拦截器。
    </li>
    <li>注册拦截器。
    </li>
    <li>声明在何处拦截代码。</li>
</ol>
<p>这看起来非常简单的几句话却非常强大。例如，在清单 7 中，我为 Struts 动作创建了一个日志记录拦截器。 这个拦截器在每个方法调用之前打印一句话：</p>
<br />
<a name="IDAUG4W"><strong>清单 7. 一个简单的日志记录拦截器</strong></a><br />
<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>
            <pre><code><br />
            <font face="Lucida Console">package ca.nexcel.books.interceptors;<br />
            <br />
            import org.springframework.aop.MethodBeforeAdvice;<br />
            <br />
            import java.lang.reflect.Method;<br />
            <br />
            public class LoggingInterceptor implements MethodBeforeAdvice {<br />
            <br />
            public void before(Method method, Object[] objects, Object o) throws Throwable {<br />
            System.out.println("logging before!");<br />
            }<br />
            }<br />
            </font></code></pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>这个拦截器非常简单。<code><font face="Courier" size="2">before()</font></code> 方法在拦截点中每个方法之前运行。在本例中，它打印出一句话，其实它可以做您想做的任何事。下一步就是在 <a title="心得与体会" href="../../shmily432685">spring in action</a> 配置文件中注册这个拦截器，如清单 8 所示：</p>
<br />
<a name="IDADH4W"><strong>清单 8. 在 </strong></a><strong><a title="心得与体会" href="../../shmily432685">spring in action</a> 配置文件中注册拦截器</strong><br />
<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>
            <pre><code><br />
            <font face="Lucida Console">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
            &lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" <br />
            "http://www.springframework.org/dtd/spring-beans.dtd"&gt;<br />
            <br />
            &lt;beans&gt;<br />
            &lt;bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/&gt;<br />
            <br />
            &lt;bean name="/searchSubmit" <br />
            class="ca.nexcel.books.actions.SearchSubmit"&gt;<br />
            &lt;property name="bookService"&gt;<br />
            &lt;ref bean="bookService"/&gt;<br />
            &lt;/property&gt;<br />
            &lt;/bean&gt;<br />
            <br />
            &lt;!--  Interceptors --&gt; <br />
            &lt;bean name="logger"    <br />
            class="ca.nexcel.books.interceptors.LoggingInterceptor"/&gt; <strong>|(1)</strong><br />
            <br />
            &lt;!-- AutoProxies --&gt;<br />
            &lt;bean name="loggingAutoProxy" <br />
            class="org.springframework.aop.framework.autoproxy.<br />
            BeanNameAutoProxyCreator"&gt; <strong>|(2)</strong><br />
            &lt;property name="beanNames"&gt;<br />
            &lt;value&gt;/searchSubmit&lt;/valuesgt; <strong>|(3)</strong><br />
            &lt;/property&gt;<br />
            &lt;property name="interceptorNames"&gt;<br />
            &lt;list&gt;<br />
            &lt;value&gt;logger&lt;/value&gt; <strong>|(4)</strong><br />
            &lt;/list&gt;<br />
            &lt;/property&gt;<br />
            &lt;/bean&gt;<br />
            <br />
            &lt;/beans&gt;<br />
            </font></code></pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>您可能已经注意到了，清单 8 扩展了 <a href="http://www-128.ibm.com/developerworks/cn/java/j-sr2.html#code6"><font color="#996699">清单 6</font></a> 中所示的应用程序以包含一个拦截器。具体细节如下：</p>
<ul>
    <li>在 (1) 处，我注册了这个拦截器。
    </li>
    <li>在 (2) 处，我创建了一个 bean 名称自动代理，它描述如何应用拦截器。还有其他的方法定义拦截点，但是这种方法常见而简便。
    </li>
    <li>在 (3) 处，我将 Struts 动作注册为将被拦截的 bean。如果您想要拦截其他的 Struts 动作，则只需要在 "beanNames" 下面创建附加的 <code><font face="Courier" size="2">&lt;value&gt;</font></code> 标记。
    </li>
    <li>在 (4) 处，当拦截发生时，我执行了在 (1) 处创建的拦截器 bean 的名称。这里列出的所有拦截器都应用于&#8220;beanNames&#8221;。</li>
</ul>
<p>就是这样。就像这个例子所展示的，将您的 Struts 动作置于 <a title="心得与体会" href="../../shmily432685">spring in action</a> 框架的控制之下，为处理您的 Struts 应用程序提供了一系列全新的选择。在本例中，使用动作委托可以轻松地利用 <a title="心得与体会" href="../../shmily432685">spring in action</a> 拦截器提高 Struts 应用程序中的日志记录能力。</p>
<br />
<p><a name="IDAFI4W"><strong><font size="4">结束语</font></strong></a></p>
<p>在本文中，您已经学习了将 Struts 动作整合到 <a title="心得与体会" href="../../shmily432685">spring in action</a> 框架中的三种窍门。使用 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的 <code><font face="Courier" size="2">ActionSupport</font></code> 来整合 Struts（第一种窍门中就是这样做的）简单而快捷，但是会将 Struts 动作与 <a title="心得与体会" href="../../shmily432685">spring in action</a> 框架耦合在一起。如果您需要将应用程序移植到一个不同的框架，则需要重写代码。第二种解决方法通过委托 <code><font face="Courier" size="2">RequestProcessor</font></code> 巧妙地解开代码的耦合，但是它的可扩展性不强，并且当 Struts 的 <code><font face="Courier" size="2">RequestProcessor</font></code> 变成一系列命令时，这种方法就持续不了很长时间。第三种方法是这三种方法中最好的：将 Struts 动作委托给 <a title="心得与体会" href="../../shmily432685">spring in action</a> 框架可以使代码解耦，从而使您可以在您的 Struts 应用程序中利用 <a title="心得与体会" href="../../shmily432685">spring in action</a> 的特性（比如日志记录拦截器）。</p>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/177254.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-01-23 13:53 <a href="http://www.blogjava.net/xyzroundo/articles/177254.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Myeclipse平台struts+hibernate+spring项目开发示例来来源</title><link>http://www.blogjava.net/xyzroundo/articles/177220.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Wed, 23 Jan 2008 03:13:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/177220.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/177220.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/177220.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/177220.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/177220.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 来源:http://www.blogjava.net/shmily432685开发前准备:&nbsp;&nbsp;&nbsp; 1、新建项目包：如下图：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dao：数据层；service：逻辑层；web：web展现层。2、建立好三层架构，部署好包名。建立一个jsp文件，取名为：logi...&nbsp;&nbsp;<a href='http://www.blogjava.net/xyzroundo/articles/177220.html'>阅读全文</a><img src ="http://www.blogjava.net/xyzroundo/aggbug/177220.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2008-01-23 11:13 <a href="http://www.blogjava.net/xyzroundo/articles/177220.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA高级：JavaVM，反射机制与动态代理 </title><link>http://www.blogjava.net/xyzroundo/articles/168258.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Mon, 17 Dec 2007 08:19:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/168258.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/168258.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/168258.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/168258.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/168258.html</trackback:ping><description><![CDATA[<table border="0" cellpadding="0" cellspacing="0" height="7674" width="745">
    <tbody>
        <tr>
            <td align="left">
            <p style="text-indent: 2em;"><span id="zoom">
            <div style="font-size: 10.5pt;">JavaVM，反射与动态代理
            <br />
            <br />
            <br />
            <br />
            Java程序的工作机制：Java对象都以单独的class文件存在，java虚拟机将其载入并执行其虚拟机指令。
            <br />
            <br />
            <br />
            <br />
            Java虚拟机查找这些java对象： <br />
            <br />
            java虚拟机根据class
            path来查找java对象，而虚拟机的class path又分为三层： <br />
            <br />
            bootstrap：sun.boot.class.path
            <br />
            <br />
            extension: java.ext.dirs <br />
            <br />
            application: java.class.path
            <br />
            <br />
            三个class path各有对应的classloader。由上而下形成父子关系
            <br />
            <br />
            当程序中调用new指令，或者ClassLoader.load方法时。其顺序如下： <br />
            <br />
            1.
            首先查看application的classloader中是否已有对应的class缓存，如果有则返回，并根据class分配内存。如果没有，接下一步。
            <br />
            <br />
            2.
            首先查看extension的classloader中是否已有对应的class缓存，如果有则返回，并根据class分配内存。如果没有，接下一步。
            <br />
            <br />
            3.
            首先查看bootstrap的classloader中是否已有对应的class缓存，如果有则返回，并根据class分配内存。如果没有，接下一步。
            <br />
            <br />
            4. 由bootstrap的classloader在其class
            path中试图加载该class，如果有，则将该class放入cache中，并返回。如果没有，接下一步。 <br />
            <br />
            5.
            由extension的classloader在其class
            path中试图加载该class，如果有，则将该class放入cache中，并返回。如果没有，接下一步。 <br />
            <br />
            6.
            由application的classloader在其class
            path中试图加载该class，如果有，则将该class放入cache中，并返回。如果没有，则抛出ClassNotFound的exception。
            <br />
            <br />
            <br />
            <br />
            Java虚拟机加载这些java对象： <br />
            <br />
            每个java虚拟机都在其启动时产生一个唯一的class
            heap，并把所有的class
            instance都分配在其中。其中每个类实例的信息又分两部分，fields域和methods域。每个类实例各自拥有fields，但同一个类的不同实例共享methods
            <br />
            <br />
            <br />
            <br />
            反射 <br />
            <br />
            JVM对反射的处理 <br />
            <br />
            简单例子代码： <br />
            <br />
            import
            java.lang.reflect.InvocationHandler; <br />
            <br />
            import java.lang.reflect.Method;
            <br />
            <br />
            import java.lang.reflect.InvocationTargetException; <br />
            <br />
            import
            java.io.IOException; <br />
            <br />
            <br />
            <br />
            public class Main { <br />
            <br />
            public static
            void main(String[] args){ <br />
            <br />
            TempImpl t1 = new TempImpl("temp1");
            <br />
            <br />
            try { <br />
            <br />
            Method t1Talk = t1.getClass().getMethod("Talk", new
            Class[0]) ; <br />
            <br />
            t1Talk.invoke(t1, null); <br />
            <br />
            } catch
            (NoSuchMethodException e) { <br />
            <br />
            e.printStackTrace(); //To change body of
            catch statement use File | Settings | File Templates. <br />
            <br />
            } catch
            (IllegalAccessException e) { <br />
            <br />
            e.printStackTrace(); //To change body of
            catch statement use File | Settings | File Templates. <br />
            <br />
            } catch
            (InvocationTargetException e) { <br />
            <br />
            e.printStackTrace(); //To change body of
            catch statement use File | Settings | File Templates. <br />
            <br />
            } <br />
            <br />
            try {
            <br />
            <br />
            System.in.read(); <br />
            <br />
            } catch (IOException e) {
            <br />
            <br />
            e.printStackTrace(); //To change body of catch statement use File |
            Settings | File Templates. <br />
            <br />
            } <br />
            <br />
            } <br />
            <br />
            } <br />
            <br />
            <br />
            复杂例子代码：
            <br />
            <br />
            import java.lang.reflect.InvocationHandler; <br />
            <br />
            import
            java.lang.reflect.Method; <br />
            <br />
            import
            java.lang.reflect.InvocationTargetException; <br />
            <br />
            import java.io.IOException;
            <br />
            <br />
            <br />
            <br />
            public class Main { <br />
            <br />
            public static void main(String[]
            args){ <br />
            <br />
            TempImpl t1 = new TempImpl("temp1"); <br />
            <br />
            TempImpl t2 = new
            TempImpl("temp2"); <br />
            <br />
            Temp2 temp2 = new Temp2(); <br />
            <br />
            try {
            <br />
            <br />
            Method t1Talk = t1.getClass().getMethod("Talk", new Class[0]) ;
            <br />
            <br />
            Method t2Talk = t2.getClass().getMethod("Talk", new Class[0]) ;
            <br />
            <br />
            t1Talk.invoke(t2, null); <br />
            <br />
            t2Talk.invoke(t1, null);
            <br />
            <br />
            if(t1Talk.equals(t2Talk)){ <br />
            <br />
            System.out.println("equals");
            <br />
            <br />
            } <br />
            <br />
            else{ <br />
            <br />
            System.out.println("not equals"); <br />
            <br />
            }
            <br />
            <br />
            if(t1Talk==t2Talk){ <br />
            <br />
            System.out.println("ref equals"); <br />
            <br />
            }
            <br />
            <br />
            else{ <br />
            <br />
            System.out.println("ref not equals"); <br />
            <br />
            }
            <br />
            <br />
            t2Talk.invoke(temp2, null); <br />
            <br />
            } catch (NoSuchMethodException e) {
            <br />
            <br />
            e.printStackTrace(); //To change body of catch statement use File |
            Settings | File Templates. <br />
            <br />
            } catch (IllegalAccessException e) {
            <br />
            <br />
            e.printStackTrace(); //To change body of catch statement use File |
            Settings | File Templates. <br />
            <br />
            } catch (InvocationTargetException e) {
            <br />
            <br />
            e.printStackTrace(); //To change body of catch statement use File |
            Settings | File Templates. <br />
            <br />
            } <br />
            <br />
            try { <br />
            <br />
            System.in.read();
            <br />
            <br />
            } catch (IOException e) { <br />
            <br />
            e.printStackTrace(); //To change body
            of catch statement use File | Settings | File Templates. <br />
            <br />
            } <br />
            <br />
            }
            <br />
            <br />
            }
            <br />
            <br />
            <br />
            <br />
            <br />
            分析：java虚拟机把每个methods当作一个执行单元。该执行单元带有两种签名：类签名和属性签名（public，static等）。
            反射的第一步，验证签名的合法性。验证通过后，顺序执行该method中的指令，当需要访问类实例的fields和传入参数时，由虚拟机注入。
            <br />
            <br />
            <br />
            <br />
            动态代理 <br />
            <br />
            Sun对动态代理的说明： <br />
            <br />
            一个简单例子代码：
            <br />
            <br />
            动态代理的内部实现——代码生成：
            <br />
            <br />
            研究JDK源代码，发现在Proxy的sun实现中调用了sun.misc.ProxyGenerator类的generateProxyClass(
            proxyName, interfaces)方法，其返回值为byte[]和class文件的内存类型一致。于是做如下试验： <br />
            <br />
            public
            class ProxyClassFile{ <br />
            <br />
            public static void main(String[] args){
            <br />
            <br />
            String proxyName = "TempProxy"; <br />
            <br />
            TempImpl t = new
            TempImpl("proxy"); <br />
            <br />
            Class[] interfaces =t.getClass().getInterfaces();
            <br />
            <br />
            <br />
            <br />
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
            <br />
            <br />
            proxyName, interfaces); <br />
            <br />
            File f = new
            File("classes/TempProxy.class"); <br />
            <br />
            try { <br />
            <br />
            FileOutputStream fos =
            new FileOutputStream(f); <br />
            <br />
            fos.write(proxyClassFile); <br />
            <br />
            fos.flush();
            <br />
            <br />
            fos.close(); <br />
            <br />
            } catch (FileNotFoundException e) {
            <br />
            <br />
            e.printStackTrace(); //To change body of catch statement use File |
            Settings | File Templates. <br />
            <br />
            } catch (IOException e) {
            <br />
            <br />
            e.printStackTrace(); //To change body of catch statement use File |
            Settings | File Templates. <br />
            <br />
            } <br />
            <br />
            } <br />
            <br />
            }
            <br />
            <br />
            <br />
            运行该类，到class文件夹下，利用反编译技术，发现原来其采用了代码生产技术： <br />
            <br />
            <br />
            <br />
            public
            interface Temp{ <br />
            <br />
            public void Talk(); <br />
            <br />
            public void Run(); <br />
            <br />
            }
            <br />
            <br />
            import java.lang.reflect.*; <br />
            <br />
            <br />
            <br />
            public final class TempProxy
            extends Proxy <br />
            <br />
            implements Temp{ <br />
            <br />
            <br />
            <br />
            private static Method m4;
            <br />
            <br />
            private static Method m2; <br />
            <br />
            private static Method m0;
            <br />
            <br />
            private static Method m3; <br />
            <br />
            private static Method m1;
            <br />
            <br />
            <br />
            <br />
            public TempProxy(InvocationHandler invocationhandler) {
            <br />
            <br />
            super(invocationhandler); <br />
            <br />
            } <br />
            <br />
            <br />
            <br />
            public final void
            Run() { <br />
            <br />
            try { <br />
            <br />
            h.invoke(this, m4, null); <br />
            <br />
            return;
            <br />
            <br />
            } <br />
            <br />
            catch(Error _ex) { } <br />
            <br />
            catch(Throwable throwable) {
            <br />
            <br />
            throw new UndeclaredThrowableException(throwable); <br />
            <br />
            } <br />
            <br />
            }
            <br />
            <br />
            <br />
            <br />
            public final String toString(){ <br />
            <br />
            try{ <br />
            <br />
            return
            (String)h.invoke(this, m2, null); <br />
            <br />
            } <br />
            <br />
            catch(Error _ex) { }
            <br />
            <br />
            catch(Throwable throwable) { <br />
            <br />
            throw new
            UndeclaredThrowableException(throwable); <br />
            <br />
            } <br />
            <br />
            return ""; <br />
            <br />
            }
            <br />
            <br />
            <br />
            <br />
            public final int hashCode() { <br />
            <br />
            try { <br />
            <br />
            return
            ((Integer)h.invoke(this, m0, null)).intValue(); <br />
            <br />
            } <br />
            <br />
            catch(Error
            _ex) { } <br />
            <br />
            catch(Throwable throwable){ <br />
            <br />
            throw new
            UndeclaredThrowableException(throwable); <br />
            <br />
            } <br />
            <br />
            return 123; <br />
            <br />
            }
            <br />
            <br />
            <br />
            <br />
            public final void Talk(){ <br />
            <br />
            try{ <br />
            <br />
            h.invoke(this,
            m3, null); <br />
            <br />
            return; <br />
            <br />
            } <br />
            <br />
            catch(Error _ex) { }
            <br />
            <br />
            catch(Throwable throwable) { <br />
            <br />
            throw new
            UndeclaredThrowableException(throwable); <br />
            <br />
            } <br />
            <br />
            }
            <br />
            <br />
            <br />
            <br />
            public final boolean equals(Object obj) { <br />
            <br />
            try {
            <br />
            <br />
            return ((Boolean)h.invoke(this, m1, new Object[] { <br />
            <br />
            obj
            <br />
            <br />
            })).booleanValue(); <br />
            <br />
            } <br />
            <br />
            catch(Error _ex) { }
            <br />
            <br />
            catch(Throwable throwable) { <br />
            <br />
            throw new
            UndeclaredThrowableException(throwable); <br />
            <br />
            } <br />
            <br />
            return false;
            <br />
            <br />
            } <br />
            <br />
            <br />
            <br />
            static{ <br />
            <br />
            try{ <br />
            <br />
            m4 =
            Class.forName("Temp").getMethod("Run", new Class[0]); <br />
            <br />
            m2 =
            Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
            <br />
            <br />
            m0 = Class.forName("java.lang.Object").getMethod("hashCode", new
            Class[0]); <br />
            <br />
            m3 = Class.forName("Temp").getMethod("Talk", new Class[0]);
            <br />
            <br />
            m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] {
            <br />
            <br />
            Class.forName("java.lang.Object") <br />
            <br />
            }); <br />
            <br />
            }
            <br />
            <br />
            catch(NoSuchMethodException nosuchmethodexception) { <br />
            <br />
            throw new
            NoSuchMethodError(nosuchmethodexception.getMessage()); <br />
            <br />
            }
            <br />
            <br />
            catch(ClassNotFoundException classnotfoundexception) { <br />
            <br />
            throw new
            NoClassDefFoundError(classnotfoundexception.getMessage()); <br />
            <br />
            } <br />
            <br />
            }
            <br />
            <br />
            }&nbsp;<br />
            </div>
            </span></p>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/168258.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2007-12-17 16:19 <a href="http://www.blogjava.net/xyzroundo/articles/168258.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【经典推荐】每个初学者都应该搞懂的问题！</title><link>http://www.blogjava.net/xyzroundo/articles/168254.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Mon, 17 Dec 2007 08:13:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/168254.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/168254.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/168254.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/168254.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/168254.html</trackback:ping><description><![CDATA[对于这个系列里的问题，每个学Java的人都应该搞懂。当然，如果只是学Java玩玩就无所谓了。如果你认为自己已经超越初学者了，却不很懂这些问题，请将你自己重归初学者行列。内容均来自于CSDN的经典老贴。 <br />
<br />
问题一：我声明了什么！ <br />
<br />
String s = "Hello world!"; <br />
<br />
许多人都做过这样的事情，但是，我们到底声明了什么？回答通常是：一个String，内容是&#8220;Hello world!&#8221;。这样模糊的回答通常是概念不清的根源。如果要准确的回答，一半的人大概会回答错误。 <br />
这
个语句声明的是一个指向对象的引用，名为&#8220;s&#8221;，可以指向类型为String的任何对象，目前指向"Hello
world!"这个String类型的对象。这就是真正发生的事情。我们并没有声明一个String对象，我们只是声明了一个只能指向String对象的
引用变量。所以，如果在刚才那句语句后面，如果再运行一句： <br />
<br />
String string = s; <br />
<br />
我们是声明了另外一个只能指向String对象的引用，名为string，并没有第二个对象产生，string还是指向原来那个对象，也就是，和s指向同一个对象。 <br />
<br />
问题二："=="和equals方法究竟有什么区别？ <br />
<br />
==操作符专门用来比较变量的值是否相等。比较好理解的一点是： <br />
int a=10; <br />
int b=10; <br />
则a==b将是true。 <br />
但不好理解的地方是： <br />
String a=new String("foo"); <br />
String b=new String("foo"); <br />
则a==b将返回false。 <br />
<br />
根
据前一帖说过，对象变量其实是一个引用，它们的值是指向对象所在的内存地址，而不是对象本身。a和b都使用了new操作符，意味着将在内存中产生两个内容
为"foo"的字符串，既然是&#8220;两个&#8221;，它们自然位于不同的内存地址。a和b的值其实是两个不同的内存地址的值，所以使用"=="操作符，结果会是
false。诚然，a和b所指的对象，它们的内容都是"foo"，应该是&#8220;相等&#8221;，但是==操作符并不涉及到对象内容的比较。 <br />
对象内容的比较，正是equals方法做的事。 <br />
<br />
看一下Object对象的equals方法是如何实现的： <br />
boolean equals(Object o){ <br />
<br />
return this==o; <br />
<br />
} <br />
Object
对象默认使用了==操作符。所以如果你自创的类没有覆盖equals方法，那你的类使用equals和使用==会得到同样的结果。同样也可以看出，
Object的equals方法没有达到equals方法应该达到的目标：比较两个对象内容是否相等。因为答案应该由类的创建者决定，所以Object把
这个任务留给了类的创建者。 <br />
<br />
看一下一个极端的类： <br />
Class Monster{ <br />
private String content; <br />
... <br />
boolean equals(Object another){ return true;} <br />
<br />
} <br />
我覆盖了equals方法。这个实现会导致无论Monster实例内容如何，它们之间的比较永远返回true。 <br />
<br />
所
以当你是用equals方法判断对象的内容是否相等，请不要想当然。因为可能你认为相等，而这个类的作者不这样认为，而类的equals方法的实现是由他
掌握的。如果你需要使用equals方法，或者使用任何基于散列码的集合（HashSet,HashMap,HashTable），请察看一下java
doc以确认这个类的equals逻辑是如何实现的。 <br />
<br />
问题三：String到底变了没有？ <br />
<br />
没有。因为String被设计成不可变(immutable)类，所以它的所有对象都是不可变对象。请看下列代码： <br />
<br />
String s = "Hello"; <br />
s = s + " world!"; <br />
<br />
s
所指向的对象是否改变了呢？从本系列第一篇的结论很容易导出这个结论。我们来看看发生了什么事情。在这段代码中，s原先指向一个String对象，内容是
"Hello"，然后我们对s进行了+操作，那么s所指向的那个对象是否发生了改变呢？答案是没有。这时，s不指向原来那个对象了，而指向了另一个
String对象，内容为"Hello world!"，原来那个对象还存在于内存之中，只是s这个引用变量不再指向它了。 <br />
通过上面的说明，
我们很容易导出另一个结论，如果经常对字符串进行各种各样的修改，或者说，不可预见的修改，那么使用String来代表字符串的话会引起很大的内存开销。
因为String对象建立之后不能再改变，所以对于每一个不同的字符串，都需要一个String对象来表示。这时，应该考虑使用StringBuffer
类，它允许修改，而不是每个不同的字符串都要生成一个新的对象。并且，这两种类的对象转换十分容易。 <br />
同时，我们还可以知道，如果要使用内容相同的字符串，不必每次都new一个String。例如我们要在构造器中对一个名叫s的String引用变量进行初始化，把它设置为初始值，应当这样做： <br />
public class Demo { <br />
private String s; <br />
... <br />
public Demo { <br />
s = "Initial Value"; <br />
} <br />
... <br />
} <br />
而非 <br />
s = new String("Initial Value"); <br />
后
者每次都会调用构造器，生成新对象，性能低下且内存开销大，并且没有意义，因为String对象不可改变，所以对于内容相同的字符串，只要一个
String对象来表示就可以了。也就说，多次调用上面的构造器创建多个对象，他们的String类型属性s都指向同一个对象。 <br />
上面的结论还基于这样一个事实：对于字符串常量，如果内容相同，Java认为它们代表同一个String对象。而用关键字new调用构造器，总是会创建一个新的对象，无论内容是否相同。 <br />
至
于为什么要把String类设计成不可变类，是它的用途决定的。其实不只String，很多Java标准类库中的类都是不可变的。在开发一个系统的时候，
我们有时候也需要设计不可变类，来传递一组相关的值，这也是面向对象思想的体现。不可变类有一些优点，比如因为它的对象是只读的，所以多线程并发访问也不
会有任何问题。当然也有一些缺点，比如每个不同的状态都要一个对象来代表，可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本，即
StringBuffer。 <br />
<br />
问题四：final关键字到底修饰了什么？ <br />
<br />
final使得被修饰的变量"不变"，但是由于对象型变量的本质是&#8220;引用&#8221;，使得&#8220;不变&#8221;也有了两种含义：引用本身的不变，和引用指向的对象不变。 <br />
<br />
引用本身的不变： <br />
final StringBuffer a=new StringBuffer("immutable"); <br />
final StringBuffer b=new StringBuffer("not immutable"); <br />
a=b;//编译期错误 <br />
<br />
引用指向的对象不变： <br />
final StringBuffer a=new StringBuffer("immutable"); <br />
a.append(" broken!"); //编译通过 <br />
<br />
可
见，final只对引用的&#8220;值&#8221;(也即它所指向的那个对象的内存地址)有效，它迫使引用只能指向初始指向的那个对象，改变它的指向会导致编译期错误。至于
它所指向的对象的变化，final是不负责的。这很类似==操作符：==操作符只负责引用的&#8220;值&#8221;相等，至于这个地址所指向的对象内容是否相等，==操作
符是不管的。 <br />
<br />
理解final问题有很重要的含义。许多程序漏洞都基于此----final只能保证引用永远指向固定对象，不能保证那
个对象的状态不变。在多线程的操作中,一个对象会被多个线程共享或修改，一个线程对对象无意识的修改可能会导致另一个使用此对象的线程崩溃。一个错误的解
决方法就是在此对象新建的时候把它声明为final，意图使得它&#8220;永远不变&#8221;。其实那是徒劳的。 <br />
<br />
问题五：到底要怎么样初始化！ <br />
<br />
本问题讨论变量的初始化，所以先来看一下Java中有哪些种类的变量。 <br />
1. 类的属性，或者叫值域 <br />
2. 方法里的局部变量 <br />
3. 方法的参数 <br />
<br />
对于第一种变量，Java虚拟机会自动进行初始化。如果给出了初始值，则初始化为该初始值。如果没有给出，则把它初始化为该类型变量的默认初始值。 <br />
<br />
int类型变量默认初始值为0 <br />
float类型变量默认初始值为0.0f <br />
double类型变量默认初始值为0.0 <br />
boolean类型变量默认初始值为false <br />
char类型变量默认初始值为0(ASCII码) <br />
long类型变量默认初始值为0 <br />
所有对象引用类型变量默认初始值为null，即不指向任何对象。注意数组本身也是对象，所以没有初始化的数组引用在自动初始化后其值也是null。 <br />
<br />
对
于两种不同的类属性，static属性与instance属性，初始化的时机是不同的。instance属性在创建实例的时候初始化，static属性在
类加载，也就是第一次用到这个类的时候初始化，对于后来的实例的创建，不再次进行初始化。这个问题会在以后的系列中进行详细讨论。 <br />
<br />
对
于第二种变量，必须明确地进行初始化。如果再没有初始化之前就试图使用它，编译器会抗议。如果初始化的语句在try块中或if块中，也必须要让它在第一次
使用前一定能够得到赋值。也就是说，把初始化语句放在只有if块的条件判断语句中编译器也会抗议，因为执行的时候可能不符合if后面的判断条件，如此一来
初始化语句就不会被执行了，这就违反了局部变量使用前必须初始化的规定。但如果在else块中也有初始化语句，就可以通过编译，因为无论如何，总有至少一
条初始化语句会被执行，不会发生使用前未被初始化的事情。对于try-catch也是一样，如果只有在try块里才有初始化语句，编译部通过。如果在
catch或finally里也有，则可以通过编译。总之，要保证局部变量在使用之前一定被初始化了。所以，一个好的做法是在声明他们的时候就初始化他
们，如果不知道要出事化成什么值好，就用上面的默认值吧！ <br />
<br />
其实第三种变量和第二种本质上是一样的，都是方法中的局部变量。只不过作为参数，肯定是被初始化过的，传入的值就是初始值，所以不需要初始化。 <br />
<br />
问题六：instanceof是什么东东？ <br />
<br />
instanceof是Java的一个二元操作符，和==，&gt;，&lt;是同一类东东。由于它是由字母组成的，所以也是Java的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例，返回boolean类型的数据。举个例子： <br />
<br />
String s = "I AM an Object!"; <br />
boolean isObject = s instanceof Object; <br />
<br />
我们声明了一个String对象引用，指向一个String对象，然后用instancof来测试它所指向的对象是否是Object类的一个实例，显然，这是真的，所以返回true，也就是isObject的值为True。 <br />
instanceof有一些用处。比如我们写了一个处理账单的系统，其中有这样三个类： <br />
<br />
public class Bill {//省略细节} <br />
public class PhoneBill extends Bill {//省略细节} <br />
public class GasBill extends Bill {//省略细节} <br />
<br />
在处理程序里有一个方法，接受一个Bill类型的对象，计算金额。假设两种账单计算方法不同，而传入的Bill对象可能是两种中的任何一种，所以要用instanceof来判断： <br />
<br />
public double calculate(Bill bill) { <br />
if (bill instanceof PhoneBill) { <br />
//计算电话账单 <br />
} <br />
if (bill instanceof GasBill) { <br />
//计算燃气账单 <br />
} <br />
... <br />
} <br />
这样就可以用一个方法处理两种子类。 <br />
<br />
然而，这种做法通常被认为是没有好好利用面向对象中的多态性。其实上面的功能要求用方法重载完全可以实现，这是面向对象变成应有的做法，避免回到结构化编程模式。只要提供两个名字和返回值都相同，接受参数类型不同的方法就可以了： <br />
<br />
public double calculate(PhoneBill bill) { <br />
//计算电话账单 <br />
} <br />
<br />
public double calculate(GasBill bill) { <br />
//计算燃气账单 <br />
} <br />
<br />
所以，使用instanceof在绝大多数情况下并不是推荐的做法，应当好好利用多态。
<img src ="http://www.blogjava.net/xyzroundo/aggbug/168254.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2007-12-17 16:13 <a href="http://www.blogjava.net/xyzroundo/articles/168254.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 关于中文乱码问题的解决方案与经验</title><link>http://www.blogjava.net/xyzroundo/articles/168250.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Mon, 17 Dec 2007 08:07:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/168250.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/168250.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/168250.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/168250.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/168250.html</trackback:ping><description><![CDATA[<p style="text-indent: 2em;"><span id="zoom">
<p><font face="Times New Roman" size="3">一、字节和unicode</font></p>
<p><font face="Times New Roman" size="3">Java内核是unicode的，就连class文件也是，但是很多媒体，包括文件/流的保存方式是使用字节流的。因此Java要对这些字节流经行转化。
char是unicode的，而byte是字节。Java中byte/char互转的函数在sun.io的包中间有。其中
ByteToCharConverter类是中调度，可以用来告诉你，你用的convertor。其中两个很常用的静态函数是：</font></p>
<p><font face="Times New Roman" size="3">public static ByteToCharConverter
getDefault(); </font></p>
<p><font face="Times New Roman" size="3">public static ByteToCharConverter
getConverter(String encoding);</font></p>
<p><font face="Times New Roman" size="3">如果你不指定converter，则系统会自动使用当前的encoding,gb平台上用gbk,en平台上用8859_1。 </font></p>
<p><font face="Times New Roman" size="3">byte ——〉char：</font></p>
<p><font face="Times New Roman" size="3">"你"的gb码是：0xc4e3
,unicode是0x4f60</font></p>
<p><font face="Times New Roman" size="3">String encoding = "gb2312";</font></p>
<p><font face="Times New Roman" size="3">byte b[] =
{(byte)''"u00c4'',(byte)''"u00e3''};</font></p>
<p><font face="Times New Roman" size="3">ByteToCharConverter converter =
ByteToCharConverter.getConverter(encoding);</font></p>
<p><font face="Times New Roman" size="3">char c[] =
converter.convertAll(b);</font></p>
<p><font face="Times New Roman" size="3">for (int i = 0; i &lt; c.length; i++)
{</font></p>
<p><font face="Times New Roman" size="3">System.out.println(Integer.toHexString(c[i]));</font></p>
<p><font face="Times New Roman" size="3">}</font></p>
<p><font face="Times New Roman" size="3">结果是什么？0x4f60</font></p>
<p><font face="Times New Roman" size="3">如果encoding
="8859_1"，结果又是什么？0x00c4,0x00e3（这表明8859_1是以字节为单位的）</font></p>
<p><font face="Times New Roman" size="3">如果代码改为： </font></p>
<p><font face="Times New Roman" size="3">byte b[] =
{(byte)''"u00c4'',(byte)''"u00e3''};</font></p>
<p><font face="Times New Roman" size="3">ByteToCharConverter converter =
ByteToCharConverter. getDefault();</font></p>
<p><font face="Times New Roman" size="3">char c[] =
converter.convertAll(b);</font></p>
<p><font face="Times New Roman" size="3">for (int i = 0; i &lt; c.length; i++)
{</font></p>
<p><font face="Times New Roman" size="3">System.out.println(Integer.toHexString(c[i]));</font></p>
<p><font face="Times New Roman" size="3">}</font></p>
<font face="Times New Roman" size="3">
<p><br />
结果将又是什么？ </p>
<p>这就要根据平台的编码而定。 </p>
<p>char ——〉byte：</p>
<p>String encoding = "gb2312";</p>
<p>char c[] = {''"u4f60''};</p>
<p>CharToByteConverter converter =
CharToByteConverter.getConverter(encoding);</p>
<p>byte b[] = converter.convertAll(c);</p>
<p>for (int i = 0; i &lt; b.length; i++) {</p>
<p>System.out.println(Integer.toHexString(b[i]));</p>
<p>}</p>
<p>结果是什么？0x00c4,0x00e3</p>
<p>如果encoding ="8859_1"，结果又是什么？0x3f</p>
<p>如果代码改为</p>
<p>String encoding = "gb2312";</p>
<p>char c[] = {''"u4f60''};</p>
<p>CharToByteConverter converter = CharToByteConverter.getDefault();</p>
<p>byte b[] = converter.convertAll(c);</p>
<p>for (int i = 0; i &lt; b.length; i++) {</p>
<p>System.out.println(Integer.toHexString(b[i]));</p>
<p>}</p>
<p><br />
结果将又是什么？还是根据平台的编码而定。 </p>
<p>很多中文问题就是从这两个最简单的类派生出来的。而却有很多类不直接支持把encoding输入，这给我们带来诸多不便。很多程序难得用encoding了，直接用default的encoding，这就给我们移植带来了很多困难。
</p>
<p>二、utf-8 </p>
<p>utf-8是和unicode一一对应的，其实现很简单： </p>
<p>7位的unicode: 0 _ _ _ _ _ _ _ </p>
<p>11位的unicode: 1 1 0 _ _ _ _ _ 1 0 _ _ _ _ _ _ </p>
<p>16位的unicode: 1 1 1 0 _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _ </p>
<p>21位的unicode: 1 1 1 1 0 _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _
_</p>
<p><br />
大多数情况是只使用到16位以下的unicode: </p>
<p>"你"的gb码是：0xc4e3 ,unicode是0x4f60</p>
<p>0xc4e3的二进制：</p>
<p>1100 ，0100 ，1110 ，0011</p>
<p><br />
由于只有两位我们按照两位的编码来排，但是我们发现这行不通，因为第７位不是0因此，返回"?" </p>
<p>0x4f60的二进制：</p>
<p>0100 ，1111 ，0110 ，0000</p>
<p>我们用utf-8补齐，变成：</p>
<p>1110 ，0100 ，1011 ，1101 ，1010 ，0000</p>
<p>e4--bd-- a0</p>
<p>于是返回：0xe4,0xbd,0xa0。</p>
<p><br />
三、string和byte[] </p>
<p>string其实核心是char[],然而要把byte转化成string，必须经过编码。string.length()其实就是char数组的长度，如果使用不同的编码，很可能会错分，造成散字和乱码。例如：
</p>
<p>String encoding = &#8220;&#8221;;</p>
<p>byte [] b={(byte)''"u00c4'',(byte)''"u00e3''}; </p>
<p>String str=new String(b,encoding);</p>
<p>如果encoding=8859_1，会有两个字，但是encoding=gb2312只有一个字这个问题在处理分页是经常发生。 </p>
<p>四、Reader,Writer / InputStream,OutputStream </p>
<p>Reader和Writer核心是char，InputStream和OutputStream核心是byte。但是Reader和Writer的主要目的是要把char读/写InputStream/OutputStream。例如：
</p>
<p>文件test.txt只有一个"你"字，0xc4,0xe3</p>
<p>String encoding = "gb2312";</p>
<p>InputStreamReader reader = new InputStreamReader(new FileInputStream(</p>
<p>"text.txt"), encoding);</p>
<p>char c[] = new char[10];</p>
<p>int length = reader.read(c);</p>
<p>for (int i = 0; i &lt; length; i++) {</p>
<p>System.out.println(c[i]);</p>
<p>}</p>
<p><br />
结果是什么？是"你"。如果encoding ="8859_1"，结果是什么？"??"两个字符，表示不认识。反过来的例子自己做。</p>
<p>五、我们要对Java的编译器有所了解：</p>
<p>Javac ?encoding</p>
<p><br />
我们常常没有用到encoding这个参数。其实encoding这个参数对于跨平台的操作是很重要的。如果没有指定encoding，则按照系统的默认encoding,gb平台上是gb2312，英文平台上是iso8859_1。Java的编译器实际上是调用
sun.tools.Javac.main的类，对文件进行编译，这个类有compile函数中间有一个encoding的变量,-encoding的参
数其实直接传给encoding变量。编译器就是根据这个变量来读取Java文件的，然后把用utf-8形式编译成class文件。例子代码： </p>
<p>String str = "你";</p>
<p>FileWriter writer = new FileWriter("text.txt");</p>
<p>write.write(str);</p>
<p>writer.close();</p>
<p>如果用gb2312编译，你会找到e4 bd a0的字段 ；</p>
<p>如果用8859_1编译， 00c4 00e3的二进制： </p>
<p>0000，0000 ，1100，0100 ，0000，0000 ，1110，0011</p>
<p>因为每个字符都大于7位，因此用11位编码： </p>
<p>1100，0001，1000，0100，1100，0011，1010，0011 </p>
<p>c1-- 84--　c3--　 a3 </p>
<p>你会找到c1 84 c3 a3</p>
<p><br />
但是我们往往忽略掉这个参数，因此这样往往会有跨平台的问题： </p>
<p>样例代码在中文平台上编译，生成zhclass </p>
<p>样例代码在英文平台上编译，输出enclass </p>
<p>(1) zhclass在中文平台上执行ok,但是在英文平台上不行 </p>
<p>(2) enclass在英文平台上执行ok,但是在中文平台上不行 </p>
<p>原因是： </p>
<p>(1) 在中文平台上编译后，其实str在运行态的char[]是0x4f60,　在中文平台上运行，filewriter的缺省编码是gb2312,因此
chartobyteconverter会自动用调用gb2312的converter,把str转化成byte输入到fileoutputstream
中，于是0xc4,0xe3放进了文件。但是如果是在英文平台下，chartobyteconverter的缺省值是8859_1,
filewriter会自动调用8859_1去转化str,但是他无法解释，因此他会输出"?" </p>
<p>(2) 在英文平台上编译后，其实str在运行态的char[]是0x00c4 0x00e3,
在中文平台上运行，中文无法识别，因此会出现??；在英文平台上，0x00c4--&gt;0xc4,0x00e3-&gt;0xe3，因此
0xc4,0xe3被放进了文件。 </p>
<p>六、其它原因： </p>
<p>&lt;%@ page contentType="text/html; charset=GBK" %&gt;</p>
<p><br />
设置浏览器的显示编码，如果response的数据是utf8编码，显示将是乱码，但是乱码和上述原因还不一样。 </p>
<p>七、发生编码的地方： </p>
<p>1. 从数据库到Java程序 byte——〉char </p>
<p>2. 从Java程序到数据库 char——〉byte </p>
<p>3. 从文件到Java程序 byte——〉char </p>
<p>4. 从Java程序到文件 char——〉byte </p>
<p>5. 从Java程序到页面显示 char——〉byte </p>
<p>6. 从页面form提交数据到Java程序byte——〉char </p>
<p>7. 从流到Java程序byte——〉char </p>
<p>8. 从Java程序到流char——〉byte </p>
<p>可以使用配置过滤器的方法解决中文乱码的： </p>
<p><filter-name>RequestFilter</filter-name></p>
<p><filter-class>net.golden.uirs.util.RequestFilter</filter-class></p>
<p>charset</param-name>
</p>
<p>gb2312</param-value>
</p>
<p><filter-name>RequestFilter</filter-name></p>
<p><url-pattern>*.Jsp</url-pattern></p>
<p>public void doFilter(ServletRequest req, ServletResponse res,</p>
<p>FilterChain fChain) throws IOException, ServletException {</p>
<p>HttpServletRequest request = (HttpServletRequest) req;</p>
<p>HttpServletResponse response = (HttpServletResponse) res;</p>
<p>HttpSession session = request.getSession();</p>
<p>String userId = (String) session.getAttribute("userid");</p>
<p>req.setCharacterEncoding(this.filterConfig.getInitParameter("charset")); </p>
<p>// 设置字符集？</p>
<p>实际上是设置了byte ——〉char的encoding</p>
<p>try {</p>
<p>if (userId == null || userId.equals("")) {</p>
<p>if (!request.getRequestURL().toString().matches(</p>
<p>".*/uirs/logon/logon(Controller){0,1}""x2EJsp$")) {</p>
<p>session.invalidate();</p>
<p>response.sendRedirect(request.getContextPath() +</p>
<p>"/uirs/logon/logon.Jsp");</p>
<p>}</p>
<p>}</p>
<p>else { </p>
<p>// 看看是否具有信息上报系统的权限</p>
<p>if (!net.golden.uirs.util.UirsChecker.check(userId, "信息上报系统",</p>
<p>net.golden.uirs.util.UirsChecker.ACTION_DO)) {</p>
<p>if (!request.getRequestURL().toString().matches(</p>
<p>".*/uirs/logon/logon(Controller){0,1}""x2EJsp$")) {</p>
<p>response.sendRedirect(request.getContextPath() +</p>
<p>"/uirs/logon/logonController.Jsp");</p>
<p>}</p>
<p>}</p>
<p>}</p>
<p>}</p>
<p>catch (Exception ex) {</p>
<p>response.sendRedirect(request.getContextPath() +</p>
<p>"/uirs/logon/logon.Jsp");</p>
<p>}</p>
<p>fChain.doFilter(req, res);</p>
<p>}</p>
</font></span></p>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/168250.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2007-12-17 16:07 <a href="http://www.blogjava.net/xyzroundo/articles/168250.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> JAVA反编译工具</title><link>http://www.blogjava.net/xyzroundo/articles/168177.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Mon, 17 Dec 2007 03:11:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/168177.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/168177.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/168177.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/168177.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/168177.html</trackback:ping><description><![CDATA[<h3>
JAVA反编译工具
</h3>
<p>
目前，比较流行的JAVA反编译工具有近30种，其中有三款堪称精品：<br />
<br />
一、 应用广泛的JAD<br />
<br />
在
众多的JAVA反编译工具中，有几种非常著名的工具使用了相同的核心引擎——JAD，其中主要包括：Front End
Plus、mDeJava、Decafe Pro、Cavaj Java Decompiler、DJ Java Decompiler、NMI&#8217;s
Java Class Viewer和国产的JAVA源代码反编译专家。<br />
<br />
JAD本身是一个命令行工具，没有图形界面，上述的这些工具大多是在JAD内核的基础之上加了一个图形界面而已。这么多种产品的共同选择，足可证明JAD在JAVA反编译领域中的尊贵地位。<br />
<br />
笔者用来测试的JAD版本是1.5.8f，其运行界面如下图：<br />
<a href="http://www.blogchina.com/resource/upload/pic/2006/03/17/264618335.1001.0161.jpg" target="_blank"><font face="verdana">http://www.blogchina.com/resource/upload/pic/2006/03/17/264618335.1001.0161.jpg</font></a><font face="verdana"> <br />
JAD是使用Microsoft Visual C++开发的，运行速度非常快，可以处理很复杂的JAVA编译文件。众多的参数使JAD可以灵活应付多种加密手段，令反编译的代码更加优化和易读。由于JAD参数太多，没必要一一解释，其中有几个最常用的如下：<br />
<br />
-d &lt;dir&gt; - 用于指定输出文件的目录<br />
<br />
-s &lt;ext&gt; - 输出文件扩展名(默认为: .jad)，通常都会把输出文件扩展名直接指定为.java，以方便修改的重新编译。<br />
<br />
-8 - 将Unicode字符转换为ANSI字符串，如果输出字符串是中文的话一定要加上这个参数才能正确显示。<br />
<br />
最常用的反编译指令如下所示：<br />
<br />
Jad &#8211;d c:\javasource &#8211;s .java -8 javatest.class<br />
<br />
这条指令将当前目录下的javatest.class反编译为javatest.java并保存在c:\javasource目录里，其中的提示输出为中文，而不是Unicode代码。<br />
<br />
二、 源码开放的JODE<br />
<br />
JODE是全球最大的开源项目网站Sourceforge.net的成员，不要以为源码开放就小瞧它，在所有的JAVA反编译器中，JODE的反编译效果是最好的，尤其是对付一些常见的加密手段，例如混淆技术等，更是出类拔粹。<br />
<br />
JODE本身也是纯JAVA开发的，最近越来越多的JAVA反编译软件也选择JODE来做它们的核心引擎，例如JCavaj Java Decompiler、BTJ (Back To Java)、jEdit's JavaInsight plugin等。<br />
<br />
JODE是一个可运行的JAR文件，在windows环境下双击即可运行，其运行界面如下：<br />
<br />
</font><a href="http://www.blogchina.com/resource/upload/pic/2006/03/17/264618335.1002.0373.jpg" target="_blank"><font face="verdana">http://www.blogchina.com/resource/upload/pic/2006/03/17/264618335.1002.0373.jpg</font></a><font face="verdana"> <br />
需
要特别说明的是，JODE不是通过常规的Open-&gt;File的方式来加载JAVA编译后的类文件（*.class）或是类包（*.jar）的，而
是通过在Options菜单中的Set
Classpath来实现的，单独的类文件可以将它的上一级目录作为Classpath输入，然后再选择Reload Classpath即可：<br />
</font><a href="http://www.blogchina.com/resource/upload/pic/2006/03/17/264618335.1003.07741.jpg" target="_blank"><font face="verdana">http://www.blogchina.com/resource/upload/pic/2006/03/17/264618335.1003.07741.jpg</font></a><font face="verdana"> <br />
</font><a href="http://www.blogchina.com/resource/upload/pic/2006/03/17/264618335.1004.08813.jpg" target="_blank"><font face="verdana">http://www.blogchina.com/resource/u....1004.08813.jpg</font></a><font face="verdana"><br />
<br />
新加入的类包或是类的名字会在左侧窗口出现，双击类包名可以展开目录树结构，双击需要反编译的类名则在右上角的窗口中直接显示反编译后的源代码。<br />
<br />
三、 独树一帜的DAVA<br />
<br />
DAVA不是一个独立的JAVA反编译器，而是JAVA代码优化工具Soot的一部分。Soot和JODE一样是纯JAVA开发的，也是一个独立的JAR包，但却不能通过双击直接运行，而是象JAD一样在命令行状态运行。<br />
</font><a href="http://www.blogchina.com/resource/upload/pic/2006/03/17/264618335.1005.09938.jpg" target="_blank"><font face="verdana">http://www.blogchina.com/resource/upload/pic/2006/03/17/264618335.1005.09938.jpg</font></a><font face="verdana"> <br />
Soot对环境变量的配置要求非常严格，通常情况下要对CLASSPATH做如下设置：<br />
<br />
Set CLASSPATH=%CLASSPATH%;c:\sootdir\sootclasses-2.1.0.jar;.;<br />
<br />
其中的c:\sootdir\是下载的soot类包放置的路径，CLASSPATH末尾的.;代表了当前目录，如果不加上这个的话Soot经常会报一个找不到类的错误。<br />
<br />
DAVA是作为Soot的一个参数使用的，通常的用法如下：<br />
<br />
Java soot.Main &#8211;f dava &#8211;d c:\javasource javatest<br />
<br />
注意最后的类名不用带.class后缀，因为它默认是处理class文件，这个操作与前述的JAD的参数效果相同。<br />
DAVA采取了流程优化的方式进行反编译，与传统反编译思路不尽相同，但却对改变流程类的加密方法有独特的反编译效果。<br />
上述的三种工具各有千秋，但效果都非常不错。经测试，它们基本上都可以把JDK自带的一些例程完全反编译，然后不加任何修改可再编译成功，并能正常运行！</font>
</p>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/168177.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2007-12-17 11:11 <a href="http://www.blogjava.net/xyzroundo/articles/168177.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>abstract class和interface的区别</title><link>http://www.blogjava.net/xyzroundo/articles/168052.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Sun, 16 Dec 2007 03:33:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/168052.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/168052.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/168052.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/168052.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/168052.html</trackback:ping><description><![CDATA[<div align="left"><font face="楷体_gb2312"><strong><font color="#000000"><font size="2"><font>abstract class</font><font face="\&quot;新宋体\&quot;">和interface是Java语言中对于抽象类定义进行支持的两种机制，</font></font></font></strong></font><font face="新宋体"><font style="background-color: #ffffcc;"><font color="#000000"><font size="2"><strong>正
是由于这两种机制的存在，才赋予了Java强大的面向对象能力。abstract
class和interface之间在对于抽象类定义的支持方面具有很大的相似性，甚至可以相互替换，因此很多开发者在进行抽象类定义时对于
abstract
class和interface的选择显得比较随意。其实，两者之间还是有很大的区别的，对于它们的选择甚至反映出对于问题领域本质的理解、对于设计意图
的理解是否正确、合理。本文将对它们之间的区别进行一番剖析，试图给开发者提供一个在二者之间进行选择的依据。</strong></font></font></font><strong><font color="#000000"><font size="2"><font>  <br />
<br />
理解抽象类 </font></font></font></strong><strong><font color="#000000"><font size="2"><font> <br />
<br />
abstract
class和interface在Java语言中都是用来进行抽象类（本文中的抽象类并非从abstract
class翻译而来，它表示的是一个抽象体，而abstract
class为Java语言中用于定义抽象类的一种方法，请读者注意区分）定义的，那么什么是抽象类，使用抽象类能为我们带来什么好处呢？</font></font></font></strong><strong><font color="#000000"><font size="2"><font>  <br />
<br />
在
面向对象的概念中，我们知道所有的对象都是通过类来描绘的，但是反过来却不是这样。并不是所有的类都是用来描绘对象的，如果一个类中没有包含足够的信息来
描绘一个具体的对象，这样的类就是抽象类。抽象类往往用来表征我们在对问题领域进行分析、设计中得出的抽象概念，是对一系列看上去不同，但是本质上相同的
具体概念的抽象。比如：如果我们进行一个图形编辑软件的开发，就会发现问题领域存在着圆、三角形这样一些具体概念，它们是不同的，但是它们又都属于形状这
样一个概念，形状这个概念在问题领域是不存在的，它就是一个抽象概念。正是因为抽象的概念在问题领域没有对应的具体概念，所以用以表征抽象概念的抽象类是
不能够实例化的。</font></font></font></strong><strong><font color="#000000"><font size="2"><font>  <br />
<br />
在
面向对象领域，抽象类主要用来进行类型隐藏。我们可以构造出一个固定的一组行为的抽象描述，但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述
就是抽象类，而这一组任意个可能的具体实现则表现为所有可能的派生类。模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体，因此它可以是不允许修改
的；同时，通过从这个抽象体派生，也可扩展此模块的行为功能。熟悉OCP的读者一定知道，为了能够实现面向对象设计的一个最核心的原则OCP(Open-
Closed Principle)，抽象类是其中的关键所在。</font></font></font></strong><strong><font color="#000000"><font size="2"><font>  <br />
<br />
OCP(Open-Closed Principle)</font> <font face="\&quot;新宋体\&quot;">意
思是,在一个系统中,对于扩展是开放的,对于修改是关闭的,一个好的系统是在不修改源代码的情况下,可以扩展你的功能..而实现开闭原则的关键就是抽象
化. &nbsp;
在"开-闭"原则中,不允许修改的是抽象的类或者接口,允许扩展的是具体的实现类,抽象类和接口在"开-闭"原则中扮演着极其重要的角色，即要预知可能变
化的需求，又预见所有可能已知的扩展，所以在这里"抽象化"是关键!!!</font></font></font></strong></font></div>
<div align="left"><font style="background-color: #ffffcc;"><font color="#000000"><font size="2"><strong> </strong></font></font></font></div>
<div align="left"><strong><font color="#000000"><font size="2"><font>从语法定义层面看abstract class和interface</font></font></font></strong><font style="background-color: #ffffcc;"><font color="#000000"><font size="2"><strong>  <br />
<br />
</strong></font></font></font><font face="新宋体"><font style="background-color: #ffffcc;"><font color="#000000"><font size="2"><strong>在语法层面，Java语言对于abstract class和interface给出了不同的定义方式，下面以定义一个名为Demo的抽象类为例来说明这种不同。</strong></font></font></font><strong><font color="#000000"><font size="2"><font>  <br />
<br />
使用abstract class的方式定义Demo抽象类的方式如下：</font></font></font></strong><strong><font color="#000000"><font size="2"><font>  <br />
<br />
abstract class Demo ｛</font></font></font></strong><strong><font color="#000000"><font size="2"><font>  <br />
abstract void method1();  <br />
abstract void method2();  <br />
&#8230;  <br />
｝</font></font></font></strong><strong><font color="#000000"><font size="2"><font>  <br />
<br />
使用interface的方式定义Demo抽象类的方式如下：</font></font></font></strong><strong><font color="#000000"><font size="2"><font>  <br />
<br />
interface Demo {  <br />
void method1();  <br />
void method2();  <br />
&#8230;  <br />
}  <br />
<br />
在abstract
class方式中，Demo可以有自己的数据成员，也可以有非abstarct的成员方法，而在interface方式的实现中，Demo只能够有静态的
不能被修改的数据成员（也就是必须是static
final的，不过在interface中一般不定义数据成员），所有的成员方法都是abstract的。从某种意义上说，interface是一种特殊
形式的abstract class。</font></font></font></strong><strong><font color="#000000"><font size="2"><font>  <br />
<br />
&nbsp;  &nbsp; 从编程的角度来看，abstract class和interface都可以用来实现"design by contract "</font></font></font></strong></font><strong><font color="#000000"><font size="2"><font><font face="\&quot;新宋体\&quot;">(DBC,</font><font face="\&quot;新宋体\&quot;">契约式设计)</font></font></font></font></strong><font face="新宋体"><font style="background-color: #ffffcc;"><font color="#000000"><font size="2"><strong>的思想。但是在具体的使用上面还是有一些区别的。</strong></font></font></font><strong><font color="#000000"><font size="2"><font>  <br />
<br />
首先，abstract class在Java语言中表示的是一种继承关系，一个类只能使用一次继承关系。但是，一个类却可以实现多个interface。也许，这是Java语言的设计者在考虑Java对于多重继承的支持方面的一种折中考虑吧。</font></font></font></strong><strong><font color="#000000"><font size="2"><font>  <br />
<br />
其次，在abstract class的定义中，我们可以赋予方法的默认行为。但是在interface的定义中，方法却不能拥有默认行为，为了绕过这个限制，必须使用委托，但是这会 增加一些复杂性，有时会造成很大的麻烦。</font></font></font></strong><strong><font color="#000000"><font size="2"><font>  <br />
<br />
在
抽象类中不能定义默认行为还存在另一个比较严重的问题，那就是可能会造成维护上的麻烦。因为如果后来想修改类的界面（一般通过abstract
class或者interface来表示）以适应新的情况（比如，添加新的方法或者给已用的方法中添加新的参数）时，就会非常的麻烦，可能要花费很多的时
间（对于派生类很多的情况，尤为如此）。但是如果界面是通过abstract class来实现的，那么可能就只需要修改定义在abstract
class中的默认行为就可以了。</font></font></font></strong><strong><font color="#000000"><font size="2"><font>  <br />
<br />
同
样，如果不能在抽象类中定义默认行为，就会导致同样的方法实现出现在该抽象类的每一个派生类中，违反了"one rule，one
place"原则，造成代码重复，同样不利于以后的维护。因此，在abstract class和interface间进行选择时要非常的小心。</font></font></font></strong></font></div>
<font face="新宋体"><font face="\&quot;新宋体\&quot;"><strong><font color="#000000"><font>从设计理念层面看abstract class和interface </font></font></strong></font></font><font face="新宋体"><font style="background-color: #ffffcc;"><font color="#000000"><font size="2"> <br />
<br />
</font></font></font></font><font face="新宋体"><font style="background-color: #ffffcc;"><font color="#000000"><font size="2">上
面主要从语法定义和编程的角度论述了abstract
class和interface的区别，这些层面的区别是比较低层次的、非本质的。本小节将从另一个层面：abstract
class和interface所反映出的设计理念，来分析一下二者的区别。作者认为，从这个层面进行分析才能理解二者概念的本质所在。</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
前
面已经提到过，abstarct class在Java语言中体现了一种继承关系，要想使得继承关系合理，父类和派生类之间必须存在"is
a"关系，即父类和派生类在概念本质上应该是相同的（参考文献〔3〕中有关于"is
a"关系的大篇幅深入的论述，有兴趣的读者可以参考）。对于interface
来说则不然，并不要求interface的实现者和interface定义在概念本质上是一致的，仅仅是实现了interface定义的契约而已。为了使
论述便于理解，下面将通过一个简单的实例进行说明。</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
考虑这样一个例子，假设在我们的问题领域中有一个关于Door的抽象概念，该Door具有执行两个动作open和close，此时我们可以通过abstract class或者interface来定义一个表示该抽象概念的类型，定义方式分别如下所示：</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
使用abstract class方式定义Door：</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
abstract class Door {  <br />
abstract void open();  <br />
abstract void close()；</font></font></font><font color="#000000"><font size="2"><font>  <br />
}  <br />
<br />
&nbsp; <br />
使用interface方式定义Door：</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
<br />
interface Door {  <br />
void open();  <br />
void close();  <br />
}  <br />
<br />
&nbsp; <br />
其他具体的Door类型可以extends使用abstract class方式定义的Door或者implements使用interface方式定义的Door。看起来好像使用abstract class和interface没有大的区别。</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
如
果现在要求Door还要具有报警的功能。我们该如何设计针对该例子的类结构呢（在本例中，主要是为了展示abstract
class和interface反映在设计理念上的区别，其他方面无关的问题都做了简化或者忽略）。下面将罗列出可能的解决方案，并从设计理念层面对这些
不同的方案进行分析。</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
解决方案一：</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
简单的在Door的定义中增加一个alarm方法，如下：</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
abstract class Door {  <br />
abstract void open();  <br />
abstract void close()；</font></font></font><font color="#000000"><font size="2"><font>  <br />
abstract void alarm();  <br />
}  <br />
<br />
&nbsp; <br />
或者</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
interface Door {  <br />
void open();  <br />
void close();  <br />
void alarm();  <br />
}  <br />
<br />
&nbsp; <br />
那么具有报警功能的AlarmDoor的定义方式如下：</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
class AlarmDoor extends Door {  <br />
void open() { &#8230; }  <br />
void close() { &#8230; }  <br />
void alarm() { &#8230; }  <br />
}  <br />
<br />
&nbsp; <br />
或者</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
class AlarmDoor implements Door ｛</font></font></font><font color="#000000"><font size="2"><font>  <br />
void open() { &#8230; }  <br />
void close() { &#8230; }  <br />
void alarm() { &#8230; }  <br />
｝</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
这
种方法违反了面向对象设计中的一个核心原则ISP（Interface Segregation
Priciple），在Door的定义中把Door概念本身固有的行为方法和另外一个概念"报警器"的行为方法混在了一起。这样引起的一个问题是那些仅仅
依赖于Door这个概念的模块会因为"报警器"这个概念的改变（比如：修改alarm方法的参数）而改变，反之依然。</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
解决方案二：</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
既
然open、close和alarm属于两个不同的概念，根据ISP原则应该把它们分别定义在代表这两个概念的抽象类中。定义方式有：这两个概念都使用
abstract class方式定义；两个概念都使用interface方式定义；一个概念使用abstract
class方式定义，另一个概念使用interface方式定义。</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
显然，由于Java语言不支持多重继承，所以两个概念都使用abstract class方式定义是不可行的。后面两种方式都是可行的，但是对于它们的选择却反映出对于问题领域中的概念本质的理解、对于设计意图的反映是否正确、合理。我们一一来分析、说明。</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
如
果两个概念都使用interface方式来定义，那么就反映出两个问题：1、我们可能没有理解清楚问题领域，AlarmDoor在概念本质上到底是
Door还是报警器？2、如果我们对于问题领域的理解没有问题，比如：我们通过对于问题领域的分析发现AlarmDoor在概念本质上和Door是一致
的，那么我们在实现时就没有能够正确的揭示我们的设计意图，因为在这两个概念的定义上（均使用interface方式定义）反映不出上述含义。</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
如
果我们对于问题领域的理解是：AlarmDoor在概念本质上是Door，同时它有具有报警的功能。我们该如何来设计、实现来明确的反映出我们的意思呢？
前面已经说过，abstract class在Java语言中表示一种继承关系，而继承关系在本质上是"is
a"关系。所以对于Door这个概念，我们应该使用abstarct
class方式来定义。另外，AlarmDoor又具有报警功能，说明它又能够完成报警概念中定义的行为，所以报警概念可以通过interface方式定
义。如下所示：</font></font></font><font color="#000000"><font size="2"><font>  <br />
<br />
abstract class Door {  <br />
abstract void open();  <br />
abstract void close()；</font></font></font><font color="#000000"><font size="2"><font>  <br />
}  <br />
interface Alarm {  <br />
void alarm();  <br />
}  <br />
class AlarmDoor extends Door implements Alarm {  <br />
void open() { &#8230; }  <br />
void close() { &#8230; }  <br />
void alarm() { &#8230; }  <br />
}  <br />
<br />
&nbsp; <br />
这
种实现方式基本上能够明确的反映出我们对于问题领域的理解，正确的揭示我们的设计意图。其实abstract class表示的是"is
a"关系，interface表示的是"like a"（&#8220;has
a&#8221;）关系，大家在选择时可以作为一个依据，当然这是建立在对问题领域的理解上的，比如：如果我们认为AlarmDoor在概念本质上是报警器，同时又具
有Door的功能，那么上述的定义方式就要反过来了。</font></font></font></font>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/168052.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2007-12-16 11:33 <a href="http://www.blogjava.net/xyzroundo/articles/168052.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于AutoComplete（文本框的自动填充）</title><link>http://www.blogjava.net/xyzroundo/articles/167127.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Wed, 12 Dec 2007 01:32:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/167127.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/167127.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/167127.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/167127.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/167127.html</trackback:ping><description><![CDATA[1：默认情况下AutoComplete是打开的。见IE-工具-内容-自动完成选项<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" /><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">form</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" />请双击文本框&nbsp;</span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">input&nbsp;</span><span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">="text"</span><span style="color: rgb(255, 0, 0);">&nbsp;name</span><span style="color: rgb(0, 0, 255);">="wd"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">input&nbsp;</span><span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">="text"</span><span style="color: rgb(255, 0, 0);">&nbsp;name</span><span style="color: rgb(0, 0, 255);">="email"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" /></span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">form</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" /></span></div>
2：有时候我们并不需要AutoComplete，例如需要用户自己再次输入而非自动完成。只要将所在表单元素的autocomplete属性设置为off即可。<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" /><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">form</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" />请双击文本框&nbsp;</span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">input&nbsp;</span><span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">="text"</span><span style="color: rgb(255, 0, 0);">&nbsp;name</span><span style="color: rgb(0, 0, 255);">="wd"</span><span style="color: rgb(255, 0, 0);">&nbsp;autocomplete</span><span style="color: rgb(0, 0, 255);">="off"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">input&nbsp;</span><span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">="text"</span><span style="color: rgb(255, 0, 0);">&nbsp;name</span><span style="color: rgb(0, 0, 255);">="email"</span><span style="color: rgb(255, 0, 0);">&nbsp;autocomplete</span><span style="color: rgb(0, 0, 255);">="off"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" /></span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">form</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" /></span></div>
3：那么，如果所有表单元素都不想使用autocomplete功能呢？见下面的方法：<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" /><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">form&nbsp;</span><span style="color: rgb(255, 0, 0);">autocomplete</span><span style="color: rgb(0, 0, 255);">="off"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" />请双击文本框&nbsp;</span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">input&nbsp;</span><span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">="text"</span><span style="color: rgb(255, 0, 0);">&nbsp;name</span><span style="color: rgb(0, 0, 255);">="wd"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">input&nbsp;</span><span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">="text"</span><span style="color: rgb(255, 0, 0);">&nbsp;name</span><span style="color: rgb(0, 0, 255);">="email"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" /></span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">form</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" /></span></div>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/167127.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2007-12-12 09:32 <a href="http://www.blogjava.net/xyzroundo/articles/167127.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从javascript语言本身谈项目实战</title><link>http://www.blogjava.net/xyzroundo/articles/166450.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Sun, 09 Dec 2007 07:20:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/166450.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/166450.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/166450.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/166450.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/166450.html</trackback:ping><description><![CDATA[<strong>从javascript语言本身谈项目实战</strong><br />
<br />
[b]从javascript语言本身谈项目实战[/b]<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; dulao5 [url=http://dulao5.blog.hexun.com/2156811_d.html][color=blue]blog原文[/color][/url]<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; TrackBack Ping URL： [url=http://dulao5.blog.hexun.com/trackback.aspx?articleid=2156811][color=#000000]<br />
http://dulao5.blog.hexun.com/trackback.aspx?articleid=2156811[/color][/url] <br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp; 随着ajax的升温，javascript越来越得到人们的重视。重要的是，ajax在一定程度上带来了web软件架构上的变化，人们把越来越多的功能分配到客户端实现，javascript子项目规模越来越大。如何更高效的使用javascript，如何更科学的组织javascript，如何更顺利的保证项目进展？我想就我的经验谈一点浅见。<br />
<br />
[b]一。 开发人员需要认真学习javascript语言本身[/b]<br />
&nbsp; &nbsp;&nbsp; &nbsp; 由于javascript是世界上最被误解的语言, 大部分人对javascript语法并没有全面了解过，只是凭借看起来很像c或者java的关键字按照自己的理解写javascript代码。其实 javascript是一种很独特的语言，和c++/java有非常大的区别，要想用javascript做大一些的项目，开发人员必须老老实实的学习 javascript的语法。真正掌握了语法后，我们才不会把delete看成释放内存对象，才不会为到底参数传递是值传递还是引用传递而烦恼。真正理解了javascript的基于原型的OO方式，才可能写出具有良好架构的javascript程序。<br />
&nbsp; &nbsp;&nbsp; &nbsp; [color=Green]《javascript权威指南》[/color]是一本最合适的书，郑重推荐。另外[url=http://www.ecma-international.org/publications/standards/Ecma-262.htm][color=Green]ECMA262[/color][/url] 文档可以作为参考。网上流行的jscript手册chm版本使用起来比较方便，不过这是微软的jscript实现，和标准的javascript略有区别，使用时应该注意上面的注脚信息。关于javascript的原型和OO,网上已经有很多文章介绍了，在此不再多说。<br />
<br />
[b]二。 良好的代码来源于良好的设计[/b]<br />
&nbsp; &nbsp;&nbsp; &nbsp; 只有设计优良，代码才会写的漂亮。现在的javascript子项目已经不是以前web项目中的&#8220;边角料&#8221;和散兵游勇了，在较大的ajax项目内， javascript将非常复杂，ajax的异步模型也和以前顺序执行的程序设计有所区别。所以建议做javascript前首先做好设计。推荐使用用例驱动的方式，把用例分析清楚，以便全局考虑所有可能的页面交互过程，绘出页面内一些对象之间的交互图，分析一些数据对象的状态，作出精细的 javascript设计。<br />
<br />
[b]三。 使用设计模式，复用其他领域的设计经验[/b]<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;如果javascript非常复杂，可以考虑使用一些模式。我想大部分做javascript的开发者都不是&#8220;javascript科班&#8221;出身吧[img]掌握了javascript的语言本质，就可以复用我们在其他领域的经验了。使用javascript框架或者ajax框架，使用单例模式做一个全局的数据缓冲池，或者使用观察者模式把界面对象和数据对象分离，使用命令模式实现用户的操作队列等等。<br />
<br />
[b]四。 调试代码的技巧[/b]<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;javascript的代码不太好调试，这是由于：<br />
<br />
&nbsp; &nbsp; [b]* 一般的开发人员对javascript语言本身不太精通[/b]。也就是上面提到的。<br />
&nbsp; &nbsp; [b]* web项目包含较多的因素[/b]，复杂性加剧。服务端脚本、模板、html、js等很多环节都可能增加调试难度。<br />
&nbsp; &nbsp; [b]* 浏览器存在兼容性问题[/b]。有可能在一个细节问题上IE、Mozilla、opera等浏览器都有差异。<br />
&nbsp; &nbsp; [b]* 工具的缺乏[/b]。虽然mozilla的jsdebugger非常好用（还有bug，比如eval时调试器有些问题），但是其他浏览器环境下调试工具就不怎么样了。ms系统自带的script debug工具调试本地代码还可以，直接调试网站js代码表现欠佳。opera除了javascript控制台外我没有找到其他调试工具。<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp; 在此我推荐几个调试技巧：<br />
<br />
&nbsp; &nbsp;[b]1. 使用Mozilla firefox的jsdebugger插件。[/b]这个我不再多说了，最经典的js调试工具。在线调试远程站点的javascript效果非常棒。<br />
&nbsp; &nbsp;[b]2. 把问题隔离，建立本地的html文件和js文件，使用ms script debug调试工具来调试。[/b]如果js模块比较独立，可以使用这个工具的。如果写hta的项目，这个工具当然是首选了。<br />
&nbsp; &nbsp;[b]3. httpWatch[/b] 这是一个ie下的插件，非常好用，能够监视ie中的任何http会话，并能够看到http会话的原文。可以通过这个工具了解你的程序有没有和服务器产生会话，参数＆返回的数据到底是什么。<br />
&nbsp; &nbsp;[b]4. 在网页内建立用于调试的textarea[/b]<br />
&nbsp; &nbsp;&nbsp; &nbsp;可以在网页内建立一个textarea来接受你想运行的js语句，然后加一个按钮使用js的eval函数执行你输入的代码。<br />
&nbsp; &nbsp;&nbsp; &nbsp;这种方式非常适合在线调试，网页出错后写代码输出页面内的对象值。建议写一些dump工具函数配合使用，效果更佳。<br />
&nbsp; &nbsp;&nbsp; &nbsp;我非常喜欢这种方式，可以随时使用开关打开页面内隐藏的textarea进行调试，感觉很像给一台服务器接上了终端，然后使用shell可以做任何事情 函数可以在这里重新定义，可以任意操作界面中的任何元素，调用任何对象的任何函数，输出任何你需要的运行时刻值。<br />
&nbsp; &nbsp;[b]5. 使用异常(exception)和断言(assert)[/b]<br />
&nbsp; &nbsp;&nbsp; &nbsp;使用try{}catch(e){}结构不光可以屏蔽出错信息，让界面更友好。我们的程序可以使用异常、抛出异常来构建一种更好的出错处理机制。<br />
&nbsp; &nbsp;&nbsp; &nbsp;有这样一个故事，我在使用string.localeCompare函数时随手写了这样的代码：<br />
&nbsp; &nbsp;&nbsp; &nbsp;var iRe = str1.localeCompare(str2);<br />
&nbsp; &nbsp;&nbsp; &nbsp;switch(iRe){<br />
&nbsp; &nbsp;&nbsp; &nbsp;0: return ....<br />
&nbsp; &nbsp;&nbsp; &nbsp;1: return ....<br />
&nbsp; &nbsp;&nbsp; &nbsp;-1:return ....<br />
&nbsp; &nbsp;&nbsp; &nbsp;defalut:throw "error:localeCompare return other value"<br />
&nbsp; &nbsp;&nbsp; &nbsp;}<br />
&nbsp; &nbsp;&nbsp; &nbsp;写完就忘了，没想到我的同事在linux下使用firefox时，异常被抛出了，然后我们得知：linux firefox下localeCompare返回的不只是0/1/-1,而是返回一个具体值.<br />
&nbsp; &nbsp;&nbsp; &nbsp;这个异常抛出有效的检测出了代码的不完美。<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;firefox下的异常dump后能得到较为详细的调用栈信息，这一点非常好。IE的异常信息没有这么详细。<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;异常和断言也可以结合成为一个非常有效的调试工具。<br />
&nbsp; &nbsp;&nbsp; &nbsp;断言(assert)是在其他语言中的一种很有效的调试工具，常常以这种形式出现：<br />
&nbsp; &nbsp;&nbsp; &nbsp;assert(&nbsp;&nbsp;) ;<br />
&nbsp; &nbsp;&nbsp; &nbsp;在程序处于debug状态，当条件为假时，系统中止运行并报告这个断言。由于断言是我们自己定义的，所以我们可以很容易的判断出出错的地方，进而找到bug所在。<br />
&nbsp; &nbsp;&nbsp; &nbsp;javascript语言没有提供宏，也没有提供assert，我们可以这样模拟<br />
&nbsp; &nbsp;&nbsp; &nbsp;if(_is_debug) assert = function(expression , strLable){<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; if( !expression ) throw Error(strLable);<br />
&nbsp; &nbsp;&nbsp; &nbsp;}<br />
&nbsp; &nbsp;&nbsp; &nbsp;else assert = function(){};//_is_debug是一个全局变量<br />
&nbsp; &nbsp;&nbsp; &nbsp;这样可以实现在发生"不可能的事情"的时候，让程序在调试模式下抛出异常，在发布版本中不作理会。<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;可以这样输出当前栈的调用信息,弥补刚才提到的IE中异常对象没有栈信息的缺陷:<br />
&nbsp; &nbsp;&nbsp; &nbsp;function callStackInfo(){<br />
&nbsp; &nbsp;&nbsp; &nbsp;var s="",line="";<br />
&nbsp; &nbsp;&nbsp; &nbsp;var cer=arguments.callee.caller;<br />
&nbsp; &nbsp;&nbsp; &nbsp;while(cer){<br />
&nbsp; &nbsp;&nbsp; &nbsp;var sf=cer.toString();<br />
&nbsp; &nbsp;&nbsp; &nbsp;s+=line+sf.substring(sf.indexOf('function'),sf.indexOf('{'))+"\n";<br />
&nbsp; &nbsp;&nbsp; &nbsp;line=".."+line;<br />
&nbsp; &nbsp;&nbsp; &nbsp;cer=cer.caller;<br />
&nbsp; &nbsp;&nbsp; &nbsp;}<br />
&nbsp; &nbsp;&nbsp; &nbsp;return s;<br />
&nbsp; &nbsp;&nbsp; &nbsp;}<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp; 本文只就javascript在web开发，特别是在ajax方面的开发做了一些讨论，主要在于管窥如何更好的使用&#8220;纯javascript&#8221;。web开发还有很多其他方面，比如xml和Dom等实际上和javascript息息相关，但是本文没有涉及，还请见谅。欢迎各位朋友就我的讨论多提意见。
<img src ="http://www.blogjava.net/xyzroundo/aggbug/166450.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2007-12-09 15:20 <a href="http://www.blogjava.net/xyzroundo/articles/166450.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>获取客户端IP地址的方法 </title><link>http://www.blogjava.net/xyzroundo/articles/164656.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Sun, 02 Dec 2007 09:00:00 GMT</pubDate><guid>http://www.blogjava.net/xyzroundo/articles/164656.html</guid><wfw:comment>http://www.blogjava.net/xyzroundo/comments/164656.html</wfw:comment><comments>http://www.blogjava.net/xyzroundo/articles/164656.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xyzroundo/comments/commentRss/164656.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xyzroundo/services/trackbacks/164656.html</trackback:ping><description><![CDATA[<p>&nbsp;java 代码<span><span></span></span></p>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><span style="color: #008080;">&nbsp;1</span><img id="Codehighlighter1_66_285_Open_Image" onclick="this.style.display='none'; Codehighlighter1_66_285_Open_Text.style.display='none'; Codehighlighter1_66_285_Closed_Image.style.display='inline'; Codehighlighter1_66_285_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_66_285_Closed_Image" style="display: none;" onclick="this.style.display='none'; Codehighlighter1_66_285_Closed_Text.style.display='none'; Codehighlighter1_66_285_Open_Image.style.display='inline'; Codehighlighter1_66_285_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;String&nbsp;getClientAddress(HttpServletRequest&nbsp;request)&nbsp;</span><span id="Codehighlighter1_66_285_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_66_285_Open_Text"><span style="color: #000000;">{&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080;">&nbsp;2</span><span style="color: #000000;"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: #008080;">&nbsp;3</span><span style="color: #000000;"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;address&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;request.getHeader(</span><span style="color: #000000;">"</span><span style="color: #000000;">X-Forwarded-For</span><span style="color: #000000;">"</span><span style="color: #000000;">);&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080;">&nbsp;4</span><span style="color: #000000;"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: #008080;">&nbsp;5</span><span style="color: #000000;"><img id="Codehighlighter1_197_237_Open_Image" onclick="this.style.display='none'; Codehighlighter1_197_237_Open_Text.style.display='none'; Codehighlighter1_197_237_Closed_Image.style.display='inline'; Codehighlighter1_197_237_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_197_237_Closed_Image" style="display: none;" onclick="this.style.display='none'; Codehighlighter1_197_237_Closed_Text.style.display='none'; Codehighlighter1_197_237_Open_Image.style.display='inline'; Codehighlighter1_197_237_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(address&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;StringUtil.isIPAddress(address))&nbsp;</span><span id="Codehighlighter1_197_237_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_197_237_Open_Text"><span style="color: #000000;">{&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080;">&nbsp;6</span><span style="color: #000000;"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: #008080;">&nbsp;7</span><span style="color: #000000;"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;address;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080;">&nbsp;8</span><span style="color: #000000;"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: #008080;">&nbsp;9</span><span style="color: #000000;"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080;">10</span><span style="color: #000000;"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: #008080;">11</span><span style="color: #000000;"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;request.getRemoteAddr();&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080;">12</span><span style="color: #000000;"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: #008080;">13</span><span style="color: #000000;"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080;">14</span><span style="color: #000000;"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>
<p>&nbsp;</p>
<p>另外原因主要是Squid的使用：</p>
<p>参见：<a href="http://www.blogjava.net/Alpha/archive/2006/07/12/57764.aspx">www.blogjava.net/Alpha/archive/2006/07/12/57764.aspx</a></p>
<p>在很多应用下都可能有需要将用户的真实IP记录下来，这时就要获得用户的真实IP地址，在JSP里，获取客户端的IP地址的方法是：<strong>request.getRemoteAddr()</strong>，这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。<br />
<br />
这段时间在做IP统计的程序设计，由于服务器作了集群，使用了反向代理软件，将<a href="http://192.168.1.110:2046/">http://192.168.1.110:2046/</a>的URL反向代理为<a href="http://www.xxx.com/">http://www.xxx.com/</a>的URL时，用<strong>request.getRemoteAddr()</strong>方法获取的IP地址是：127.0.0.1　或　<u><font color="#0000ff">192.168.1.110</font></u>，而并不是客户端的真实ＩＰ。这是什么原因呢？<br />
<br />
这是反向代理的原因。经过代理以后，由于在客户端和服务之间增加了中间层，因此服务器无法直接拿到客户端的IP，服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中，增加了X－FORWARDED－FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。当我们访问<a href="http://www.xxx.com/index.jsp/">http://www.xxx.com/index.jsp/</a>时，其实并不是我们浏览器真正访问到了服务器上的index.jsp文件，而是先由代理服务器去访问<a href="http://xxx.xxx.xxx.xxx:2046/index.jsp">http://192.168.1.110:2046/index.jsp</a>，代理服务器再将访问到的结果返回给我们的浏览器，因为是代理服务器去访问index.jsp的，所以index.jsp中通过<strong>request.getRemoteAddr()</strong>的方法获取的IP实际上是代理服务器的地址，并不是客户端的IP地址。<br />
</p>
<img src ="http://www.blogjava.net/xyzroundo/aggbug/164656.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xyzroundo/" target="_blank">xyz</a> 2007-12-02 17:00 <a href="http://www.blogjava.net/xyzroundo/articles/164656.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>