﻿<?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-                                  &lt;center&gt;&lt;font size=5&gt;心的方向&lt;/center&gt;-随笔分类-J2EE</title><link>http://www.blogjava.net/zilong/category/21124.html</link><description>                           &lt;center&gt;   新的征途...... &lt;/center&gt;</description><language>zh-cn</language><lastBuildDate>Sat, 03 Jul 2010 04:42:59 GMT</lastBuildDate><pubDate>Sat, 03 Jul 2010 04:42:59 GMT</pubDate><ttl>60</ttl><item><title>强制类型转换－ArrayList使用toArray()构造数组时的问题</title><link>http://www.blogjava.net/zilong/archive/2010/06/25/324376.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Thu, 24 Jun 2010 16:49:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2010/06/25/324376.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/324376.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2010/06/25/324376.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/324376.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/324376.html</trackback:ping><description><![CDATA[<p><font face="Verdana" size="2">本文链接： <a href="http://blog.csdn.net/jrq/archive/2005/10/27/517428.aspx">http://blog.csdn.net/jrq/archive/2005/10/27/517428.aspx</a></font></p>
<p><font face="Verdana" size="2">正文：</font></p>
<p>1. 为了方便按列作外循环，想把ArrayList构造成一个二维数组，如下：</p>
<p>&nbsp;&nbsp;&nbsp; ......</p>
<p>&nbsp; ArrayList result=GetResult(); </p>
<p>&nbsp; int n=result.size();</p>
<p>&nbsp; String[][] myArray=new String[n][]; //定义二维数组<br />
&nbsp;<br />
&nbsp; for (int i=0;i&lt;n;i++)&nbsp; //构造二维数组<br />
&nbsp; {<br />
&nbsp;&nbsp;&nbsp; ArrayList tempArray= (ArrayList)result.get(i);<br />
&nbsp;&nbsp;&nbsp; myArray[i]=(String[])tempArray.toArray(); <br />
&nbsp; }</p>
<p>&nbsp; ......</p>
<p>程序可以编译通过。</p>
<p>但在运行到myArray[i]=(String[])tempArray.toArray()时，出现java.lang.ClassCastException的错误，很奇怪。</p>
<p>花了一晚上时间，查了N多资料，总算搞定了。现把问题记录下来，以备参考。</p>
<p>2. 此事从头说起。　　</p>
<p>ArrayList类扩展AbstractList并执行List接口。ArrayList支持可随需要而增长的动态数组。</p>
<p>&nbsp;&nbsp;&nbsp; ArrayList有如下的构造函数：<br />
　　<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ArrayList( )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ArrayList(Collection c)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ArrayList(int capacity)</p>
<p>如果调用new ArrayList()构造时，其默认的capacity(初始容量)为10。</p>
<p>参见ArrayList源码，其中是这样定义的：</p>
<p>&nbsp;&nbsp;&nbsp; public ArrayList() {<br />
　　this(10);<br />
&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>默认初始化内部数组大小为10。为什么是10？不知道。可能SUN觉得这样比较爽吧。</p>
<p>程序编译后执行ArrayList.toArray()，把ArrayList转化为数组时，该数组大小仍为capacity（为10）。</p>
<p>当 装入的数据和capacity值不等时（小于capacity），比如只装入了5个数据，数组中后面的（capacity - size）个对象将置为null，此时当数组强制类型转换时，容易出现一些问题，如java.lang.ClassCastException异常等。</p>
<p>解决办法是：在用ArrayList转化为数组装数据后，使用trimToSize()重新设置数组的真实大小。</p>
<p><br />
</p>
<p>3. 本例修改后的代码修如下，可顺利运行：</p>
<p>&nbsp; &nbsp; for (int i=0;i&lt;n;i++)&nbsp; //构造二维数组<br />
&nbsp; &nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; ArrayList tempArray= (ArrayList)result.get(i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;myArray[i]=(String[])tempArray.toArray(new String[0]);&nbsp;&nbsp; <font color="#ff0000">//注意此处的写法<br />
</font>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; }</p>
<p>&nbsp;看看下面这些也许就明白了－－</p>
<p>ArrayList.toArray()之一：</p>
<p>public Object[] toArray() {<br />
　　Object[] result = new Object[size];<br />
　　System.arraycopy(elementData, 0, result, 0, size);<br />
　　return result;<br />
}</p>
<p>返回ArrayList元素的一个数组，注意这里虽然生成了一个新的数组，但是数组元素和集合中的元素是共享的，Collection接口中说这个是安全的，这是不严格的。</p>
<p>下面的例子演示了这个效果。<br />
&nbsp;<br />
&nbsp;&nbsp; ArrayList al=new ArrayList();<br />
&nbsp;&nbsp; al.add(new StringBuffer("hello"));<br />
&nbsp;&nbsp; Object[] a=al.toArray();<br />
&nbsp;&nbsp; StringBuffer sb=(StringBuffer)a[0];<br />
&nbsp;&nbsp; sb.append("changed");&nbsp; //改变数组元素同样也改变了原来的ArrayList中的元素<br />
&nbsp;&nbsp; System.out.println(al.get(0)); 　　　 </p>
<p>这里不要用String来代替StringBuffer，因为String是不可变的。</p>
<p><br />
ArrayList.toArray()之二：</p>
<p>public Object[] toArray(Object a[]) {<br />
　　if (a.length &lt; size)<br />
　　　　a = (Object[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);<br />
　　 System.arraycopy(elementData, 0, a, 0, size);<br />
　　 if (a.length &gt; size)<br />
　　　　　　a[size] = null;<br />
　　 return a;<br />
}</p>
<p>这个方法有可能不需要生成新的数组，注意到如果数组a容量过大，只在size处设置为null。</p>
<p><font color="#ff0000">如果这个数组a足够大，就会把数据全放进去，返回的数组也是指向这个数组，（数组多余的空间存储的是null对象）；要是不够大，就申请一个跟参数同样类型的数组，把值放进去，然后返回。</font></p>
<p><br />
4. 网上的资料一：</p>
<p>&nbsp; public String[] getPlatformIDList()<br />
&nbsp; <br />
&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Vector result = new Vector();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Statement stmt = conn.createStatement();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String sql = "SELECT PlatformID FROM Platform";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rs = stmt.executeQuery(sql);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(rs.next())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result.add(rs.getString(1));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (result.size() &gt; 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String[] str = (String[]) result.toArray(); // 出现ClassCastException<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return str;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(Exception e)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; finally<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rs.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conn.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(Exception e2)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; 程序运行后，发现不能将Vector类经过toArray()方法得到的Object[]直接转换成String[]。</p>
<p>&nbsp;&nbsp;&nbsp; 找到用另一个带有参数的 toArray(T[] a)方法才可以。</p>
<p>&nbsp;&nbsp;&nbsp; 将该语句改为：</p>
<p>&nbsp;&nbsp;&nbsp; String[] str = (String[]) result.toArray(new String[1]);即告诉Vector，我要得到的数组的类型。</p>
<p>&nbsp;&nbsp;&nbsp; 回想一下，应该是java中的强制类型转换只是针对单个对象的，想要偷懒，将整个数组转换成另外一种类型的数组是不行的。</p>
<p><br />
5. 网上的资料二：</p>
<p>&nbsp;&nbsp;&nbsp; 正确使用List.toArray()－－<br />
&nbsp; <br />
&nbsp;&nbsp; 在程序中，往往得到一个List，程序要求对应赋值给一个array，可以这样写程序:<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; Long [] l = new Long[list.size()];<br />
&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;list.size();i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; l[i] = (Long) list.get(i);<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;要写这些code，似乎比较繁琐，其实List提供了toArray()的方法。<br />
&nbsp; &nbsp; 但是要使用不好，就会有ClassCastExceptiony异常。究竟这个是如何产生的，且看代码：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List list = new ArrayList();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list.add(new Long(1));list.add(new Long(2));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list.add(new Long(3));list.add(new Long(4));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#ff0000">Long[] l = (Long[])list.toArray();</font><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0; i&lt;l.length; i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(l[i].longValue());</p>
<p>&nbsp;&nbsp;&nbsp; 红色代码会抛java.lang.ClassCastException。</p>
<p>&nbsp;&nbsp;&nbsp; 当然，为了读出值来，你可以这样code:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object [] a =&nbsp; list.toArray();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;a.length;i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(((Long)a[i]).longValue());</p>
<p>&nbsp;&nbsp;&nbsp; 但是让数组丢失了类型信息，这个不是我们想要得。</p>
<p><br />
&nbsp;&nbsp;&nbsp; toArray()正确使用方式如下：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1)&nbsp;&nbsp;Long[] l = new Long[&lt;total size&gt;];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;list.toArray(l);<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2)&nbsp; Long[] l = (Long []) list.toArray(new Long[0]);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;3) &nbsp;Long [] a = new Long[&lt;total size&gt;];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Long [] l = (Long []) list.toArray(a);</p>
<p>6. 总结补充：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java sdk doc 上讲:<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Object[] toArray(Object[] a) </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a--the array into which the elements of this list are to be stored, if it is big enough; otherwise, a new array of the same&nbsp; runtime type is allocated for this purpose. </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果这个数组a足够大，就会把数据全放进去，返回的数组也是指向这个数组，（数组多余的空间存储的是null对象）；要是不够大，就申请一个跟参数同样类型的数组，把值放进去，然后返回。<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; 需要注意的是：你要是传入的参数为9个大小，而list里面有5个object,那么其他的四个很可能是null , 使用的时候要特别注意。</p>
<p>7. 完毕。</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; J.R.Q.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; 2005.10.27凌晨于广州&nbsp; </p>
<img src ="http://www.blogjava.net/zilong/aggbug/324376.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2010-06-25 00:49 <a href="http://www.blogjava.net/zilong/archive/2010/06/25/324376.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java异常(转载)</title><link>http://www.blogjava.net/zilong/archive/2008/08/26/224389.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Tue, 26 Aug 2008 02:06:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2008/08/26/224389.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/224389.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2008/08/26/224389.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/224389.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/224389.html</trackback:ping><description><![CDATA[<p>转自：http://www.blogjava.net/freeman1984/archive/2007/09/27/148850.html<br />
</p>
<p><font size="2">六种异常处理的陋习</font></p>
<p><font size="2">你觉得自己是一个Java专家吗？是否肯定自己已经全面掌握了Java的异常处理机制？在下面这段代码中，你能够迅速找出异常处理的六个问题吗？ <br />
<br />
</font></p>
<p>
<table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1">
    <tbody>
        <tr>
            <td><font size="2">1 OutputStreamWriter out = ... <br />
            2 java.sql.Connection conn = ... <br />
            3 try { // ⑸ <br />
            4 　Statement stat = conn.createStatement(); <br />
            5 　ResultSet rs = stat.executeQuery( <br />
            6 　　"select uid, name from user"); <br />
            7 　while (rs.next()) <br />
            8 　{ <br />
            9 　　out.println("ID：" + rs.getString("uid") // ⑹ <br />
            10 　　　"，姓名：" + rs.getString("name")); <br />
            11 　} <br />
            12 　conn.close(); // ⑶ <br />
            13 　out.close(); <br />
            14 } <br />
            15 catch(Exception ex) // ⑵ <br />
            16 { <br />
            17 　ex.printStackTrace(); //⑴，⑷ <br />
            18 }</font></td>
        </tr>
    </tbody>
</table>
</p>
<p><br />
<font size="2">　　作为一个Java程序员，你至少应该能够找出两个问题。但是，如果你不能找出全部六个问题，请继续阅读本文。 <br />
<br />
　　本文讨论的不是Java异常处理的一般性原则，因为这些原则已经被大多数人熟知。我们要做的是分析各种可称为&#8220;反例&#8221;（anti-pattern）的违背优秀编码规范的常见坏习惯，帮助读者熟悉这些典型的反面例子，从而能够在实际工作中敏锐地察觉和避免这些问题。 <br />
<br />
　　<strong>反例之一：丢弃异常 </strong><br />
<br />
　　代码：15行-18行。 <br />
<br />
　　这段代码捕获了异常却不作任何处理，可以算得上Java编程中的杀手。从问题出现的频繁程度和祸害程度来看，它也许可以和C/C++程序的一个恶名远播的问题相提并论??不检查缓冲区是否已满。如果你看到了这种丢弃（而不是抛出）异常的情况，可以百分之九十九地肯定代码存在问题（在极少数情况下，这段代码有存在的理由，但最好加上完整的注释，以免引起别人误解）。 <br />
<br />
　　这段代码的错误在于，异常（几乎）总是意味着某些事情不对劲了，或者说至少发生了某些不寻常的事情，我们不应该对程序发出的求救信号保持沉默和无动于衷。调用一下printStackTrace算不上&#8220;处理异常&#8221;。不错，调用printStackTrace对调试程序有帮助，但程序调试阶段结束之后，printStackTrace就不应再在异常处理模块中担负主要责任了。 <br />
<br />
　　丢弃异常的情形非常普遍。打开JDK的ThreadDeath类的文档，可以看到下面这段说明：&#8220;特别地，虽然出现ThreadDeath是一种&#8216;正常的情形&#8217;，但ThreadDeath类是Error而不是Exception的子类，因为许多应用会捕获所有的Exception然后丢弃它不再理睬。&#8221;这段话的意思是，虽然ThreadDeath代表的是一种普通的问题，但鉴于许多应用会试图捕获所有异常然后不予以适当的处理，所以JDK把ThreadDeath定义成了Error的子类，因为Error类代表的是一般的应用不应该去捕获的严重问题。可见，丢弃异常这一坏习惯是如此常见，它甚至已经影响到了Java本身的设计。 <br />
<br />
　　那么，应该怎样改正呢？主要有四个选择： <br />
<br />
　　1、处理异常。针对该异常采取一些行动，例如修正问题、提醒某个人或进行其他一些处理，要根据具体的情形确定应该采取的动作。再次说明，调用printStackTrace算不上已经&#8220;处理好了异常&#8221;。 <br />
<br />
　　2、重新抛出异常。处理异常的代码在分析异常之后，认为自己不能处理它，重新抛出异常也不失为一种选择。 <br />
<br />
　　3、把该异常转换成另一种异常。大多数情况下，这是指把一个低级的异常转换成应用级的异常（其含义更容易被用户了解的异常）。 <br />
<br />
　　4、不要捕获异常。 <br />
<br />
　　结论一：既然捕获了异常，就要对它进行适当的处理。不要捕获异常之后又把它丢弃，不予理睬。 <br />
<br />
　　<strong>反例之二：不指定具体的异常 </strong><br />
<br />
　　代码：15行。 <br />
<br />
　　许多时候人们会被这样一种&#8220;美妙的&#8221;想法吸引：用一个catch语句捕获所有的异常。最常见的情形就是使用catch(Exception ex)语句。但实际上，在绝大多数情况下，这种做法不值得提倡。为什么呢？ <br />
<br />
　　要理解其原因，我们必须回顾一下catch语句的用途。catch语句表示我们预期会出现某种异常，而且希望能够处理该异常。异常类的作用就是告诉Java编译器我们想要处理的是哪一种异常。由于绝大多数异常都直接或间接从java.lang.Exception派生，catch(Exception ex)就相当于说我们想要处理几乎所有的异常。 <br />
<br />
　　再来看看前面的代码例子。我们真正想要捕获的异常是什么呢？最明显的一个是SQLException，这是JDBC操作中常见的异常。另一个可能的异常是IOException，因为它要操作OutputStreamWriter。显然，在同一个catch块中处理这两种截然不同的异常是不合适的。如果用两个catch块分别捕获SQLException和IOException就要好多了。这就是说，catch语句应当尽量指定具体的异常类型，而不应该指定涵盖范围太广的Exception类。 <br />
<br />
　　另一方面，除了这两个特定的异常，还有其他许多异常也可能出现。例如，如果由于某种原因，executeQuery返回了null，该怎么办？答案是让它们继续抛出，即不必捕获也不必处理。实际上，我们不能也不应该去捕获可能出现的所有异常，程序的其他地方还有捕获异常的机会??直至最后由JVM处理。 <br />
<br />
　　结论二：在catch语句中尽可能指定具体的异常类型，必要时使用多个catch。不要试图处理所有可能出现的异常。 <br />
<br />
　　<strong>反例之三：占用资源不释放 </strong><br />
<br />
　　代码：3行-14行。 <br />
<br />
　　异常改变了程序正常的执行流程。这个道理虽然简单，却常常被人们忽视。如果程序用到了文件、Socket、JDBC连接之类的资源，即使遇到了异常，也要正确释放占用的资源。为此，Java提供了一个简化这类操作的关键词finally。 <br />
<br />
　　finally是样好东西：不管是否出现了异常，Finally保证在try/catch/finally块结束之前，执行清理任务的代码总是有机会执行。遗憾的是有些人却不习惯使用finally。 <br />
<br />
　　当然，编写finally块应当多加小心，特别是要注意在finally块之内抛出的异常??这是执行清理任务的最后机会，尽量不要再有难以处理的错误。 <br />
<br />
　　结论三：保证所有资源都被正确释放。充分运用finally关键词。</font></p>
<p><font size="2"><strong>反例之四：不说明异常的详细信息 <br />
<br />
</strong>　　代码：3行-18行。 <br />
<br />
　　仔细观察这段代码：如果循环内部出现了异常，会发生什么事情？我们可以得到足够的信息判断循环内部出错的原因吗？不能。我们只能知道当前正在处理的类发生了某种错误，但却不能获得任何信息判断导致当前错误的原因。 <br />
<br />
　　printStackTrace的堆栈跟踪功能显示出程序运行到当前类的执行流程，但只提供了一些最基本的信息，未能说明实际导致错误的原因，同时也不易解读。 <br />
<br />
　　因此，在出现异常时，最好能够提供一些文字信息，例如当前正在执行的类、方法和其他状态信息，包括以一种更适合阅读的方式整理和组织printStackTrace提供的信息。 <br />
<br />
　　结论四：在异常处理模块中提供适量的错误原因信息，组织错误信息使其易于理解和阅读。 <br />
<br />
　　<strong>反例之五：过于庞大的try块 </strong><br />
<br />
　　代码：3行-14行。 <br />
<br />
　　经常可以看到有人把大量的代码放入单个try块，实际上这不是好习惯。这种现象之所以常见，原因就在于有些人图省事，不愿花时间分析一大块代码中哪几行代码会抛出异常、异常的具体类型是什么。把大量的语句装入单个巨大的try块就象是出门旅游时把所有日常用品塞入一个大箱子，虽然东西是带上了，但要找出来可不容易。 <br />
<br />
　　一些新手常常把大量的代码放入单个try块，然后再在catch语句中声明Exception，而不是分离各个可能出现异常的段落并分别捕获其异常。这种做法为分析程序抛出异常的原因带来了困难，因为一大段代码中有太多的地方可能抛出Exception。 <br />
<br />
　　结论五：尽量减小try块的体积。 <br />
<br />
　　<strong>反例之六：输出数据不完整</strong> <br />
<br />
　　代码：7行-11行。 <br />
<br />
　　不完整的数据是Java程序的隐形杀手。仔细观察这段代码，考虑一下如果循环的中间抛出了异常，会发生什么事情。循环的执行当然是要被打断的，其次，catch块会执行??就这些，再也没有其他动作了。已经输出的数据怎么办？使用这些数据的人或设备将收到一份不完整的（因而也是错误的）数据，却得不到任何有关这份数据是否完整的提示。对于有些系统来说，数据不完整可能比系统停止运行带来更大的损失。 <br />
<br />
　　较为理想的处置办法是向输出设备写一些信息，声明数据的不完整性；另一种可能有效的办法是，先缓冲要输出的数据，准备好全部数据之后再一次性输出。 <br />
<br />
　　结论六：全面考虑可能出现的异常以及这些异常对执行流程的影响。 <br />
<br />
　　<strong>改写后的代码</strong> <br />
<br />
　　根据上面的讨论，下面给出改写后的代码。也许有人会说它稍微有点?嗦，但是它有了比较完备的异常处理机制。 <br />
<br />
</font>
<table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1">
    <tbody>
        <tr>
            <td><font size="2">OutputStreamWriter out = ... <br />
            java.sql.Connection conn = ... <br />
            try { <br />
            　Statement stat = conn.createStatement(); <br />
            　ResultSet rs = stat.executeQuery( <br />
            　　"select uid, name from user"); <br />
            　while (rs.next()) <br />
            　{ <br />
            　　out.println("ID：" + rs.getString("uid") + "，姓名: " + rs.getString("name")); <br />
            　} <br />
            } <br />
            catch(SQLException sqlex) <br />
            { <br />
            　out.println("警告：数据不完整"); <br />
            　throw new ApplicationException("读取数据时出现SQL错误", sqlex); <br />
            } <br />
            catch(IOException ioex) <br />
            { <br />
            　throw new ApplicationException("写入数据时出现IO错误", ioex); <br />
            } <br />
            finally <br />
            { <br />
            　if (conn != null) { <br />
            　　try { <br />
            　　　conn.close(); <br />
            　　} <br />
            　　catch(SQLException sqlex2) <br />
            　　{ <br />
            　　　System.err(this.getClass().getName() + ".mymethod - 不能关闭数据库连接: " + sqlex2.toString()); <br />
            　　} <br />
            　} <br />
            <br />
            　if (out != null) { <br />
            　　try { <br />
            　　　out.close(); <br />
            　　} <br />
            　　catch(IOException ioex2) <br />
            　　{ <br />
            　　　System.err(this.getClass().getName() + ".mymethod - 不能关闭输出文件" + ioex2.toString()); <br />
            　　} <br />
            　} <br />
            } </font></td>
        </tr>
    </tbody>
</table>
<br />
<font size="2">　　本文的结论不是放之四海皆准的教条，有时常识和经验才是最好的老师。如果你对自己的做法没有百分之百的信心，务必加上详细、全面的注释。 <br />
<br />
　　另一方面，不要笑话这些错误，不妨问问你自己是否真地彻底摆脱了这些坏习惯。即使最有经验的程序员偶尔也会误入歧途，原因很简单，因为它们确确实实带来了&#8220;方便&#8221;。所有这些反例都可以看作Java编程世界的恶魔，它们美丽动人，无孔不入，时刻诱惑着你。也许有人会认为这些都属于鸡皮蒜毛的小事，不足挂齿，但请记住：勿以恶小而为之，勿以善小而不为。<br />
<br />
<br />
<br />
<br />
<br />
------------------------------------------------------------------下面是一些java异常集-------------------------------------------------------------------------------------------</font></p>
<p><br />
&nbsp;</p>
<p>算术异常类：ArithmeticExecption</p>
<p>空指针异常类：NullPointerException</p>
<p>类型强制转换异常：ClassCastException</p>
<p>数组负下标异常：NegativeArrayException</p>
<p>数组下标越界异常：ArrayIndexOutOfBoundsException</p>
<p>违背安全原则异常：SecturityException</p>
<p>文件已结束异常：EOFException</p>
<p>文件未找到异常：FileNotFoundException</p>
<p>字符串转换为数字异常：NumberFormatException</p>
<p><br />
操作数据库异常：SQLException</p>
<p><br />
输入输出异常：IOException</p>
<p><br />
方法未找到异常：NoSuchMethodException</p>
<p>java.lang.AbstractMethodError</p>
<p>抽象方法错误。当应用试图调用抽象方法时抛出。</p>
<p>java.lang.AssertionError</p>
<p>断言错。用来指示一个断言失败的情况。</p>
<p>java.lang.ClassCircularityError</p>
<p>类循环依赖错误。在初始化一个类时，若检测到类之间循环依赖则抛出该异常。</p>
<p>java.lang.ClassFormatError</p>
<p>类格式错误。当Java虚拟机试图从一个文件中读取Java类，而检测到该文件的内容不符合类的有效格式时抛出。</p>
<p>java.lang.Error</p>
<p>错误。是所有错误的基类，用于标识严重的程序运行问题。这些问题通常描述一些不应被应用程序捕获的反常情况。</p>
<p>java.lang.ExceptionInInitializerError</p>
<p>初始化程序错误。当执行一个类的静态初始化程序的过程中，发生了异常时抛出。静态初始化程序是指直接包含于类中的static语句段。</p>
<p>java.lang.IllegalAccessError</p>
<p>违法访问错误。当一个应用试图访问、修改某个类的域（Field）或者调用其方法，但是又违反域或方法的可见性声明，则抛出该异常。</p>
<p>java.lang.IncompatibleClassChangeError</p>
<p>不兼容的类变化错误。当正在执行的方法所依赖的类定义发生了不兼容的改变时，抛出该异常。一般在修改了应用中的某些类的声明定义而没有对整个应用重新编译而直接运行的情况下，容易引发该错误。</p>
<p>java.lang.InstantiationError</p>
<p>实例化错误。当一个应用试图通过Java的new操作符构造一个抽象类或者接口时抛出该异常.</p>
<p>java.lang.InternalError</p>
<p>内部错误。用于指示Java虚拟机发生了内部错误。</p>
<p>java.lang.LinkageError</p>
<p>链接错误。该错误及其所有子类指示某个类依赖于另外一些类，在该类编译之后，被依赖的类改变了其类定义而没有重新编译所有的类，进而引发错误的情况。</p>
<p>java.lang.NoClassDefFoundError</p>
<p>未找到类定义错误。当Java虚拟机或者类装载器试图实例化某个类，而找不到该类的定义时抛出该错误。</p>
<p>java.lang.NoSuchFieldError</p>
<p>域不存在错误。当应用试图访问或者修改某类的某个域，而该类的定义中没有该域的定义时抛出该错误。</p>
<p>java.lang.NoSuchMethodError</p>
<p>方法不存在错误。当应用试图调用某类的某个方法，而该类的定义中没有该方法的定义时抛出该错误。</p>
<p>java.lang.OutOfMemoryError</p>
<p>内存不足错误。当可用内存不足以让Java虚拟机分配给一个对象时抛出该错误。</p>
<p>java.lang.StackOverflowError</p>
<p>堆栈溢出错误。当一个应用递归调用的层次太深而导致堆栈溢出时抛出该错误。</p>
<p>java.lang.ThreadDeath</p>
<p>线程结束。当调用Thread类的stop方法时抛出该错误，用于指示线程结束。</p>
<p>java.lang.UnknownError</p>
<p>未知错误。用于指示Java虚拟机发生了未知严重错误的情况。</p>
<p>java.lang.UnsatisfiedLinkError</p>
<p>未满足的链接错误。当Java虚拟机未找到某个类的声明为native方法的本机语言定义时抛出。</p>
<p>java.lang.UnsupportedClassVersionError</p>
<p>不支持的类版本错误。当Java虚拟机试图从读取某个类文件，但是发现该文件的主、次版本号不被当前Java虚拟机支持的时候，抛出该错误。</p>
<p>java.lang.VerifyError</p>
<p>验证错误。当验证器检测到某个类文件中存在内部不兼容或者安全问题时抛出该错误。</p>
<p>java.lang.VirtualMachineError</p>
<p>虚拟机错误。用于指示虚拟机被破坏或者继续执行操作所需的资源不足的情况。</p>
<p><br />
java.lang.ArithmeticException</p>
<p>算术条件异常。譬如：整数除零等。</p>
<p>java.lang.ArrayIndexOutOfBoundsException</p>
<p>数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。</p>
<p>java.lang.ArrayStoreException</p>
<p>数组存储异常。当向数组中存放非数组声明类型对象时抛出。</p>
<p>java.lang.ClassCastException</p>
<p>类造型异常。假设有类A和B（A不是B的父类或子类），O是A的实例，那么当强制将O构造为类B的实例时抛出该异常。该异常经常被称为强制类型转换异常。</p>
<p>java.lang.ClassNotFoundException</p>
<p>找不到类异常。当应用试图根据字符串形式的类名构造类，而在遍历CLASSPAH之后找不到对应名称的class文件时，抛出该异常。</p>
<p>java.lang.CloneNotSupportedException</p>
<p>不支持克隆异常。当没有实现Cloneable接口或者不支持克隆方法时,调用其clone()方法则抛出该异常。</p>
<p>java.lang.EnumConstantNotPresentException</p>
<p>枚举常量不存在异常。当应用试图通过名称和枚举类型访问一个枚举对象，但该枚举对象并不包含常量时，抛出该异常。</p>
<p>java.lang.Exception</p>
<p>根异常。用以描述应用程序希望捕获的情况。</p>
<p>java.lang.IllegalAccessException</p>
<p>违法的访问异常。当应用试图通过反射方式创建某个类的实例、访问该类属性、调用该类方法，而当时又无法访问类的、属性的、方法的或构造方法的定义时抛出该异常。</p>
<p>java.lang.IllegalMonitorStateException</p>
<p>违法的监控状态异常。当某个线程试图等待一个自己并不拥有的对象（O）的监控器或者通知其他线程等待该对象（O）的监控器时，抛出该异常。</p>
<p>java.lang.IllegalStateException</p>
<p>违法的状态异常。当在Java环境和应用尚未处于某个方法的合法调用状态，而调用了该方法时，抛出该异常。</p>
<p>java.lang.IllegalThreadStateException</p>
<p>违法的线程状态异常。当县城尚未处于某个方法的合法调用状态，而调用了该方法时，抛出异常。</p>
<p>java.lang.IndexOutOfBoundsException</p>
<p>索引越界异常。当访问某个序列的索引值小于0或大于等于序列大小时，抛出该异常。</p>
<p>java.lang.InstantiationException</p>
<p>实例化异常。当试图通过newInstance()方法创建某个类的实例，而该类是一个抽象类或接口时，抛出该异常。</p>
<p>java.lang.InterruptedException</p>
<p>被中止异常。当某个线程处于长时间的等待、休眠或其他暂停状态，而此时其他的线程通过Thread的interrupt方法终止该线程时抛出该异常。</p>
<p>java.lang.NegativeArraySizeException</p>
<p>数组大小为负值异常。当使用负数大小值创建数组时抛出该异常。</p>
<p>java.lang.NoSuchFieldException</p>
<p>属性不存在异常。当访问某个类的不存在的属性时抛出该异常。</p>
<p>java.lang.NoSuchMethodException</p>
<p>方法不存在异常。当访问某个类的不存在的方法时抛出该异常。</p>
<p>java.lang.NullPointerException</p>
<p>空指针异常。当应用试图在要求使用对象的地方使用了null时，抛出该异常。譬如：调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等。</p>
<p>java.lang.NumberFormatException</p>
<p>数字格式异常。当试图将一个String转换为指定的数字类型，而该字符串确不满足数字类型要求的格式时，抛出该异常。</p>
<p>java.lang.RuntimeException</p>
<p>运行时异常。是所有Java虚拟机正常操作期间可以被抛出的异常的父类。</p>
<p>java.lang.SecurityException</p>
<p>安全异常。由安全管理器抛出，用于指示违反安全情况的异常。</p>
<p>java.lang.StringIndexOutOfBoundsException</p>
<p>字符串索引越界异常。当使用索引值访问某个字符串中的字符，而该索引值小于0或大于等于序列大小时，抛出该异常。</p>
<p>java.lang.TypeNotPresentException</p>
<p>类型不存在异常。当应用试图以某个类型名称的字符串表达方式访问该类型，但是根据给定的名称又找不到该类型是抛出该异常。该异常与ClassNotFoundException的区别在于该异常是unchecked（不被检查）异常，而ClassNotFoundException是checked（被检查）异常。</p>
<p>java.lang.UnsupportedOperationException</p>
<p>不支持的方法异常。指明请求的方法不被支持情况的异常。</p>
<p>异常<br />
javax.servlet.jsp.JspException: Cannot retrieve mapping for action /Login （/Login是你的action名字）&nbsp;&nbsp; </p>
<p>可能原因<br />
action没有再struts-config.xml 中定义，或没有找到匹配的action，例如在JSP文件中使用 &lt;html:form action="Login.do".将表单提交给Login.do处理，如果出现上述异常，请查看struts-config.xml中的定义部分，有时可能是打错了字符或者是某些不符合规则，可以使用strutsconsole工具来检查。<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
org.apache.jasper.JasperException: Cannot retrieve definition for form bean null</p>
<p>可能原因&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
这个异常是因为Struts根据struts-config.xml中的mapping没有找到action期望的form bean。大部分的情况可能是因为在form-bean中设置的name属性和action中设置的name属性不匹配所致。换句话说，action和form都应该各自有一个name属性，并且要精确匹配，包括大小写。这个错误当没有name属性和action关联时也会发生，如果没有在action中指定name属性，那么就没有name属性和action相关联。当然当action制作某些控制时，譬如根据参数值跳转到相应的jsp页面，而不是处理表单数据，这是就不用name属性，这也是action的使用方法之一。<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
No action instance for path /xxxx could be created</p>
<p>可能原因<br />
特别提示：因为有很多中情况会导致这个错误的发生，所以推荐大家调高你的web服务器的日志/调试级别，这样可以从更多的信息中看到潜在的、在试图创建action类时发生的错误，这个action类你已经在struts-config.xml中设置了关联（即添加了&lt;action&gt;标签）。</p>
<p>在struts-config.xml中通过action标签的class属性指定的action类不能被找到有很多种原因，例如：定位编译后的.class文件失败。Failure to place compiled .class file for the action in the classpath (在web开发中，class的的位置在r WEB-INF/classes，所以你的action class必须要在这个目录下。例如你的action类位于WEB-INF/classes/action/Login.class,那么在struts-config.xml中设置action的属性type时就是action.Login).<br />
拼写错误，这个也时有发生，并且不易找到，特别注意第一个字母的大小写和包的名称。 <br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
javax.servlet.jsp.JspException: No getter method for property username of bean org.apache.struts.taglib.html.BEAN</p>
<p>可能原因<br />
没有位form bean中的某个变量定义getter 方法</p>
<p>这个错误主要发生在表单提交的FormBean中，用struts标记&lt;html:text property=&#8221;username&#8221;&gt;时，在FormBean中必须有一个getUsername()方法。注意字母&#8220;U&#8221;。<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
java.lang.NoClassDefFoundError: org/apache/struts/action/ActionForm</p>
<p>可能原因<br />
这个错误主要发生在在classpath中找不到相应的Java .class文件。如果这个错误发生在web应用程序的运行时，主要是因为指定的class文件不在web server的classpath中（/WEB-INF/classes 和 /WEB-INF/lib）。在上面的错误中，原因是找不到ActionForm类。<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
javax.servlet.jsp.JspException: Exception creating bean of class org.apache.struts.action.ActionForm: {1}</p>
<p>可能原因<br />
Instantiating Struts-provided ActionForm class directly instead of instantiating a class derived off ActionForm. This mightoccur implicitly if you specify that a form-bean is this Struts ActionForm class rather than specifying a child of this classfor the form-bean.</p>
<p>Not associating an ActionForm-descended class with an action can also lead to this error.<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
javax.servlet.jsp.JspException: Cannot find ActionMappings or ActionFormBeans collection</p>
<p>可能原因<br />
不是标识Struts actionServlet的&lt;servlet&gt;标记就是映射.do扩展名的&lt;sevlet-mapping&gt;标记或者两者都没有在web.xml中声明。</p>
<p>在struts-config.xml中的打字或者拼写错误也可导致这个异常的发生。例如缺少一个标记的关闭符号/&gt;。最好使用struts console工具检查一下。</p>
<p>另外，load-on-startup必须在web.xml中声明，这要么是一个空标记，要么指定一个数值，这个数值用来表servlet运行的优先级，数值越大优先级越低。</p>
<p>还有一个和使用load-on-startup有关的是使用Struts预编译JSP文件时也可能导致这个异常。<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
java.lang.NullPointerException at org.apache.struts.util.RequestUtils.forwardURL(RequestUtils.java:1223)</p>
<p>可能原因<br />
在struts-config.xml中的forward元素缺少path属性。例如应该是如下形式：<br />
&lt;forward name="userhome" path="/user/userhome.jsp"/&gt;<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
javax.servlet.jsp.JspException: Cannot find bean org.apache.struts.taglib.html.BEAN in any scope</p>
<p><br />
&nbsp; </p>
<p>Probable Causes<br />
试图在Struts的form标记外使用form的子元素。这常常发生在你在&lt;/html:form&gt;后面使用Struts的html标记。另外要注意可能你不经意使用的无主体的标记，如&lt;html:form &#8230; /&gt;，这样web 服务器解析时就当作一个无主体的标记，随后使用的所有&lt;html&gt;标记都被认为是在这个标记之外的，如又使用了&lt;html:text property=&#8221;id&#8221;&gt;还有就是在使用taglib引入HTML标记库时，你使用的prefix的值不是html。<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
javax.servlet.jsp.JspException: Missing message for key xx.xx.xx</p>
<p>Probable Causes<br />
这个key的值对没有在资源文件ApplicationResources.properties中定义。如果你使用eclipse时经常碰到这样的情况，当项目重新编译时，eclipse会自动将classes目录下的资源文件删除。</p>
<p>资源文件ApplicationResources.properties 不在classpath中应将资源文件放到 WEB-INF/classes 目录下，当然要在struts-config.xml中定义)<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
Cannot find message resources under key org.apache.struts.action.MESSAGE</p>
<p>可能原因<br />
很显然，这个错误是发生在使用资源文件时，而Struts没有找到资源文件。</p>
<p>Implicitly trying to use message resources that are not available (such as using empty html:options tag instead of specifyingthe options in its body -- this assumes options are specified in ApplicationResources.properties file)</p>
<p>XML parser issues -- too many, too few, incorrect/incompatible versions<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
Strange and seemingly random characters in HTML and on screen, but not in original JSP or servlet.</p>
<p>可能原因<br />
混和使用Struts的html:form标记和标准的HTML标记不正确。</p>
<p>使用的编码样式在本页中不支持。<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
"Document contained no data" in Netscape</p>
<p>No data rendered (completely empty) page in Microsoft Internet Explorer</p>
<p>可能原因<br />
使用一个Action的派生类而没有实现perform()方法或execute()方法。在Struts1.0中实现的是perform()方法，在Struts1.1中实现的是execute()方法，但Struts1.1向后兼容perform()方法。但你使用Struts1.1创建一个Action的派生类，并且实现了execute()方法，而你在Struts1.0中运行的话，就会得到"Document contained nodata" error message in Netscape or a completely empty (no HTML whatsoever) page rendered in Microsoft Internet Explorer.&#8221;的错误信息。</p>
<p>---------------------------------------------------------------------------------------------------------------------------<br />
异常<br />
ServletException: BeanUtils.populate<br />
解决方案<br />
在用Struts上传文件时,遇到了javax.servlet.ServletException: BeanUtils.populate异常。<br />
我的ActionServlet并没有用到BeanUtils这些工具类。后来仔细检查代码发现是在jsp文件里的form忘了加enctype=&amp;quot;multipart/form-data&amp;quot; 了。所以写程序遇到错误或异常应该从多方面考虑问题存在的可能性，想到系统提示信息以外的东西。<br />
----------------------------------------------------------------------------------------------------------------------------<br />
1. 定义Action后, 如果指定了name, 那么必须要定义一个与它同名的FormBean才能进行form映射.2. 如果定义Action后, 提交页面时出现 "No input attribute for mapping path..." 错误, 则需要在其input属性中定义转向的页面.3. 如果插入新的数据时出现 "Batch update row count wrong:..." 错误, 则说明XXX.hbm.xml中指定的key的类型为原始类型(int, long),因为这种类型会自动分配值, 而这个值往往会让系统认为已经存在该记录, 正确的方法是使用java.lang.Integer或java.lang.Long对象.4. 如果插入数据时出现 "argument type mismatch" 错误, 可能是你使用了Date等特殊对象, 因为struts不能自动从String型转换成Date型,所以, 你需要在Action中手动把String型转换成Date型.5. Hibernate中, Query的iterator()比list()方法快很多.6. 如果出现 "equal symbol expected" 错误, 说明你的strtus标签中包含另一个标签或者变量, 例如:<br />
&lt;html:select property="test" onchange="&lt;%=test%&gt;"/&gt;<br />
或者<br />
&lt;html:hidden property="test" value="&lt;bean:write name="t" property="p"/&gt;"/&gt;<br />
这样的情况... <br />
---------------------------------------------------------------------------------------------------------------------------<br />
错误：Exception in thread "main" org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update原因与解决：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 因为Hibernate Tools（或者Eclipse本身的Database Explorer）生成*.hbn.xml工具中包含有catalog="***"（*表示数据库名称）这样的属性,将该属性删除就可以了<br />
---------------------------------------------------------------------------------------------------------------------------<br />
错误：org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations)<br />
原因与解决：<br />
方法1 删除Set方的cascade<br />
方法2 解决关联关系后，再删除<br />
方法3 在many-to-one方增加cascade 但值不能是none<br />
最后一招：<br />
检查一下hashCode equals是否使用了id作为唯一标示的选项了；我用uuid.hex时是没有问题的；但是用了native，就不行了，怎么办？删除啊！<br />
----------------------------------------------------------------------------------------------------------------------------<br />
问题：今天用Tomcat 5.5.12，发现原来很好用的系统不能用了，反复测试发现页面中不能包含 taglib，否则会出现以下提示：HTTP Status 500 -type Exception reportMessage description The server encountered an internal error () that prevented it from fulfilling this request.exceptionorg.apache.jasper.JasperException: /index.jsp(1,1) Unable to read TLD "META-INF/tlds/struts-bean.tld" from JAR file"file:*****/WEB-INF/lib/struts.jar":原因：更新了工程用的lib文件夹下的jar，发布时也发布了servlet.jar和jsp-api.jar。解决：把jsp-api.jar删除就解决这个问题了。-----------------------------------------------------------------------------------------------------------------------------<br />
错误： java.lang.NullPointerException<br />
原因： 发现 dao 实例、 manage 实例等需要注入的东西没有被注入（俗称空指针异常）解决：这个时候，你应该查看日志文件；默认是应用服务器的 log 文件，比如 Tomcat 就是 [Tomcat 安装目录 ]/logs ；你会发现提示你：可能是：org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sf' defined in ServletContextresource [/WEB-INF/applicationContext.xml]: Initialization of bean failed; nested exception isorg.hibernate.HibernateException: could not configure from URL: file:src/hibernate.cfg.xmlorg.hibernate.HibernateException: could not configure from URL: file:src/hibernate.cfg.xml&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.Caused by: java.io.FileNotFoundException: src\hibernate.cfg.xml可能是：org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined inServletContext resource [/WEB-INF/applicationContext.xml]: Initialization of bean failed; nested exception isorg.hibernate.MappingException: Resource: com/mcc/coupon/model/UserRole.hbm.xml not foundorg.hibernate.MappingException: Resource: com/mcc/coupon/model/UserRole.hbm.xml not found然后你就知道原因是因为配置文件的解析出了错误，这个通过 Web 页面是看不出来的。更多的是持久化影射文件出的错误；导致了没有被解析；当然你需要的功能就无法使用了。<br />
----------------------------------------------------------------------------------------------------------------------------<br />
错误：StandardWrapperValve[action]: Servlet.service() for servlet action threw exception<br />
javax.servlet.jsp.JspException: Cannot retrieve mapping for action /settlementTypeManage<br />
或者：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type Status report&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; message Servlet action is not available&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; description The requested resource (Servlet action is not available) is not available.<br />
原因： 同 上<br />
----------------------------------------------------------------------------------------------------------------------------<br />
错误StandardWrapperValve[jsp]: Servlet.service() for servlet jsp threw exceptionjava.lang.ClassNotFoundException: org.apache.struts.taglib.bean.CookieTei界面错误具体描述：<br />
org.apache.jasper.JasperException: Failed to load or instantiate TagExtraInfo class: org.apache.struts.taglib.bean.CookieTei<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 原因与解决：&nbsp;&nbsp;&nbsp; &lt;方案一&gt;你的&#8220;html:&#8221;开头的标签没有放在一个&lt;html:form&gt;中&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;方案二&gt;重新启动你的应用服务器，自动就没有这个问题<br />
</p>
<img src ="http://www.blogjava.net/zilong/aggbug/224389.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2008-08-26 10:06 <a href="http://www.blogjava.net/zilong/archive/2008/08/26/224389.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>追MM与Java的23种设计模式</title><link>http://www.blogjava.net/zilong/archive/2008/08/18/222886.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Mon, 18 Aug 2008 14:17:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2008/08/18/222886.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/222886.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2008/08/18/222886.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/222886.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/222886.html</trackback:ping><description><![CDATA[转自：http://freeman983.javaeye.com/blog/215073<br />
<p><strong>创建型模式 <br />
</strong>　　1、FACTORY―追MM少不了请吃饭了，麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西，虽然口味有所不同，但不管你带MM去麦当劳或肯德基，只管向服务员说&#8220;来四个鸡翅&#8221;就行了。麦当劳和肯德基就是生产鸡翅的Factory <br />
　　<br />
　　工厂模式：客户类和工厂类分开。消费者任何时候需要某种产品，只需向工厂请求即可。消费者无须修改就可以接纳新产品。缺点是当产品修改时，工厂类也要做相应的修改。如：如何创建及如何向客户端提供。 <br />
　　<br />
　　2、BUILDER―MM最爱听的就是&#8220;我爱你&#8221;这句话了，见到不同地方的MM,要能够用她们的方言跟她说这句话哦，我有一个多种语言翻译机，上面每种语言都有一个按键，见到MM我只要按对应的键，它就能够用相应的语言说出&#8220;我爱你&#8221;这句话了，国外的MM也可以轻松搞掂，这就是我的&#8220;我爱你&#8221;builder。（这一定比美军在伊拉克用的翻译机好卖） <br />
　　<br />
　　建造模式：将产品的内部表象和产品的生成过程分割开来，从而使一个建造过程生成具有不同的内部表象的产品对象。建造模式使得产品内部表象可以独立的变化，客户不必知道产品内部组成的细节。建造模式可以强制实行一种分步骤进行的建造过程。 <br />
　　<br />
　　3、FACTORY METHOD―请MM去麦当劳吃汉堡，不同的MM有不同的口味，要每个都记住是一件烦人的事情，我一般采用Factory Method模式，带着MM到服务员那儿，说&#8220;要一个汉堡&#8221;，具体要什么样的汉堡呢，让MM直接跟服务员说就行了。 <br />
　　<br />
　　工厂方法模式：核心工厂类不再负责所有产品的创建，而是将具体创建的工作交给子类去做，成为一个抽象工厂角色，仅负责给出具体工厂类必须实现的接口，而不接触哪一个产品类应当被实例化这种细节。 <br />
　　<br />
　　4、PROTOTYPE―跟MM用QQ聊天，一定要说些深情的话语了，我搜集了好多肉麻的情话，需要时只要copy出来放到QQ里面就行了，这就是我的情话prototype了。（100块钱一份，你要不要） <br />
　　<br />
　　原始模型模式：通过给出一个原型对象来指明所要创建的对象的类型，然后用复制这个原型对象的方法创建出更多同类型的对象。原始模型模式允许动态的增加或减少产品类，产品类不需要非得有任何事先确定的等级结构，原始模型模式适用于任何的等级结构。缺点是每一个类都必须配备一个克隆方法。 <br />
　　<br />
　　5、SINGLETON―俺有6个漂亮的老婆，她们的老公都是我，我就是我们家里的老公Sigleton，她们只要说道&#8220;老公&#8221;，都是指的同一个人，那就是我(刚才做了个梦啦，哪有这么好的事) <br />
　　<br />
　　单例模式：单例模式确保某一个类只有一个实例，而且自行实例化并向整个系统提供这个实例单例模式。单例模式只应在有真正的&#8220;单一实例&#8221;的需求时才可使用。 <br />
　　<br />
　　<strong>结构型模式</strong><br />
　　6、ADAPTER―在朋友聚会上碰到了一个美女Sarah，从香港来的，可我不会说粤语，她不会说普通话，只好求助于我的朋友kent了，他作为我和Sarah之间的Adapter，让我和Sarah可以相互交谈了(也不知道他会不会耍我) <br />
　　<br />
　　适配器（变压器）模式：把一个类的接口变换成客户端所期待的另一种接口，从而使原本因接口原因不匹配而无法一起工作的两个类能够一起工作。适配类可以根据参数返还一个合适的实例给客户端。 <br />
　　<br />
　　7、BRIDGE―早上碰到MM，要说早上好，晚上碰到MM，要说晚上好；碰到MM穿了件新衣服，要说你的衣服好漂亮哦，碰到MM新做的发型，要说你的头发好漂亮哦。不要问我&#8220;早上碰到MM新做了个发型怎么说&#8221;这种问题，自己用BRIDGE组合一下不就行了 <br />
　　<br />
　　桥梁模式：将抽象化与实现化脱耦，使得二者可以独立的变化，也就是说将他们之间的强关联变成弱关联，也就是指在一个软件系统的抽象化和实现化之间使用组合/聚合关系而不是继承关系，从而使两者可以独立的变化。 <br />
　　<br />
　　8、COMPOSITE―Mary今天过生日。&#8220;我过生日，你要送我一件礼物。&#8221;&#8220;嗯，好吧，去商店，你自己挑。&#8221;&#8220;这件T恤挺漂亮，买，这条裙子好看，买，这个包也不错，买。&#8221;&#8220;喂，买了三件了呀，我只答应送一件礼物的哦。&#8221;&#8220;什么呀，T恤加裙子加包包，正好配成一套呀，小姐，麻烦你包起来。&#8221;&#8220;&#8230;&#8230;&#8221;，MM都会用Composite模式了，你会了没有？ <br />
　　<br />
　　合成模式：合成模式将对象组织到树结构中，可以用来描述整体与部分的关系。合成模式就是一个处理对象的树结构的模式。合成模式把部分与整体的关系用树结构表示出来。合成模式使得客户端把一个个单独的成分对象和由他们复合而成的合成对象同等看待。 <br />
　　<br />
　　9、DECORATOR―Mary过完轮到Sarly过生日，还是不要叫她自己挑了，不然这个月伙食费肯定玩完，拿出我去年在华山顶上照的照片，在背面写上&#8220;最好的的礼物，就是爱你的Fita&#8221;，再到街上礼品店买了个像框（卖礼品的MM也很漂亮哦），再找隔壁搞美术设计的Mike设计了一个漂亮的盒子装起来&#8230;&#8230;，我们都是Decorator，最终都在修饰我这个人呀，怎么样，看懂了吗？ <br />
　　<br />
　　装饰模式：装饰模式以对客户端透明的方式扩展对象的功能，是继承关系的一个替代方案，提供比继承更多的灵活性。动态给一个对象增加功能，这些功能可以再动态的撤消。增加由一些基本功能的排列组合而产生的非常大量的功能。 <br />
　　<br />
　　10、FACADE―我有一个专业的Nikon相机，我就喜欢自己手动调光圈、快门，这样照出来的照片才专业，但MM可不懂这些，教了半天也不会。幸好相机有Facade设计模式，把相机调整到自动档，只要对准目标按快门就行了，一切由相机自动调整，这样MM也可以用这个相机给我拍张照片了。 <br />
　　<br />
　　门面模式：外部与一个子系统的通信必须通过一个统一的门面对象进行。门面模式提供一个高层次的接口，使得子系统更易于使用。每一个子系统只有一个门面类，而且此门面类只有一个实例，也就是说它是一个单例模式。但整个系统可以有多个门面类。 <br />
　　<br />
　　11、FLYWEIGHT―每天跟MM发短信，手指都累dead了，最近买了个新手机，可以把一些常用的句子存在手机里，要用的时候，直接拿出来，在前面加上MM的名字就可以发送了，再不用一个字一个字敲了。共享的句子就是Flyweight，MM的名字就是提取出来的外部特征，根据上下文情况使用。 <br />
　　<br />
　　享元模式：FLYWEIGHT在拳击比赛中指最轻量级。享元模式以共享的方式高效的支持大量的细粒度对象。享元模式能做到共享的关键是区分内蕴状态和外蕴状态。内蕴状态存储在享元内部，不会随环境的改变而有所不同。外蕴状态是随环境的改变而改变的。外蕴状态不能影响内蕴状态，它们是相互独立的。将可以共享的状态和不可以共享的状态从常规类中区分开来，将不可以共享的状态从类里剔除出去。客户端不可以直接创建被共享的对象，而应当使用一个工厂对象负责创建被共享的对象。享元模式大幅度的降低内存中对象的数量。 <br />
　　<br />
　　12、PROXY―跟MM在网上聊天，一开头总是&#8220;hi,你好&#8221;,&#8220;你从哪儿来呀？&#8221;&#8220;你多大了？&#8221;&#8220;身高多少呀？&#8221;这些话，真烦人，写个程序做为我的Proxy吧，凡是接收到这些话都设置好了自动的回答，接收到其他的话时再通知我回答，怎么样，酷吧。 <br />
　　<br />
　　代理模式：代理模式给某一个对象提供一个代理对象，并由代理对象控制对源对象的引用。代理就是一个人或一个机构代表另一个人或者一个机构采取行动。某些情况下，客户不想或者不能够直接引用一个对象，代理对象可以在客户和目标对象直接起到中介的作用。客户端分辨不出代理主题对象与真实主题对象。代理模式可以并不知道真正的被代理对象，而仅仅持有一个被代理对象的接口，这时候代理对象不能够创建被代理对象，被代理对象必须有系统的其他角色代为创建并传入。 <br />
　　<br />
　　<strong> 行为模式 </strong><br />
　　13、CHAIN OF RESPONSIBLEITY―晚上去上英语课，为了好开溜坐到了最后一排，哇，前面坐了好几个漂亮的MM哎，找张纸条，写上&#8220;Hi,可以做我的女朋友吗？如果不愿意请向前传&#8221;，纸条就一个接一个的传上去了，糟糕，传到第一排的MM把纸条传给老师了，听说是个老处女呀，快跑! <br />
　　<br />
　　责任链模式：在责任链模式中，很多对象由每一个对象对其下家的引用而接 <br />
　　<br />
　　起来形成一条链。请求在这个链上传递，直到链上的某一个对象决定处理此请求。客户并不知道链上的哪一个对象最终处理这个请求，系统可以在不影响客户端的情况下动态的重新组织链和分配责任。处理者有两个选择：承担责任或者把责任推给下家。一个请求可以最终不被任何接收端对象所接受。 <br />
　　<br />
　　14、COMMAND―俺有一个MM家里管得特别严，没法见面，只好借助于她弟弟在我们俩之间传送信息，她对我有什么指示，就写一张纸条让她弟弟带给我。这不，她弟弟又传送过来一个COMMAND，为了感谢他，我请他吃了碗杂酱面，哪知道他说：&#8220;我同时给我姐姐三个男朋友送COMMAND，就数你最小气，才请我吃面。&#8221;， <br />
　　<br />
　　命令模式：命令模式把一个请求或者操作封装到一个对象中。命令模式把发出命令的责任和执行命令的责任分割开，委派给不同的对象。命令模式允许请求的一方和发送的一方独立开来，使得请求的一方不必知道接收请求的一方的接口，更不必知道请求是怎么被接收，以及操作是否执行，何时被执行以及是怎么被执行的。系统支持命令的撤消。 <br />
　　<br />
　　15、INTERPRETER―俺有一个《泡MM真经》，上面有各种泡MM的攻略，比如说去吃西餐的步骤、去看电影的方法等等，跟MM约会时，只要做一个Interpreter，照着上面的脚本执行就可以了。 <br />
　　<br />
　　解释器模式：给定一个语言后，解释器模式可以定义出其文法的一种表示，并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子。解释器模式将描述怎样在有了一个简单的文法后，使用模式设计解释这些语句。在解释器模式里面提到的语言是指任何解释器对象能够解释的任何组合.</p>
<img src ="http://www.blogjava.net/zilong/aggbug/222886.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2008-08-18 22:17 <a href="http://www.blogjava.net/zilong/archive/2008/08/18/222886.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>优化WebSphere应用性能技巧集锦</title><link>http://www.blogjava.net/zilong/archive/2008/04/08/191447.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Tue, 08 Apr 2008 05:03:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2008/04/08/191447.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/191447.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2008/04/08/191447.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/191447.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/191447.html</trackback:ping><description><![CDATA[<span id="Label4">&nbsp; 转自：http://blog.tostudy.com.cn/blog/show_3574.html
<p>优化Web应用的性能绝不象有些人想象的那样简单易行，它涉及到诸多技术，从最简单的HTML代码修改，到复杂的EJB改造，无不涉及性能问题。但有一点是非常清楚的：要想找出和解决Web应用的性能瓶颈，就必须深入全面地了解信息在Web应用中的流程。 </p>
<p>　　改善Web应用的性能不一定要局限于Web应用的Java代码，例如有些时候，简单地改动一下HTML页面的质量、减少其传输频度和数据量就可以有效地提高应用的性能表现；有时提高性能的关键却在于修改Web应用的数据库访问部分——这只是Java代码之外影响性能的两个因素，其他还有许多因素会影响到Web应用的整体性能表现。另一方面，就Java程序本身而言，其性能优化又可以分成三个领域：基本的Java代码优化，JSP/Servlet优化，EJB优化。 </p>
<p>　　一、表现层优化 </p>
<p>　　Web应用的最大性能瓶颈常常不在其他地方，而在于最基本的网络带宽限制。如果你的Web应用也面临这类问题，提高性能最简单的办法是减少HTTP传输，例如用JavaScript实现客户端编辑功能以减少数据传输次数，避免将数据发送到服务器端再执行合法性验证之类的编辑操作。 </p>
<p>　　应当采用一切可能措施减少通过网络传输的数据。例如，你可以要求浏览器缓冲模块化的JavaScript文件，在SCRIPT标记的SRC中指定： <br />
SCRIPT LANGUAGE="JavaScript" SRC="FormChek.js"。</p>
<p>　　其他减少网络传输应当注意的地方还包括：避免过度使用隐藏域，减少超长Cookie值，在RADIO、CHECKBOX和SELECT域中用代码来替代长长的字符串，等等。不过在HTML优化方面本文不准备作全面的讨论，因为WebSphere应用的开发者一般不会担负设计表现层的责任，只要了解下面这个原理就足够了： </p>
<p>　　性能技巧之一：尽可能减少HTTP数据传输的总量和频度 </p>
<p>　　二、数据库访问 </p>
<p>　　朋友小A对Java的了解极为有限，但他却成功地改进了许多WebSphere应用的性能。他是怎么做到的呢？原来，小A是一个数据库专家，他通过优化数据库访问有效地改进了整个应用的性能，但对于Java，他只是略微了解一些有关JDBC的知识。在优化数据库访问时，小A做的第一件事情总是检查数据库的设计，有时他会建议重新构造数据库的结构（必须指出的是，为了提高性能而重新构造数据库结构有时可能使数据库反规格化（De-Normalization），从而带来维护方面的问题）。&nbsp; <br />
性能技巧之二：规格化（Normalization）数据库结构</p>
<p>　　小A做的第二件事情是执行数据库分析，根据分析结果提出增加某个索引、减少某个索引的建议。完成这一步骤后，小A通常可以让应用有令人满意的性能表现，根本不必去查看应用的Java代码。 </p>
<p>　　性能技巧之三：针对常用的SQL操作建立索引，删除多余的索引 </p>
<p>　　有时，为了进一步优化应用的性能，小A会检查Java（也许应该说是SQL）代码，经常找到Java程序没有合理运用PreparedStatement和连接缓冲池的情形。只要把Statement类的动态SQL替换成PreparedStatement类的静态SQL，从连接池提取SQL连接（而不是直接创建连接），应用的性能将得到显著的改善。注意DB2 UDB（包括其他一些数据库）的PreparedStatement是可调整和配置的。 </p>
<p>　　性能技巧之四：合理运用PreparedStatement和连接池 </p>
<p>　　进一步分析应用的工作流程之后，小A有时会建议批量执行某些SQL命令，这样就只需一个对数据库服务器的请求就可以运行大量的SQL命令。 </p>
<p>　　性能技巧之五：考虑批量执行SQL命令</p>
<p>　　既然如此，小A有时还会指出，如果应用中有些SQL命令可以组合成单个事务逻辑，那么应该可以用一个存储过程来替代。DB2 UDB的存储过程语言（SPL，Stored Procedure Language）非常强大，如果把数据库操作逻辑从Web应用转移到数据库，一般总是对性能有益。不过需要注意的是，虽然批量执行SQL命令或使用存储过程会提高性能，但就象重新构造数据库结构一样，有时会带来维护方面的困难。 </p>
<p>　　性能技巧之六：考虑使用数据库存储过程</p>
<p>　　检查JDBC代码的时候，小A总是留意对象有没有及时正确释放。这一点其实很重要。 </p>
<p>　　性能技巧之七：及时关闭不用的Statement、ResultSet、Connection等对象（但不是在finalize方法内） </p>
<p>三、Java代码 </p>
<p>　　前面我们以小A的经验为例，探讨了Web应用中数据库访问性能的重要性。调整好数据库之后，接下来要做的自然是深入分析应用的Java代码。从哪里入手呢？你最好使用Java分析工具来找出性能问题的焦点所在。优化Java代码的性能是一个艰苦的过程，因此一个重要的原则是把精力集中到那些可能引起性能问题的代码上。换句话说，就是要尊重80/20规则：利用Java分析工具的结果，调整带来80%性能开销的那20%代码。 </p>
<p>　　性能技巧之八：用Java分析工具清楚地界定性能问题所在 </p>
<p>　　目前市场上已经有许多优秀的Java分析工具，例如ej-technologie的JProfile（<a href="http://www.ej-technologies.com/">http://www.ej-technologies.com</a>），Klgroup的Jprobe（<a href="http://www.klg.com/">http://www.klg.com</a>），以及Intuitive Systems的OptimizeIt（<a href="http://www.optimizeit.com/">http://www.optimizeit.com</a>）。不过不要忘记WebSphere Studio Application Developer（WSAD）本身也集成了一个优秀的分析器，有条件的话，最好多用几种分析工具分析Java代码。 </p>
<p>　　考虑到资金问题，你不一定乐意购买昂贵的分析软件，但你可以用Java本身的命令行工具生成分析信息。例如，在JDK 1.3中，你可以用下面的命令将TestOrderProcessing类的CPU使用情况保存到java.hprof文件：java -Xrunhprof:cpu=times,format=a,file=java.hprof TestOrderProcessing。 </p>
<p>　　这种办法的缺点是它提供的信息条理不够清楚，比较繁杂；也许可以找到一些源代码开放的工具辅助分析，但一般不如使用WSAD本身的分析工具或商业化的分析工具方便。另外，如果你已经了解哪些代码块可能引起性能问题，可以通过保存系统时间的方式获得分析信息，例如： <br />
long startTime = System.currentTimeMillis(); <br />
// 执行某些操作<br />
long endTime = System.currentTimeMillis();</p>
<p>　　3.1 基本篇 </p>
<p>　　有人建议&#8220;稳定性第一，速度第二&#8221;，一般而言遵从这个建议是不会错的，但这并不妨碍我们在编写代码的同时运用某些已经证实的性能技巧。例如，我们都知道String类是不可变的，连接两个String是一项开销很大操作。 </p>
<p>　　性能技巧之九：用StringBuffer来连接两个字符串</p>
<p>　　也许你已经注意到，SUN的许多标准Java类是线程安全的，这些类内部的同步机制实际上很容易造成性能问题。例如，Vector类就是一个线程安全的类，除非确实要用到同步机制，否则使用Vector是不值得的，如有可能，应当尽量改用非线程安全的类如ArrayList。 </p>
<p>　　性能技巧之十：只有在必要时才运用线程安全的类</p>
<p>　　许多人习惯使用System.out.println来输出跟踪信息，但println要占用不少资源，所以输出跟踪信息最好使用专用日志记录框架，如IBM的JRas或Apache的Log4j。 </p>
<p>　　性能技巧之十一：用日志记录框架类输出跟踪信息，而不是使用System.out.println </p>
<p>　　最后一个提高代码性能的简单技巧是清除类里面的调试信息，减小类的体积。IBM有一个WSAD插件，它提供了一个叫做setDebugInfo的任务，可以从Ant脚本调用。 </p>
<p>　　性能技巧之十二：从正式发行的软件中删除调试信息<br />
</p>
</span>
<img src ="http://www.blogjava.net/zilong/aggbug/191447.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2008-04-08 13:03 <a href="http://www.blogjava.net/zilong/archive/2008/04/08/191447.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>web.xml配置的详细说明3</title><link>http://www.blogjava.net/zilong/archive/2008/04/06/191070.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Sun, 06 Apr 2008 09:42:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2008/04/06/191070.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/191070.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2008/04/06/191070.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/191070.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/191070.html</trackback:ping><description><![CDATA[<strong>web.xml配置的详细说明3</strong><br />
7 指定欢迎页
<p>假如用户提供了一个像http: //host/webAppPrefix/directoryName/ 这样的包含一个目录名但没有包含文件名的URL，会发生什么事情呢？用户能得到一个目录表？一个错误？还是标准文件的内容？如果得到标准文件内容，是 index.html、index.jsp、default.html、default.htm或别的什么东西呢？<br />
Welcome-file-list 元素及其辅助的welcome-file元素解决了这个模糊的问题。例如，下面的web.xml项指出，如果一个URL给出一个目录名但未给出文件名，服务器应该首先试用index.jsp，然后再试用index.html。如果两者都没有找到，则结果有赖于所用的服务器（如一个目录列表）。<br />
&lt;welcome-file-list&gt;<br />
&lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;<br />
&lt;welcome-file&gt;index.html&lt;/welcome-file&gt;<br />
&lt;/welcome-file-list&gt;<br />
虽然许多服务器缺省遵循这种行为，但不一定必须这样。因此，明确地使用welcom-file-list保证可移植性是一种良好的习惯。</p>
<p>8 指定处理错误的页面</p>
<p>现在我了解到，你在开发servlet和JSP页面时从不会犯错误，而且你的所有页面是那样的清晰，一般的程序员都不会被它们的搞糊涂。但是，是人总会犯错误的，用户可能会提供不合规定的参数，使用不正确的URL或者不能提供必需的表单字段值。除此之外，其它开发人员可能不那么细心，他们应该有些工具来克服自己的不足。<br />
error-page元素就是用来克服这些问题的。它有两个可能的子元素，分别是：error-code和exception- type。第一个子元素error-code指出在给定的HTTP错误代码出现时使用的URL。第二个子元素excpetion-type指出在出现某个给定的Java异常但未捕捉到时使用的URL。error-code和exception-type都利用location元素指出相应的URL。此 URL必须以/开始。location所指出的位置处的页面可通过查找HttpServletRequest对象的两个专门的属性来访问关于错误的信息，这两个属性分别是：javax.servlet.error.status_code和javax.servlet.error.message。<br />
可回忆一下，在web.xml内以正确的次序声明web-app的子元素很重要。这里只要记住，error-page出现在web.xml文件的末尾附近，servlet、servlet-name和welcome-file-list之后即可。</p>
<p>8.1 error-code元素<br />
为了更好地了解error-code元素的值，可考虑一下如果不正确地输入文件名，大多数站点会作出什么反映。这样做一般会出现一个404错误信息，它表示不能找到该文件，但几乎没提供更多有用的信息。另一方面，可以试一下在<a href="http://www.microsoft.com/">www.microsoft.com</a>、<a href="http://www.ibm.com/">www.ibm.com</a> 处或者特别是在<a href="http://www.bea.com/">www.bea.com</a> 处输出未知的文件名。这是会得出有用的消息，这些消息提供可选择的位置，以便查找感兴趣的页面。提供这样有用的错误页面对于Web应用来说是很有价值得。事实上rm-error-page子元素）。由form-login-page给出的HTML表单必须具有一个j_security_check的 ACTION属性、一个名为j_username的用户名文本字段以及一个名为j_password的口令字段。<br />
例如，程序清单5-19指示服务器使用基于表单的验证。Web应用的顶层目录中的一个名为login.jsp的页面将收集用户名和口令，并且失败的登陆将由相同目录中名为login-error.jsp的页面报告。</p>
<p>程序清单5-19 web.xml（说明login-config的摘录）<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE web-app<br />
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />
"<a href="http://java.sun.com/dtd/web-app_2_3.dtd">http://java.sun.com/dtd/web-app_2_3.dtd</a>"&gt;</p>
<p>&lt;web-app&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;security-constraint&gt; ... &lt;/security-constraint&gt;<br />
&lt;login-config&gt;<br />
&lt;auth-method&gt; FORM &lt;/auth-method&gt;<br />
&lt;form-login-config&gt;<br />
&lt;form-login-page&gt;/login.jsp&lt;/form-login-page&gt;<br />
&lt;form-error-page&gt;/login-error.jsp&lt;/form-error-page&gt;<br />
&lt;/form-login-config&gt;<br />
&lt;/login-config&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;/web-app&gt;</p>
<p>8.2 exception-type元素<br />
error-code元素处理某个请求产生一个特定的HTTP状态代码时的情况。然而，对于servlet或JSP页面返回200但产生运行时异常这种同样是常见的情况怎么办呢？这正是exception-type元素要处理的情况。只需提供两样东西即可：即提供如下的一个完全限定的异常类和一个位置：<br />
&lt;error-page&gt;<br />
&lt;exception-type&gt;packageName.className&lt;/exception-type&gt;<br />
&lt;location&gt;/SomeURL&lt;/location&gt;<br />
&lt;/error-page&gt;<br />
这样，如果Web应用中的任何servlet或JSP页面产生一个特定类型的未捕捉到的异常，则使用指定的URL。此异常类型可以是一个标准类型，如javax.ServletException或java.lang.OutOfMemoryError，或者是一个专门针对你的应用的异常。<br />
例如，程序清单5-15给出了一个名为DumbDeveloperException的异常类，可用它来特别标记经验较少的程序员（不是说你的开发组中一定有这种人）所犯的错误。这个类还包含一个名为dangerousComputation的静态方法，它时不时地生成这种类型的异常。程序清单5-16给出对随机整数值调用dangerousCompution的一个JSP页面。在抛出此异常时，如程序清单5-18的web.xml版本中所给出的exception-type所指出的那样，对客户机显示DDE.jsp（程序清单5-17）。图5-16和图5-17分别给出幸运和不幸的结果。 </p>
<p>程序清单5-15 DumbDeveloperException.java<br />
package moreservlets;</p>
<p>/** Exception used to flag particularly onerous<br />
programmer blunders. Used to illustrate the<br />
exception-type web.xml element.<br />
* &lt;P&gt;<br />
* Taken from More Servlets and JavaServer Pages<br />
* from Prentice Hall and Sun Microsystems Press,<br />
* <a href="http://www.moreservlets.com/">http://www.moreservlets.com/</a>.<br />
* &amp;copy; 2002 Marty Hall; may be freely used or adapted.<br />
*/</p>
<p>public class DumbDeveloperException extends Exception {<br />
public DumbDeveloperException() {<br />
super("Duh. What was I *thinking*?");<br />
}</p>
<p>public static int dangerousComputation(int n)<br />
throws DumbDeveloperException {<br />
if (n &lt; 5) {<br />
return(n + 10);<br />
} else {<br />
throw(new DumbDeveloperException());<br />
}<br />
}<br />
}</p>
<p><br />
程序清单5-16 RiskyPage.jsp<br />
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />
&lt;HTML&gt;<br />
&lt;HEAD&gt;&lt;TITLE&gt;Risky JSP Page&lt;/TITLE&gt;&lt;/HEAD&gt;<br />
&lt;BODY BGCOLOR="#FDF5E6"&gt;<br />
&lt;H2&gt;Risky Calculations&lt;/H2&gt;<br />
&lt;%@ page import="moreservlets.*" %&gt;<br />
&lt;% int n = ((int)(10 * Math.random())); %&gt;<br />
&lt;UL&gt;<br />
&lt;LI&gt;n: &lt;%= n %&gt;<br />
&lt;LI&gt;dangerousComputation(n): <br />
&lt;%= DumbDeveloperException.dangerousComputation(n) %&gt;<br />
&lt;/UL&gt;<br />
&lt;/BODY&gt;&lt;/HTML&gt;</p>
<p><br />
程序清单5-17 DDE.jsp<br />
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />
&lt;HTML&gt;<br />
&lt;HEAD&gt;&lt;TITLE&gt;Dumb&lt;/TITLE&gt;&lt;/HEAD&gt;<br />
&lt;BODY BGCOLOR="#FDF5E6"&gt;<br />
&lt;H2&gt;Dumb Developer&lt;/H2&gt;<br />
We're brain dead. Consider using our competitors.<br />
&lt;/BODY&gt;&lt;/HTML&gt;</p>
<p><br />
程序清单5-18 web.xml（为异常指定错误页面的摘录）<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE web-app<br />
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />
"<a href="http://java.sun.com/dtd/web-app_2_3.dtd">http://java.sun.com/dtd/web-app_2_3.dtd</a>"&gt;</p>
<p>&lt;web-app&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet&gt; &#8230; &lt;/servlet&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;error-page&gt;<br />
&lt;exception-type&gt;<br />
moreservlets.DumbDeveloperException<br />
&lt;/exception-type&gt;<br />
&lt;location&gt;/DDE.jsp&lt;/location&gt;<br />
&lt;/error-page&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;/web-app&gt;</p>
<p>9 提供安全性</p>
<p>利用web.xml中的相关元素为服务器的内建功能提供安全性。<br />
9.1 指定验证的方法<br />
使用login-confgi元素规定服务器应该怎样验证试图访问受保护页面的用户。它包含三个可能的子元素，分别是：auth-method、realm-name和form-login-config。login-config元素应该出现在web.xml部署描述符文件的结尾附近，紧跟在security-constraint元素之后。<br />
l auth-method<br />
login-config的这个子元素列出服务器将要使用的特定验证机制。有效值为BASIC、DIGEST、FORM和CLIENT-CERT。服务器只需要支持BASIC和FORM。<br />
BASIC指出应该使用标准的HTTP验证，在此验证中服务器检查Authorization头。如果缺少这个头则返回一个401状态代码和一个WWW-Authenticate头。这导致客户机弹出一个用来填写Authorization头的对话框。此机制很少或不提供对攻击者的防范，这些攻击者在Internet连接上进行窥探（如通过在客户机的子网上执行一个信息包探测装置），因为用户名和口令是用简单的可逆base64编码发送的，他们很容易得手。所有兼容的服务器都需要支持BASIC验证。<br />
DIGEST指出客户机应该利用加密Digest Authentication形式传输用户名和口令。这提供了比BASIC验证更高的防范网络截取得的安全性，但这种加密比SSL（HTTPS）所用的方法更容易破解。不过，此结论有时没有意义，因为当前很少有浏览器支持Digest Authentication，所以servlet容器不需要支持它。<br />
FORM指出服务器应该检查保留的会话cookie并且把不具有它的用户重定向到一个指定的登陆页。此登陆页应该包含一个收集用户名和口令的常规HTML表单。在登陆之后，利用保留会话级的cookie跟踪用户。虽然很复杂，但FORM验证防范网络窥探并不比BASIC验证更安全，如果有必要可以在顶层安排诸如SSL或网络层安全（如IPSEC或VPN）等额外的保护。所有兼容的服务器都需要支持FORM验证。<br />
CLIENT-CERT规定服务器必须使用HTTPS（SSL之上的HTTP）并利用用户的公开密钥证书（Pulic Key Certificat）对用户进行验证。这提供了防范网络截取的很强的安全性，但只有兼容J2EE的服务器需要支持它。<br />
l realm-name<br />
此元素只在auth-method为BASIC时使用。它指出浏览器在相应对话框标题使用的、并作为Authorization头组成部分的安全域的名称。<br />
l form-login-config<br />
此元素只在auth-method为FORM时适用。它指定两个页面，分别是：包含收集用户名及口令的HTML表单的页面（利用form-login-page子元素），用来指示验证失败的页面（利用form-error-page子元素）。由form-login-page给出的HTML表单必须具有一个j_security_check的ACTION属性、一个名为j_username的用户名文本字段以及一个名为j_password的口令字段。<br />
例如，程序清单5-19指示服务器使用基于表单的验证。Web应用的顶层目录中的一个名为login.jsp的页面将收集用户名和口令，并且失败的登陆将由相同目录中名为login-error.jsp的页面报告。</p>
<p>程序清单5-19 web.xml（说明login-config的摘录）<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE web-app<br />
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />
"<a href="http://java.sun.com/dtd/web-app_2_3.dtd">http://java.sun.com/dtd/web-app_2_3.dtd</a>"&gt;</p>
<p>&lt;web-app&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;security-constraint&gt; ... &lt;/security-constraint&gt;<br />
&lt;login-config&gt;<br />
&lt;auth-method&gt; FORM &lt;/auth-method&gt;<br />
&lt;form-login-config&gt;<br />
&lt;form-login-page&gt;/login.jsp&lt;/form-login-page&gt;<br />
&lt;form-error-page&gt;/login-error.jsp&lt;/form-error-page&gt;<br />
&lt;/form-login-config&gt;<br />
&lt;/login-config&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;/web-app&gt;</p>
<p><br />
9.2 限制对Web资源的访问<br />
现在，可以指示服务器使用何种验证方法了。"了不起，"你说道，"除非我能指定一个来收到保护的 URL，否则没有多大用处。"没错。指出这些URL并说明他们应该得到何种保护正是security-constriaint元素的用途。此元素在 web.xml中应该出现在login-config的紧前面。它包含是个可能的子元素，分别是：web-resource-collection、 auth-constraint、user-data-constraint和display-name。下面各小节对它们进行介绍。<br />
l web-resource-collection<br />
此元素确定应该保护的资源。所有security-constraint元素都必须包含至少一个web-resource-collection项。此元素由一个给出任意标识名称的web-resource-name元素、一个确定应该保护的URL的url-pattern元素、一个指出此保护所适用的 HTTP命令（GET、POST等，缺省为所有方法）的http-method元素和一个提供资料的可选description元素组成。例如，下面的 Web-resource-collection项（在security-constratint元素内）指出Web应用的proprietary目录中所有文档应该受到保护。<br />
&lt;security-constraint&gt;<br />
&lt;web-resource-coolection&gt;<br />
&lt;web-resource-name&gt;Proprietary&lt;/web-resource-name&gt;<br />
&lt;url-pattern&gt;/propritary/*&lt;/url-pattern&gt;<br />
&lt;/web-resource-coolection&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;/security-constraint&gt;<br />
重要的是应该注意到，url-pattern仅适用于直接访问这些资源的客户机。特别是，它不适合于通过MVC体系结构利用 RequestDispatcher来访问的页面，或者不适合于利用类似jsp:forward的手段来访问的页面。这种不匀称如果利用得当的话很有好处。例如，servlet可利用MVC体系结构查找数据，把它放到bean中，发送请求到从bean中提取数据的JSP页面并显示它。我们希望保证决不直接访问受保护的JSP页面，而只是通过建立该页面将使用的bean的servlet来访问它。url-pattern和auth-contraint元素可通过声明不允许任何用户直接访问JSP页面来提供这种保证。但是，这种不匀称的行为可能让开发人员放松警惕，使他们偶然对应受保护的资源提供不受限制的访问。 <br />
l auth-constraint<br />
尽管web-resource-collention元素质出了哪些URL应该受到保护，但是auth-constraint元素却指出哪些用户应该具有受保护资源的访问权。此元素应该包含一个或多个标识具有访问权限的用户类别role- name元素，以及包含（可选）一个描述角色的description元素。例如，下面web.xml中的security-constraint元素部门规定只有指定为Administrator或Big Kahuna（或两者）的用户具有指定资源的访问权。<br />
&lt;security-constraint&gt;<br />
&lt;web-resource-coolection&gt; ... &lt;/web-resource-coolection&gt;<br />
&lt;auth-constraint&gt;<br />
&lt;role-name&gt;administrator&lt;/role-name&gt;<br />
&lt;role-name&gt;kahuna&lt;/role-name&gt;<br />
&lt;/auth-constraint&gt;<br />
&lt;/security-constraint&gt;<br />
重要的是认识到，到此为止，这个过程的可移植部分结束了。服务器怎样确定哪些用户处于任何角色以及它怎样存放用户的口令，完全有赖于具体的系统。<br />
例如，Tomcat使用install_dir/conf/tomcat-users.xml将用户名与角色名和口令相关联，正如下面例子中所示，它指出用户joe（口令bigshot）和jane（口令enaj）属于administrator和kahuna角色。<br />
&lt;tomcat-users&gt;<br />
&lt;user name="joe" password="bigshot" roles="administrator,kahuna" /&gt;<br />
&lt;user name="jane" password="enaj" roles="kahuna" /&gt;<br />
&lt;/tomcat-users&gt;<br />
l user-data-constraint<br />
这个可选的元素指出在访问相关资源时使用任何传输层保护。它必须包含一个transport-guarantee子元素（合法值为NONE、 INTEGRAL或CONFIDENTIAL），并且可选地包含一个description元素。transport-guarantee为NONE值将对所用的通讯协议不加限制。INTEGRAL值表示数据必须以一种防止截取它的人阅读它的方式传送。虽然原理上（并且在未来的HTTP版本中），在 INTEGRAL和CONFIDENTIAL之间可能会有差别，但在当前实践中，他们都只是简单地要求用SSL。例如，下面指示服务器只允许对相关资源做 HTTPS连接：<br />
&lt;security-constraint&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;user-data-constraint&gt;<br />
&lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;<br />
&lt;/user-data-constraint&gt;<br />
&lt;/security-constraint&gt;<br />
l display-name<br />
security-constraint的这个很少使用的子元素给予可能由GUI工具使用的安全约束项一个名称。<br />
9.3 分配角色名<br />
迄今为止，讨论已经集中到完全由容器（服务器）处理的安全问题之上了。但servlet以及JSP页面也能够处理它们自己的安全问题。<br />
例如，容器可能允许用户从bigwig或bigcheese角色访问一个显示主管人员额外紧贴的页面，但只允许bigwig用户修改此页面的参数。完成这种更细致的控制的一种常见方法是调用HttpServletRequset的isUserInRole方法，并据此修改访问。<br />
Servlet的 security-role-ref子元素提供出现在服务器专用口令文件中的安全角色名的一个别名。例如，假如编写了一个调用 request.isUserInRole（"boss"）的servlet，但后来该servlet被用在了一个其口令文件调用角色manager而不是boss的服务器中。下面的程序段使该servlet能够使用这两个名称中的任何一个。<br />
&lt;servlet&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;security-role-ref&gt;<br />
&lt;role-name&gt;boss&lt;/role-name&gt; &lt;!-- New alias --&gt;<br />
&lt;role-link&gt;manager&lt;/role-link&gt; &lt;!-- Real name --&gt;<br />
&lt;/security-role-ref&gt;<br />
&lt;/servlet&gt;<br />
也可以在web-app内利用security-role元素提供将出现在role-name元素中的所有安全角色的一个全局列表。分别地生命角色使高级IDE容易处理安全信息。</p>
<p>10 控制会话超时</p>
<p>如果某个会话在一定的时间内未被访问，服务器可把它扔掉以节约内存。可利用HttpSession的setMaxInactiveInterval方法直接设置个别会话对象的超时值。如果不采用这种方法，则缺省的超时值由具体的服务器决定。但可利用session-config和session- timeout元素来给出一个适用于所有服务器的明确的超时值。超时值的单位为分钟，因此，下面的例子设置缺省会话超时值为三个小时（180分钟）。<br />
&lt;session-config&gt;<br />
&lt;session-timeout&gt;180&lt;/session-timeout&gt;<br />
&lt;/session-config&gt;</p>
<p>11 Web应用的文档化</p>
<p>越来越多的开发环境开始提供servlet和JSP的直接支持。例子有Borland Jbuilder Enterprise Edition、Macromedia UltraDev、Allaire JRun Studio（写此文时，已被Macromedia收购）以及IBM VisuaAge for Java等。<br />
大量的web.xml元素不仅是为服务器设计的，而且还是为可视开发环境设计的。它们包括icon、display-name和discription等。<br />
可回忆一下，在web.xml内以适当地次序声明web-app子元素很重要。不过，这里只要记住icon、display-name和description是web.xml的web-app元素内的前三个合法元素即可。<br />
l icon<br />
icon元素指出GUI工具可用来代表Web应用的一个和两个图像文件。可利用small-icon元素指定一幅16 x 16的GIF或JPEG图像，用large-icon元素指定一幅32 x 32的图像。下面举一个例子： <br />
&lt;icon&gt;<br />
&lt;small-icon&gt;/images/small-book.gif&lt;/small-icon&gt;<br />
&lt;large-icon&gt;/images/tome.jpg&lt;/large-icon&gt;<br />
&lt;/icon&gt;<br />
l display-name<br />
display-name元素提供GUI工具可能会用来标记此Web应用的一个名称。下面是个例子。<br />
&lt;display-name&gt;Rare Books&lt;/display-name&gt;<br />
l description<br />
description元素提供解释性文本，如下所示：<br />
&lt;description&gt;<br />
This Web application represents the store developed for<br />
rare-books.com, an online bookstore specializing in rare<br />
and limited-edition books.<br />
&lt;/description&gt;</p>
<p>12 关联文件与MIME类型</p>
<p>服务器一般都具有一种让Web站点管理员将文件扩展名与媒体相关联的方法。例如，将会自动给予名为mom.jpg的文件一个image/jpeg的MIME 类型。但是，假如你的Web应用具有几个不寻常的文件，你希望保证它们在发送到客户机时分配为某种MIME类型。mime-mapping元素（具有 extension和mime-type子元素）可提供这种保证。例如，下面的代码指示服务器将application/x-fubar的MIME类型分配给所有以.foo结尾的文件。<br />
&lt;mime-mapping&gt;<br />
&lt;extension&gt;foo&lt;/extension&gt;<br />
&lt;mime-type&gt;application/x-fubar&lt;/mime-type&gt;<br />
&lt;/mime-mapping&gt;<br />
或许，你的Web应用希望重载（override）标准的映射。例如，下面的代码将告诉服务器在发送到客户机时指定.ps文件作为纯文本（text/plain）而不是作为PostScript（application/postscript）。<br />
&lt;mime-mapping&gt;<br />
&lt;extension&gt;ps&lt;/extension&gt;<br />
&lt;mime-type&gt;application/postscript&lt;/mime-type&gt;<br />
&lt;/mime-mapping&gt;</p>
<p><br />
13 定位TLD</p>
<p>JSP taglib元素具有一个必要的uri属性，它给出一个TLD（Tag Library Descriptor）文件相对于Web应用的根的位置。TLD文件的实际名称在发布新的标签库版本时可能会改变，但我们希望避免更改所有现有JSP页面。此外，可能还希望使用保持taglib元素的简练性的一个简短的uri。这就是部署描述符文件的taglib元素派用场的所在了。Taglib包含两个子元素：taglib-uri和taglib-location。taglib-uri元素应该与用于JSP taglib元素的uri属性的东西相匹配。Taglib-location元素给出TLD文件的实际位置。例如，假如你将文件chart-tags- 1.3beta.tld放在WebApp/WEB-INF/tlds中。现在，假如web.xml在web-app元素内包含下列内容。<br />
&lt;taglib&gt;<br />
&lt;taglib-uri&gt;/charts.tld&lt;/taglib-uri&gt;<br />
&lt;taglib-location&gt;<br />
/WEB-INF/tlds/chart-tags-1.3beta.tld<br />
&lt;/taglib-location&gt;<br />
&lt;/taglib&gt;<br />
给出这个说明后，JSP页面可通过下面的简化形式使用标签库。<br />
&lt;%@ taglib uri="/charts.tld" prefix="somePrefix" %&gt;</p>
<p>14 指定应用事件监听程序</p>
<p>应用事件监听器程序是建立或修改servlet环境或会话对象时通知的类。它们是servlet规范的版本2.3中的新内容。这里只简单地说明用来向Web应用注册一个监听程序的web.xml的用法。<br />
注册一个监听程序涉及在web.xml的web-app元素内放置一个listener元素。在listener元素内，listener-class元素列出监听程序的完整的限定类名，如下所示：<br />
&lt;listener&gt;<br />
&lt;listener-class&gt;package.ListenerClass&lt;/listener-class&gt;<br />
&lt;/listener&gt;<br />
虽然listener元素的结构很简单，但请不要忘记，必须正确地给出web-app元素内的子元素的次序。listener元素位于所有的servlet 元素之前以及所有filter-mapping元素之后。此外，因为应用生存期监听程序是serlvet规范的2.3版本中的新内容，所以必须使用 web.xml DTD的2.3版本，而不是2.2版本。<br />
例如，程序清单5-20给出一个名为ContextReporter的简单的监听程序，只要Web应用的Servlet-Context建立（如装载Web应用）或消除（如服务器关闭）时，它就在标准输出上显示一条消息。程序清单5-21给出此监听程序注册所需要的web.xml文件的一部分。</p>
<p>程序清单5-20 ContextReporterjava<br />
package moreservlets;</p>
<p>import javax.servlet.*;<br />
import java.util.*;</p>
<p>/** Simple listener that prints a report on the standard output <br />
* when the ServletContext is created or destroyed.<br />
* &lt;P&gt;<br />
* Taken from More Servlets and JavaServer Pages<br />
* from Prentice Hall and Sun Microsystems Press,<br />
* <a href="http://www.moreservlets.com/">http://www.moreservlets.com/</a>.<br />
* &#169; 2002 Marty Hall; may be freely used or adapted.<br />
*/</p>
<p>public class ContextReporter implements ServletContextListener {<br />
public void contextInitialized(ServletContextEvent event) {<br />
System.out.println("Context created on " +<br />
new Date() + ".");<br />
}</p>
<p>public void contextDestroyed(ServletContextEvent event) {<br />
System.out.println("Context destroyed on " +<br />
new Date() + ".");<br />
}<br />
}</p>
<p>程序清单5-21 web.xml（声明一个监听程序的摘录）<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE web-app<br />
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />
"<a href="http://java.sun.com/dtd/web-app_2_3.dtd">http://java.sun.com/dtd/web-app_2_3.dtd</a>"&gt;</p>
<p>&lt;web-app&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;filter-mapping&gt; &#8230; &lt;/filter-mapping&gt;<br />
&lt;listener&gt;<br />
&lt;listener-class&gt;package.ListenerClass&lt;/listener-class&gt;<br />
&lt;/listener&gt;<br />
&lt;servlet&gt; ... &lt;/servlet&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;/web-app&gt;</p>
<p>15 J2EE元素</p>
<p>本节描述用作J2EE环境组成部分的Web应用的web.xml元素。这里将提供一个简明的介绍，详细内容可以参阅<a href="http://java.sun.com/j2ee/j2ee-1_3-fr-spec.pdf">http://java.sun.com/j2ee/j2ee-1_3-fr-spec.pdf</a>的Java 2 Plantform Enterprise Edition版本1.3规范的第5章。<br />
l distributable<br />
distributable 元素指出，Web应用是以这样的方式编程的：即，支持集群的服务器可安全地在多个服务器上分布Web应用。例如，一个可分布的应用必须只使用 Serializable对象作为其HttpSession对象的属性，而且必须避免用实例变量（字段）来实现持续性。distributable元素直接出现在discription元素之后，并且不包含子元素或数据，它只是一个如下的标志。<br />
&lt;distributable /&gt;<br />
l resource-env-ref<br />
resource -env-ref元素声明一个与某个资源有关的管理对象。此元素由一个可选的description元素、一个resource-env-ref- name元素（一个相对于java:comp/env环境的JNDI名）以及一个resource-env-type元素（指定资源类型的完全限定的类），如下所示：<br />
&lt;resource-env-ref&gt;<br />
&lt;resource-env-ref-name&gt;<br />
jms/StockQueue<br />
&lt;/resource-env-ref-name&gt;<br />
&lt;resource-env-ref-type&gt;<br />
javax.jms.Queue<br />
&lt;/resource-env-ref-type&gt;<br />
&lt;/resource-env-ref&gt;<br />
l env-entry<br />
env -entry元素声明Web应用的环境项。它由一个可选的description元素、一个env-entry-name元素（一个相对于java: comp/env环境JNDI名）、一个env-entry-value元素（项值）以及一个env-entry-type元素（java.lang程序包中一个类型的完全限定类名，java.lang.Boolean、java.lang.String等）组成。下面是一个例子：<br />
&lt;env-entry&gt;<br />
&lt;env-entry-name&gt;minAmout&lt;/env-entry-name&gt;<br />
&lt;env-entry-value&gt;100.00&lt;/env-entry-value&gt;<br />
&lt;env-entry-type&gt;minAmout&lt;/env-entry-type&gt;<br />
&lt;/env-entry&gt;<br />
l ejb-ref<br />
ejb -ref元素声明对一个EJB的主目录的应用。它由一个可选的description元素、一个ejb-ref-name元素（相对于java: comp/env的EJB应用）、一个ejb-ref-type元素（bean的类型，Entity或Session）、一个home元素（bean的主目录接口的完全限定名）、一个remote元素（bean的远程接口的完全限定名）以及一个可选的ejb-link元素（当前bean链接的另一个 bean的名称）组成。<br />
l ejb-local-ref<br />
ejb-local-ref元素声明一个EJB的本地主目录的引用。除了用local-home代替home外，此元素具有与ejb-ref元素相同的属性并以相同的方式使用</p>
<img src ="http://www.blogjava.net/zilong/aggbug/191070.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2008-04-06 17:42 <a href="http://www.blogjava.net/zilong/archive/2008/04/06/191070.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> web.xml配置的详细说明 2</title><link>http://www.blogjava.net/zilong/archive/2008/04/06/191068.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Sun, 06 Apr 2008 09:39:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2008/04/06/191068.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/191068.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2008/04/06/191068.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/191068.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/191068.html</trackback:ping><description><![CDATA[<p>&nbsp;<strong>web.xml配置的详细说明 2<br />
</strong>4 禁止激活器servlet<br />
对servlet或JSP页面建立定制URL的一个原因是，这样做可以注册从 init（servlet）或jspInit（JSP页面）方法中读取得初始化参数。但是，初始化参数只在是利用定制URL模式或注册名访问 servlet或JSP页面时可以使用，用缺省URL <a href="http://host/webAppPrefix/servlet/ServletName">http://host/webAppPrefix/servlet/ServletName</a> 访问时不能使用。因此，你可能会希望关闭缺省URL，这样就不会有人意外地调用初始化servlet了。这个过程有时称为禁止激活器servlet，因为多数服务器具有一个用缺省的servlet URL注册的标准servlet，并激活缺省的URL应用的实际servlet。<br />
有两种禁止此缺省URL的主要方法：<br />
l 在每个Web应用中重新映射/servlet/模式。<br />
l 全局关闭激活器servlet。<br />
重要的是应该注意到，虽然重新映射每个Web应用中的/servlet/模式比彻底禁止激活servlet所做的工作更多，但重新映射可以用一种完全可移植的方式来完成。相反，全局禁止激活器servlet完全是针对具体机器的，事实上有的服务器（如ServletExec）没有这样的选择。下面的讨论对每个Web应用重新映射/servlet/ URL模式的策略。后面提供在Tomcat中全局禁止激活器servlet的详细内容。<br />
4.1 重新映射/servlet/URL模式<br />
在一个特定的Web应用中禁止以<a href="http://host/webAppPrefix/servlet/">http://host/webAppPrefix/servlet/</a> 开始的URL的处理非常简单。所需做的事情就是建立一个错误消息servlet，并使用前一节讨论的url-pattern元素将所有匹配请求转向该 servlet。只要简单地使用：<br />
&lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br />
作为servlet-mapping元素中的模式即可。<br />
例如，程序清单5-5给出了将SorryServlet servlet（程序清单5-6）与所有以<a href="http://host/webAppPrefix/servlet/">http://host/webAppPrefix/servlet/</a> 开头的URL相关联的部署描述符文件的一部分。<br />
程序清单5-5 web.xml（说明JSP页命名的摘录）<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE web-app<br />
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />
"<a href="http://java.sun.com/dtd/web-app_2_3.dtd">http://java.sun.com/dtd/web-app_2_3.dtd</a>"&gt;</p>
<p>&lt;web-app&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;Sorry&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;moreservlets.SorryServlet&lt;/servlet-class&gt;<br />
&lt;/servlet&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet-mapping&gt;<br />
&lt;servlet-name&gt; Sorry &lt;/servlet-name&gt;<br />
&lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;/web-app&gt;</p>
<p>程序清单5-6 SorryServlet.java<br />
package moreservlets;</p>
<p>import java.io.*;<br />
import javax.servlet.*;<br />
import javax.servlet.http.*;</p>
<p>/** Simple servlet used to give error messages to<br />
* users who try to access default servlet URLs<br />
* (i.e., <a href="http://host/webAppPrefix/servlet/ServletName">http://host/webAppPrefix/servlet/ServletName</a>)<br />
* in Web applications that have disabled this<br />
* behavior.<br />
* &lt;P&gt;<br />
* Taken from More Servlets and JavaServer Pages<br />
* from Prentice Hall and Sun Microsystems Press,<br />
* <a href="http://www.moreservlets.com/">http://www.moreservlets.com/</a>.<br />
* &#169; 2002 Marty Hall; may be freely used or adapted.<br />
*/</p>
<p>public class SorryServlet extends HttpServlet {<br />
public void doGet(HttpServletRequest request,<br />
HttpServletResponse response)<br />
throws ServletException, IOException {<br />
response.setContentType("text/html");<br />
PrintWriter out = response.getWriter();<br />
String title = "Invoker Servlet Disabled.";<br />
out.println(ServletUtilities.headWithTitle(title) +<br />
"&lt;BODY BGCOLOR=\"#FDF5E6\"&gt;\n" +<br />
"&lt;H2&gt;" + title + "&lt;/H2&gt;\n" +<br />
"Sorry, access to servlets by means of\n" +<br />
"URLs that begin with\n" +<br />
"<a href="http://host/webAppPrefix/servlet//n">http://host/webAppPrefix/servlet/\n</a>" +<br />
"has been disabled.\n" + <br />
"&lt;/BODY&gt;&lt;/HTML&gt;");<br />
}</p>
<p>public void doPost(HttpServletRequest request,<br />
HttpServletResponse response)<br />
throws ServletException, IOException {<br />
doGet(request, response);<br />
}<br />
}</p>
<p><br />
4.2 全局禁止激活器：Tomcat<br />
Tomcat 4中用来关闭缺省URL的方法与Tomcat 3中所用的很不相同。下面介绍这两种方法：<br />
1．禁止激活器： Tomcat 4<br />
Tomcat 4用与前面相同的方法关闭激活器servlet，即利用web.xml中的url-mapping元素进行关闭。不同之处在于Tomcat使用了放在 install_dir/conf中的一个服务器专用的全局web.xml文件，而前面使用的是存放在每个Web应用的WEB-INF目录中的标准 web.xml文件。<br />
因此，为了在Tomcat 4中关闭激活器servlet，只需在install_dir/conf/web.xml中简单地注释出/servlet/* URL映射项即可，如下所示：<br />
&lt;!-- <br />
&lt;servlet-mapping&gt;<br />
&lt;servlet-name&gt;invoker&lt;/servlet-name&gt;<br />
&lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;<br />
--&gt;<br />
再次提醒，应该注意这个项是位于存放在install_dir/conf的Tomcat专用的web.xml文件中的，此文件不是存放在每个Web应用的WEB-INF目录中的标准web.xml。<br />
2．禁止激活器：Tomcat3<br />
在Apache Tomcat的版本3中，通过在install_dir/conf/server.xml中注释出InvokerInterceptor项全局禁止缺省 servlet URL。例如，下面是禁止使用缺省servlet URL的server.xml文件的一部分。<br />
&lt;!-- <br />
&lt;RequsetInterceptor <br />
className="org.apache.tomcat.request.InvokerInterceptor"<br />
debug="0" prefix="/servlet/" /&gt;<br />
--&gt;</p>
<p>5 初始化和预装载servlet与JSP页面<br />
这里讨论控制servlet和JSP页面的启动行为的方法。特别是，说明了怎样分配初始化参数以及怎样更改服务器生存期中装载servlet和JSP页面的时刻。<br />
5.1 分配servlet初始化参数<br />
利用init-param元素向servlet提供初始化参数，init-param元素具有param-name和param-value子元素。例如，在下面的例子中，如果initServlet servlet是利用它的注册名（InitTest）访问的，它将能够从其方法中调用getServletConfig(). getInitParameter("param1")获得"Value 1"，调用getServletConfig().getInitParameter("param2")获得"2"。<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;InitTest&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;moreservlets.InitServlet&lt;/servlet-class&gt;<br />
&lt;init-param&gt;<br />
&lt;param-name&gt;param1&lt;/param-name&gt;<br />
&lt;param-value&gt;value1&lt;/param-value&gt;<br />
&lt;/init-param&gt;<br />
&lt;init-param&gt;<br />
&lt;param-name&gt;param2&lt;/param-name&gt;<br />
&lt;param-value&gt;2&lt;/param-value&gt;<br />
&lt;/init-param&gt;<br />
&lt;/servlet&gt;<br />
在涉及初始化参数时，有几点需要注意：<br />
l 返回值。GetInitParameter的返回值总是一个String。因此，在前一个例子中，可对param2使用Integer.parseInt获得一个int。<br />
l JSP中的初始化。JSP页面使用jspInit而不是init。JSP页面还需要使用jsp-file元素代替servlet-class。<br />
l 缺省URL。初始化参数只在通过它们的注册名或与它们注册名相关的定制URL模式访问Servlet时可以使用。因此，在这个例子中，param1和 param2初始化参数将能够在使用URL <a href="http://host/webAppPrefix/servlet/InitTest">http://host/webAppPrefix/servlet/InitTest</a> 时可用，但在使用URL <a href="http://host/webAppPrefix/servlet/myPackage.InitServlet">http://host/webAppPrefix/servlet/myPackage.InitServlet</a> 时不能使用。<br />
例如，程序清单5-7给出一个名为InitServlet的简单servlet，它使用init方法设置firstName和emailAddress字段。程序清单5-8给出分配名称InitTest给servlet的web.xml文件。<br />
程序清单5-7 InitServlet.java<br />
package moreservlets;</p>
<p>import java.io.*;<br />
import javax.servlet.*;<br />
import javax.servlet.http.*;</p>
<p>/** Simple servlet used to illustrate servlet<br />
* initialization parameters.<br />
* &lt;P&gt;<br />
* Taken from More Servlets and JavaServer Pages<br />
* from Prentice Hall and Sun Microsystems Press,<br />
* <a href="http://www.moreservlets.com/">http://www.moreservlets.com/</a>.<br />
* &#169; 2002 Marty Hall; may be freely used or adapted.<br />
*/</p>
<p>public class InitServlet extends HttpServlet {<br />
private String firstName, emailAddress;</p>
<p>public void init() {<br />
ServletConfig config = getServletConfig();<br />
firstName = config.getInitParameter("firstName");<br />
emailAddress = config.getInitParameter("emailAddress");<br />
}</p>
<p>public void doGet(HttpServletRequest request,<br />
HttpServletResponse response)<br />
throws ServletException, IOException {<br />
response.setContentType("text/html");<br />
PrintWriter out = response.getWriter();<br />
String uri = request.getRequestURI();<br />
out.println(ServletUtilities.headWithTitle("Init Servlet") +<br />
"&lt;BODY BGCOLOR=\"#FDF5E6\"&gt;\n" +<br />
"&lt;H2&gt;Init Parameters:&lt;/H2&gt;\n" +<br />
"&lt;UL&gt;\n" +<br />
"&lt;LI&gt;First name: " + firstName + "\n" +<br />
"&lt;LI&gt;Email address: " + emailAddress + "\n" +<br />
"&lt;/UL&gt;\n" + <br />
"&lt;/BODY&gt;&lt;/HTML&gt;");<br />
}<br />
}</p>
<p><br />
程序清单5-8 web.xml（说明初始化参数的摘录）<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE web-app<br />
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />
"<a href="http://java.sun.com/dtd/web-app_2_3.dtd">http://java.sun.com/dtd/web-app_2_3.dtd</a>"&gt;</p>
<p>&lt;web-app&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;InitTest&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;moreservlets.InitServlet&lt;/servlet-class&gt;<br />
&lt;init-param&gt;<br />
&lt;param-name&gt;firstName&lt;/param-name&gt;<br />
&lt;param-value&gt;Larry&lt;/param-value&gt;<br />
&lt;/init-param&gt;<br />
&lt;init-param&gt;<br />
&lt;param-name&gt;emailAddress&lt;/param-name&gt;<br />
&lt;param-value&gt;Ellison@Microsoft.com&lt;/param-value&gt;<br />
&lt;/init-param&gt;<br />
&lt;/servlet&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;/web-app&gt;</p>
<p>5.2 分配JSP初始化参数<br />
给JSP页面提供初始化参数在三个方面不同于给servlet提供初始化参数。<br />
1）使用jsp-file而不是servlet-class。因此，WEB-INF/web.xml文件的servlet元素如下所示：<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />
&lt;jsp-file&gt;/RealPage.jsp&lt;/jsp-file&gt;<br />
&lt;init-param&gt;<br />
&lt;param-name&gt;...&lt;/param-name&gt;<br />
&lt;param-value&gt;...&lt;/param-value&gt;<br />
&lt;/init-param&gt;<br />
...<br />
&lt;/servlet&gt;<br />
2) 几乎总是分配一个明确的URL模式。对servlet，一般相应地使用以<a href="http://host/webAppPrefix/servlet/">http://host/webAppPrefix/servlet/</a> 开始的缺省URL。只需记住，使用注册名而不是原名称即可。这对于JSP页面在技术上也是合法的。例如，在上面给出的例子中，可用URL <a href="http://host/webAppPrefix/servlet/PageName">http://host/webAppPrefix/servlet/PageName</a> 访问RealPage.jsp的对初始化参数具有访问权的版本。但在用于JSP页面时，许多用户似乎不喜欢应用常规的servlet的URL。此外，如果 JSP页面位于服务器为其提供了目录清单的目录中（如，一个既没有index.html也没有index.jsp文件的目录），则用户可能会连接到此 JSP页面，单击它，从而意外地激活未初始化的页面。因此，好的办法是使用url-pattern（5.3节）将JSP页面的原URL与注册的 servlet名相关联。这样，客户机可使用JSP页面的普通名称，但仍然激活定制的版本。例如，给定来自项目1的servlet定义，可使用下面的 servlet-mapping定义：<br />
&lt;servlet-mapping&gt;<br />
&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />
&lt;url-pattern&gt;/RealPage.jsp&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;<br />
3）JSP页使用jspInit而不是init。自动从JSP页面建立的servlet或许已经使用了inti方法。因此，使用JSP声明提供一个init方法是不合法的，必须制定jspInit方法。<br />
为了说明初始化JSP页面的过程，程序清单5-9给出了一个名为InitPage.jsp的JSP页面，它包含一个jspInit方法且放置于 deployDemo Web应用层次结构的顶层。一般，<a href="http://host/deployDemo/InitPage.jsp">http://host/deployDemo/InitPage.jsp</a> 形式的URL将激活此页面的不具有初始化参数访问权的版本，从而将对firstName和emailAddress变量显示null。但是， web.xml文件（程序清单5-10）分配了一个注册名，然后将该注册名与URL模式/InitPage.jsp相关联。</p>
<p>程序清单5-9 InitPage.jsp<br />
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />
&lt;HTML&gt;<br />
&lt;HEAD&gt;&lt;TITLE&gt;JSP Init Test&lt;/TITLE&gt;&lt;/HEAD&gt;<br />
&lt;BODY BGCOLOR="#FDF5E6"&gt;<br />
&lt;H2&gt;Init Parameters:&lt;/H2&gt;<br />
&lt;UL&gt;<br />
&lt;LI&gt;First name: &lt;%= firstName %&gt;<br />
&lt;LI&gt;Email address: &lt;%= emailAddress %&gt;<br />
&lt;/UL&gt;<br />
&lt;/BODY&gt;&lt;/HTML&gt;<br />
&lt;%!<br />
private String firstName, emailAddress;</p>
<p>public void jspInit() {<br />
ServletConfig config = getServletConfig();<br />
firstName = config.getInitParameter("firstName");<br />
emailAddress = config.getInitParameter("emailAddress");<br />
}<br />
%&gt;</p>
<p><br />
程序清单5-10 web.xml（说明JSP页面的init参数的摘录）<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE web-app<br />
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />
"<a href="http://java.sun.com/dtd/web-app_2_3.dtd">http://java.sun.com/dtd/web-app_2_3.dtd</a>"&gt;</p>
<p>&lt;web-app&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;InitPage&lt;/servlet-name&gt;<br />
&lt;jsp-file&gt;/InitPage.jsp&lt;/jsp-file&gt;<br />
&lt;init-param&gt;<br />
&lt;param-name&gt;firstName&lt;/param-name&gt;<br />
&lt;param-value&gt;Bill&lt;/param-value&gt;<br />
&lt;/init-param&gt;<br />
&lt;init-param&gt;<br />
&lt;param-name&gt;emailAddress&lt;/param-name&gt;<br />
&lt;param-value&gt;gates@oracle.com&lt;/param-value&gt;<br />
&lt;/init-param&gt;<br />
&lt;/servlet&gt;<br />
&lt;!-- ... --&gt; <br />
&lt;servlet-mapping&gt;<br />
&lt;servlet-name&gt; InitPage&lt;/servlet-name&gt;<br />
&lt;url-pattern&gt;/InitPage.jsp&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;/web-app&gt;</p>
<p><br />
5.3 提供应用范围内的初始化参数<br />
一般，对单个地servlet或JSP页面分配初始化参数。指定的servlet或JSP页面利用ServletConfig的getInitParameter方法读取这些参数。但是，在某些情形下，希望提供可由任意servlet或JSP页面借助ServletContext的getInitParameter方法读取的系统范围内的初始化参数。<br />
可利用context-param元素声明这些系统范围内的初始化值。context-param元素应该包含param-name、param-value以及可选的description子元素，如下所示：<br />
&lt;context-param&gt;<br />
&lt;param-name&gt;support-email&lt;/param-name&gt;<br />
&lt;param-value&gt;blackhole@mycompany.com&lt;/param-value&gt;<br />
&lt;/context-param&gt;<br />
可回忆一下，为了保证可移植性，web.xml内的元素必须以正确的次序声明。但这里应该注意，context-param元素必须出现任意与文档有关的元素（icon、display-name或description）之后及filter、filter-mapping、listener或 servlet元素之前。<br />
5.4 在服务器启动时装载servlet<br />
假如servlet或JSP页面有一个要花很长时间执行的init （servlet）或jspInit（JSP）方法。例如，假如init或jspInit方法从某个数据库或ResourceBundle查找产量。这种情况下，在第一个客户机请求时装载servlet的缺省行为将对第一个客户机产生较长时间的延迟。因此，可利用servlet的load-on- startup元素规定服务器在第一次启动时装载servlet。下面是一个例子。<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt; &#8230; &lt;/servlet-name&gt;<br />
&lt;servlet-class&gt; &#8230; &lt;/servlet-class&gt; &lt;!-- Or jsp-file --&gt;<br />
&lt;load-on-startup/&gt;<br />
&lt;/servlet&gt;<br />
可以为此元素体提供一个整数而不是使用一个空的load-on-startup。想法是服务器应该在装载较大数目的servlet或JSP页面之前装载较少数目的servlet或JSP页面。例如，下面的servlet项（放置在Web应用的WEB-INF目录下的web.xml文件中的web-app元素内）将指示服务器首先装载和初始化SearchServlet，然后装载和初始化由位于Web应用的result目录中的index.jsp文件产生的 servlet。<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;Search&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;myPackage.SearchServlet&lt;/servlet-class&gt; &lt;!-- Or jsp-file --&gt;<br />
&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br />
&lt;/servlet&gt;<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;Results&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;/results/index.jsp&lt;/servlet-class&gt; &lt;!-- Or jsp-file --&gt;<br />
&lt;load-on-startup&gt;2&lt;/load-on-startup&gt;<br />
&lt;/servlet&gt;</p>
<p>6 声明过滤器</p>
<p>servlet版本2.3引入了过滤器的概念。虽然所有支持servlet API版本2.3的服务器都支持过滤器，但为了使用与过滤器有关的元素，必须在web.xml中使用版本2.3的DTD。<br />
过滤器可截取和修改进入一个servlet或JSP页面的请求或从一个servlet或JSP页面发出的相应。在执行一个servlet或JSP页面之前，必须执行第一个相关的过滤器的doFilter方法。在该过滤器对其FilterChain对象调用doFilter时，执行链中的下一个过滤器。如果没有其他过滤器，servlet或JSP页面被执行。过滤器具有对到来的ServletRequest对象的全部访问权，因此，它们可以查看客户机名、查找到来的cookie等。为了访问servlet或JSP页面的输出，过滤器可将响应对象包裹在一个替身对象（stand-in object）中，比方说把输出累加到一个缓冲区。在调用FilterChain对象的doFilter方法之后，过滤器可检查缓冲区，如有必要，就对它进行修改，然后传送到客户机。<br />
例如，程序清单5-11帝国难以了一个简单的过滤器，只要访问相关的servlet或JSP页面，它就截取请求并在标准输出上打印一个报告（开发过程中在桌面系统上运行时，大多数服务器都可以使用这个过滤器）。</p>
<p>程序清单5-11 ReportFilter.java<br />
package moreservlets;</p>
<p>import java.io.*;<br />
import javax.servlet.*;<br />
import javax.servlet.http.*;<br />
import java.util.*;</p>
<p>/** Simple filter that prints a report on the standard output <br />
* whenever the associated servlet or JSP page is accessed.<br />
* &lt;P&gt;<br />
* Taken from More Servlets and JavaServer Pages<br />
* from Prentice Hall and Sun Microsystems Press,<br />
* <a href="http://www.moreservlets.com/">http://www.moreservlets.com/</a>.<br />
* &#169; 2002 Marty Hall; may be freely used or adapted.<br />
*/</p>
<p>public class ReportFilter implements Filter {<br />
public void doFilter(ServletRequest request,<br />
ServletResponse response,<br />
FilterChain chain)<br />
throws ServletException, IOException {<br />
HttpServletRequest req = (HttpServletRequest)request;<br />
System.out.println(req.getRemoteHost() +<br />
" tried to access " +<br />
req.getRequestURL() +<br />
" on " + new Date() + ".");<br />
chain.doFilter(request,response);<br />
}</p>
<p>public void init(FilterConfig config)<br />
throws ServletException {<br />
}</p>
<p>public void destroy() {}<br />
}</p>
<p>一旦建立了一个过滤器，可以在web.xml中利用filter元素以及filter-name（任意名称）、file-class（完全限定的类名）和（可选的）init-params子元素声明它。请注意，元素在web.xml的web-app元素中出现的次序不是任意的；允许服务器（但不是必需的）强制所需的次序，并且实际中有些服务器也是这样做的。但这里要注意，所有filter元素必须出现在任意filter-mapping元素之前， filter-mapping元素又必须出现在所有servlet或servlet-mapping元素之前。<br />
例如，给定上述的ReportFilter类，可在web.xml中作出下面的filter声明。它把名称Reporter与实际的类ReportFilter（位于moreservlets程序包中）相关联。<br />
&lt;filter&gt;<br />
&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />
&lt;filter-class&gt;moresevlets.ReportFilter&lt;/filter-class&gt;<br />
&lt;/filter&gt;<br />
一旦命名了一个过滤器，可利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。关于此项工作有两种选择。<br />
首先，可使用filter-name和servlet-name子元素把此过滤器与一个特定的servlet名（此servlet名必须稍后在相同的 web.xml文件中使用servlet元素声明）关联。例如，下面的程序片断指示系统只要利用一个定制的URL访问名为SomeServletName 的servlet或JSP页面，就运行名为Reporter的过滤器。<br />
&lt;filter-mapping&gt;<br />
&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />
&lt;servlet-name&gt;SomeServletName&lt;/servlet-name&gt;<br />
&lt;/filter-mapping&gt;<br />
其次，可利用filter-name和url-pattern子元素将过滤器与一组servlet、JSP页面或静态内容相关联。例如，相面的程序片段指示系统只要访问Web应用中的任意URL，就运行名为Reporter的过滤器。<br />
&lt;filter-mapping&gt;<br />
&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br />
&lt;/filter-mapping&gt;<br />
例如，程序清单5-12给出了将ReportFilter过滤器与名为PageName的servlet相关联的web.xml文件的一部分。名字 PageName依次又与一个名为TestPage.jsp的JSP页面以及以模式http: //host/webAppPrefix/UrlTest2/ 开头的URL相关联。TestPage.jsp的源代码已经JSP页面命名的谈论在前面的3节"分配名称和定制的URL"中给出。事实上，程序清单5- 12中的servlet和servlet-name项从该节原封不动地拿过来的。给定这些web.xml项，可看到下面的标准输出形式的调试报告（换行是为了容易阅读）。<br />
audit.irs.gov tried to access <br />
<a href="http://mycompany.com/deployDemo/UrlTest2/business/tax-plan.html">http://mycompany.com/deployDemo/UrlTest2/business/tax-plan.html</a><br />
on Tue Dec 25 13:12:29 EDT 2001.</p>
<p>程序清单5-12 Web.xml（说明filter用法的摘录）<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE web-app<br />
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />
"<a href="http://java.sun.com/dtd/web-app_2_3.dtd">http://java.sun.com/dtd/web-app_2_3.dtd</a>"&gt;</p>
<p>&lt;web-app&gt;<br />
&lt;filter&gt;<br />
&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />
&lt;filter-class&gt;moresevlets.ReportFilter&lt;/filter-class&gt;<br />
&lt;/filter&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;filter-mapping&gt;<br />
&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />
&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />
&lt;/filter-mapping&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />
&lt;jsp-file&gt;/RealPage.jsp&lt;/jsp-file&gt;<br />
&lt;/servlet&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet-mapping&gt;<br />
&lt;servlet-name&gt; PageName &lt;/servlet-name&gt;<br />
&lt;url-pattern&gt;/UrlTest2/*&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;/web-app&gt;</p>
<p><br />
</p>
<img src ="http://www.blogjava.net/zilong/aggbug/191068.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2008-04-06 17:39 <a href="http://www.blogjava.net/zilong/archive/2008/04/06/191068.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> web.xml配置的详细说明1</title><link>http://www.blogjava.net/zilong/archive/2008/04/06/191067.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Sun, 06 Apr 2008 09:36:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2008/04/06/191067.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/191067.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2008/04/06/191067.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/191067.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/191067.html</trackback:ping><description><![CDATA[<p align="center"><strong>&nbsp;web.xml配置的详细说明1</strong><br />
</p>
<p>1 定义头和根元素<br />
部署描述符文件就像所有XML文件一样，必须以一个XML头开始。这个头声明可以使用的XML版本并给出文件的字符编码。<br />
DOCYTPE声明必须立即出现在此头之后。这个声明告诉服务器适用的servlet规范的版本（如2.2或2.3）并指定管理此文件其余部分内容的语法的DTD(Document Type Definition，文档类型定义)。<br />
所有部署描述符文件的顶层（根）元素为web-app。请注意，XML元素不像HTML，他们是大小写敏感的。因此，web-App和WEB-APP都是不合法的，web-app必须用小写。<br />
2 部署描述符文件内的元素次序<br />
XML 元素不仅是大小写敏感的，而且它们还对出现在其他元素中的次序敏感。例如，XML头必须是文件中的第一项，DOCTYPE声明必须是第二项，而web- app元素必须是第三项。在web-app元素内，元素的次序也很重要。服务器不一定强制要求这种次序，但它们允许（实际上有些服务器就是这样做的）完全拒绝执行含有次序不正确的元素的Web应用。这表示使用非标准元素次序的web.xml文件是不可移植的。<br />
下面的列表给出了所有可直接出现在web-app元素内的合法元素所必需的次序。例如，此列表说明servlet元素必须出现在所有servlet-mapping元素之前。请注意，所有这些元素都是可选的。因此，可以省略掉某一元素，但不能把它放于不正确的位置。<br />
l icon icon元素指出IDE和GUI工具用来表示Web应用的一个和两个图像文件的位置。<br />
l display-name display-name元素提供GUI工具可能会用来标记这个特定的Web应用的一个名称。<br />
l description description元素给出与此有关的说明性文本。<br />
l context-param context-param元素声明应用范围内的初始化参数。<br />
l filter 过滤器元素将一个名字与一个实现javax.servlet.Filter接口的类相关联。<br />
l filter-mapping 一旦命名了一个过滤器，就要利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。<br />
l listener servlet API的版本2.3增加了对事件监听程序的支持，事件监听程序在建立、修改和删除会话或servlet环境时得到通知。Listener元素指出事件监听程序类。<br />
l servlet 在向servlet或JSP页面制定初始化参数或定制URL时，必须首先命名servlet或JSP页面。Servlet元素就是用来完成此项任务的。<br />
l servlet-mapping 服务器一般为servlet提供一个缺省的URL：<a href="http://host/webAppPrefix/servlet/ServletName">http://host/webAppPrefix/servlet/ServletName</a>。但是，常常会更改这个URL，以便servlet可以访问初始化参数或更容易地处理相对URL。在更改缺省URL时，使用servlet-mapping元素。<br />
l session-config 如果某个会话在一定时间内未被访问，服务器可以抛弃它以节省内存。可通过使用HttpSession的setMaxInactiveInterval方法明确设置单个会话对象的超时值，或者可利用session-config元素制定缺省超时值。<br />
l mime-mapping 如果Web应用具有想到特殊的文件，希望能保证给他们分配特定的MIME类型，则mime-mapping元素提供这种保证。<br />
l welcom-file-list welcome-file-list元素指示服务器在收到引用一个目录名而不是文件名的URL时，使用哪个文件。<br />
l error-page error-page元素使得在返回特定HTTP状态代码时，或者特定类型的异常被抛出时，能够制定将要显示的页面。<br />
l taglib taglib元素对标记库描述符文件（Tag Libraryu Descriptor file）指定别名。此功能使你能够更改TLD文件的位置，而不用编辑使用这些文件的JSP页面。<br />
l resource-env-ref resource-env-ref元素声明与资源相关的一个管理对象。<br />
l resource-ref resource-ref元素声明一个资源工厂使用的外部资源。<br />
l security-constraint security-constraint元素制定应该保护的URL。它与login-config元素联合使用<br />
l login-config 用login-config元素来指定服务器应该怎样给试图访问受保护页面的用户授权。它与sercurity-constraint元素联合使用。<br />
l security-role security-role元素给出安全角色的一个列表，这些角色将出现在servlet元素内的security-role-ref元素的role-name子元素中。分别地声明角色可使高级IDE处理安全信息更为容易。<br />
l env-entry env-entry元素声明Web应用的环境项。<br />
l ejb-ref ejb-ref元素声明一个EJB的主目录的引用。<br />
l ejb-local-ref ejb-local-ref元素声明一个EJB的本地主目录的应用。<br />
3 分配名称和定制的UL<br />
在web.xml中完成的一个最常见的任务是对servlet或JSP页面给出名称和定制的URL。用servlet元素分配名称，使用servlet-mapping元素将定制的URL与刚分配的名称相关联。<br />
3.1 分配名称<br />
为了提供初始化参数，对servlet或JSP页面定义一个定制URL或分配一个安全角色，必须首先给servlet或JSP页面一个名称。可通过 servlet元素分配一个名称。最常见的格式包括servlet-name和servlet-class子元素（在web-app元素内），如下所示：<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;moreservlets.TestServlet&lt;/servlet-class&gt;<br />
&lt;/servlet&gt; <br />
这表示位于WEB-INF/classes/moreservlets/TestServlet的servlet已经得到了注册名Test。给 servlet一个名称具有两个主要的含义。首先，初始化参数、定制的URL模式以及其他定制通过此注册名而不是类名引用此servlet。其次,可在 URL而不是类名中使用此名称。因此，利用刚才给出的定义，URL <a href="http://host/webAppPrefix/servlet/Test">http://host/webAppPrefix/servlet/Test</a> 可用于 <a href="http://host/webAppPrefix/servlet/moreservlets.TestServlet">http://host/webAppPrefix/servlet/moreservlets.TestServlet</a> 的场所。<br />
请记住：XML元素不仅是大小写敏感的，而且定义它们的次序也很重要。例如，web-app元素内所有servlet元素必须位于所有servlet- mapping元素（下一小节介绍）之前，而且还要位于5.6节和5.11节讨论的与过滤器或文档相关的元素（如果有的话）之前。类似地，servlet 的servlet-name子元素也必须出现在servlet-class之前。5.2节"部署描述符文件内的元素次序"将详细介绍这种必需的次序。<br />
例如，程序清单5-1给出了一个名为TestServlet的简单servlet，它驻留在moreservlets程序包中。因为此servlet是扎根在一个名为deployDemo的目录中的Web应用的组成部分，所以TestServlet.class放在deployDemo/WEB- INF/classes/moreservlets中。程序清单5-2给出将放置在deployDemo/WEB-INF/内的web.xml文件的一部分。此web.xml文件使用servlet-name和servlet-class元素将名称Test与TestServlet.class相关联。图 5-1和图5-2分别显示利用缺省URL和注册名调用TestServlet时的结果。<br />
程序清单5-1 TestServlet.java<br />
package moreservlets;</p>
<p>import java.io.*;<br />
import javax.servlet.*;<br />
import javax.servlet.http.*;</p>
<p>/** Simple servlet used to illustrate servlet naming<br />
* and custom URLs.<br />
* &lt;P&gt;<br />
* Taken from More Servlets and JavaServer Pages<br />
* from Prentice Hall and Sun Microsystems Press,<br />
* <a href="http://www.moreservlets.com/">http://www.moreservlets.com/</a>.<br />
* &#169; 2002 Marty Hall; may be freely used or adapted.<br />
*/</p>
<p>public class TestServlet extends HttpServlet {<br />
public void doGet(HttpServletRequest request,<br />
HttpServletResponse response)<br />
throws ServletException, IOException {<br />
response.setContentType("text/html");<br />
PrintWriter out = response.getWriter();<br />
String uri = request.getRequestURI();<br />
out.println(ServletUtilities.headWithTitle("Test Servlet") +<br />
"&lt;BODY BGCOLOR=\"#FDF5E6\"&gt;\n" +<br />
"&lt;H2&gt;URI: " + uri + "&lt;/H2&gt;\n" +<br />
"&lt;/BODY&gt;&lt;/HTML&gt;");<br />
}<br />
}</p>
<p>程序清单5-2 web.xml（说明servlet名称的摘录）<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE web-app<br />
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />
"<a href="http://java.sun.com/dtd/web-app_2_3.dtd">http://java.sun.com/dtd/web-app_2_3.dtd</a>"&gt;</p>
<p>&lt;web-app&gt;<br />
&lt;!-- &#8230; --&gt;<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;moreservlets.TestServlet&lt;/servlet-class&gt;<br />
&lt;/servlet&gt;<br />
&lt;!-- &#8230; --&gt;<br />
&lt;/web-app&gt;</p>
<p>3.2 定义定制的URL<br />
大多数服务器具有一个缺省的serlvet URL：<br />
<a href="http://host/webAppPrefix/servlet/packageName.ServletName">http://host/webAppPrefix/servlet/packageName.ServletName</a>。虽然在开发中使用这个URL很方便，但是我们常常会希望另一个URL用于部署。例如，可能会需要一个出现在Web应用顶层的URL（如，http: //host/webAppPrefix/Anyname），并且在此URL中没有servlet项。位于顶层的URL简化了相对URL的使用。此外，对许多开发人员来说，顶层URL看上去比更长更麻烦的缺省URL更简短。<br />
事实上，有时需要使用定制的URL。比如，你可能想关闭缺省URL映射，以便更好地强制实施安全限制或防止用户意外地访问无初始化参数的servlet。如果你禁止了缺省的URL，那么你怎样访问servlet呢？这时只有使用定制的URL了。<br />
为了分配一个定制的URL，可使用servlet-mapping元素及其servlet-name和url-pattern子元素。Servlet- name元素提供了一个任意名称，可利用此名称引用相应的servlet；url-pattern描述了相对于Web应用的根目录的URL。url- pattern元素的值必须以斜杠（/）起始。<br />
下面给出一个简单的web.xml摘录，它允许使用URL <a href="http://host/webAppPrefix/UrlTest">http://host/webAppPrefix/UrlTest</a>而不是<a href="http://host/webAppPrefix/servlet/Test">http://host/webAppPrefix/servlet/Test</a>或<br />
http: //host/webAppPrefix/servlet/moreservlets.TestServlet。请注意，仍然需要XML头、 DOCTYPE声明以及web-app封闭元素。此外，可回忆一下，XML元素出现地次序不是随意的。特别是，需要把所有servlet元素放在所有 servlet-mapping元素之前。<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;moreservlets.TestServlet&lt;/servlet-class&gt;<br />
&lt;/servlet&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet-mapping&gt;<br />
&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />
&lt;url-pattern&gt;/UrlTest&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;<br />
URL模式还可以包含通配符。例如，下面的小程序指示服务器发送所有以Web应用的URL前缀开始，以..asp结束的请求到名为BashMS的servlet。<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;BashMS&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;msUtils.ASPTranslator&lt;/servlet-class&gt;<br />
&lt;/servlet&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet-mapping&gt;<br />
&lt;servlet-name&gt;BashMS&lt;/servlet-name&gt;<br />
&lt;url-pattern&gt;/*.asp&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;<br />
3.3 命名JSP页面<br />
因为JSP页面要转换成sevlet，自然希望就像命名servlet一样命名JSP页面。毕竟，JSP页面可能会从初始化参数、安全设置或定制的URL中受益，正如普通的serlvet那样。虽然JSP页面的后台实际上是servlet这句话是正确的，但存在一个关键的猜疑：即，你不知道JSP页面的实际类名（因为系统自己挑选这个名字）。因此，为了命名JSP页面，可将jsp-file元素替换为servlet-calss元素，如下所示：<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />
&lt;jsp-file&gt;/TestPage.jsp&lt;/jsp-file&gt;<br />
&lt;/servlet&gt;<br />
命名JSP页面的原因与命名servlet的原因完全相同：即为了提供一个与定制设置（如，初始化参数和安全设置）一起使用的名称，并且，以便能更改激活 JSP页面的URL（比方说，以便多个URL通过相同页面得以处理，或者从URL中去掉.jsp扩展名）。但是，在设置初始化参数时，应该注意，JSP页面是利用jspInit方法，而不是init方法读取初始化参数的。<br />
例如，程序清单5-3给出一个名为TestPage.jsp的简单JSP页面，它的工作只是打印出用来激活它的URL的本地部分。TestPage.jsp放置在deployDemo应用的顶层。程序清单5-4给出了用来分配一个注册名PageName，然后将此注册名与<a href="http://host/webAppPrefix/UrlTest2/anything">http://host/webAppPrefix/UrlTest2/anything</a> 形式的URL相关联的web.xml文件（即，deployDemo/WEB-INF/web.xml）的一部分。</p>
<p>程序清单5-3 TestPage.jsp<br />
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />
&lt;HTML&gt;<br />
&lt;HEAD&gt;<br />
&lt;TITLE&gt;<br />
JSP Test Page<br />
&lt;/TITLE&gt;<br />
&lt;/HEAD&gt;<br />
&lt;BODY BGCOLOR="#FDF5E6"&gt;<br />
&lt;H2&gt;URI: &lt;%= request.getRequestURI() %&gt;&lt;/H2&gt;<br />
&lt;/BODY&gt;<br />
&lt;/HTML&gt;</p>
<p>程序清单5-4 web.xml（说明JSP页命名的摘录）<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE web-app<br />
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />
"<a href="http://java.sun.com/dtd/web-app_2_3.dtd">http://java.sun.com/dtd/web-app_2_3.dtd</a>"&gt;</p>
<p>&lt;web-app&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />
&lt;jsp-file&gt;/TestPage.jsp&lt;/jsp-file&gt;<br />
&lt;/servlet&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet-mapping&gt;<br />
&lt;servlet-name&gt; PageName &lt;/servlet-name&gt;<br />
&lt;url-pattern&gt;/UrlTest2/*&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;/web-app&gt;</p>
转自:http://lizzyostrich.blog.sohu.com/83686972.html
<img src ="http://www.blogjava.net/zilong/aggbug/191067.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2008-04-06 17:36 <a href="http://www.blogjava.net/zilong/archive/2008/04/06/191067.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>web.xml的细节</title><link>http://www.blogjava.net/zilong/archive/2008/04/06/191066.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Sun, 06 Apr 2008 09:34:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2008/04/06/191066.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/191066.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2008/04/06/191066.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/191066.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/191066.html</trackback:ping><description><![CDATA[<p>web.xml的元素 <br />
首先注意 xml是大小写敏感的</p>
<p>1、 web.xml的头和根元素<br />
必须以一个XML头开始。这个头声明可以使用的XML版本并给出文件的字符编码。 <br />
DOCYTPE声明必须立即出现在此头之后。这个声明告诉服务器适用的servlet规范的版本（如2.2或2.3）并指定管理此文件其余部分内容的语法的DTD(Document Type Definition，文档类型定义)。 <br />
所有部署描述符文件的顶层（根）元素为web-app。<br />
例（红色部分是可选项）：<br />
--------------------------------------------------------------------------------------------------------------------------<br />
&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
&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;<br />
&nbsp;&nbsp; &lt;web-app id="WebApp"&gt;<br />
&nbsp;&nbsp; &lt;/web-app&gt;<br />
--------------------------------------------------------------------------------------------------------------------------<br />
&nbsp;2、元素 <br />
以下元素几乎都是可选项，不过要注意它们是有顺序的。虽然有些服务器要求宽松些，但某些服务器会拒绝执行顺序不正确的web应用。所以还是按顺序写好</p>
<p>--------------------------------------------------------------------------------------------------------------------------<br />
&#183; icon icon元素指出IDE和GUI工具用来表示Web应用的一个和两个图像文件的位置。 <br />
&#183; display-name display-name元素提供GUI工具可能会用来标记这个特定的Web应用的一个名称。 <br />
&#183; description description元素给出与此有关的说明性文本。 <br />
&#183; context-param context-param元素声明应用范围内的初始化参数。 <br />
&#183; filter 过滤器元素将一个名字与一个实现javax.servlet.Filter接口的类相关联。 <br />
&#183; filter-mapping 一旦命名了一个过滤器，就要利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。 <br />
&#183; listener servlet API的版本2.3增加了对事件监听程序的支持，事件监听程序在建立、修改和删除会话或servlet环境时得到通知。Listener元素指出事件监听程序类。 <br />
&#183; servlet 在向servlet或JSP页面制定初始化参数或定制URL时，必须首先命名servlet或JSP页面。Servlet元素就是用来完成此项任务的。 <br />
&#183; servlet-mapping服务器一般为servlet提供一个缺省的URL：http://host/webAppPrefix/servlet/ServletName。但是，常常会更改这个URL，以便servlet可以访问初始化参数或更容易地处理相对URL。在更改缺省URL时，使用servlet-mapping元素。<br />
&#183;session-config如果某个会话在一定时间内未被访问，服务器可以抛弃它以节省内存。可通过使用HttpSession的setMaxInactiveInterval方法明确设置单个会话对象的超时值，或者可利用session-config元素制定缺省超时值。 <br />
&#183; mime-mapping 如果Web应用具有想到特殊的文件，希望能保证给他们分配特定的MIME类型，则mime-mapping元素提供这种保证。 <br />
&#183; welcom-file-list welcome-file-list元素指示服务器在收到引用一个目录名而不是文件名的URL时，使用哪个文件。 <br />
&#183; error-page error-page元素使得在返回特定HTTP状态代码时，或者特定类型的异常被抛出时，能够制定将要显示的页面。 <br />
&#183; taglib taglib元素对标记库描述符文件（Tag Libraryu Descriptor file）指定别名。此功能使你能够更改TLD文件的位置，而不用编辑使用这些文件的JSP页面。 <br />
&#183; resource-env-ref resource-env-ref元素声明与资源相关的一个管理对象。 <br />
&#183; resource-ref resource-ref元素声明一个资源工厂使用的外部资源。 <br />
&#183; security-constraint security-constraint元素制定应该保护的URL。它与login-config元素联合使用 <br />
&#183; login-config 用login-config元素来指定服务器应该怎样给试图访问受保护页面的用户授权。它与sercurity-constraint元素联合使用。 <br />
&#183; security-role security-role元素给出安全角色的一个列表，这些角色将出现在servlet元素内的security-role-ref元素的role-name子元素中。分别地声明角色可使高级IDE处理安全信息更为容易。 <br />
&#183; env-entry env-entry元素声明Web应用的环境项。 <br />
&#183; ejb-ref ejb-ref元素声明一个EJB的主目录的引用。 <br />
&#183; ejb-local-ref ejb-local-ref元素声明一个EJB的本地主目录的应用。 </p>
<p><br />
该文章的原文地址为：http://www.blogjava.net/fastzch/archive/2007/08/28/140607.html</p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/zilong/aggbug/191066.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2008-04-06 17:34 <a href="http://www.blogjava.net/zilong/archive/2008/04/06/191066.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring与weblogic jndi集成</title><link>http://www.blogjava.net/zilong/archive/2008/03/01/183059.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Fri, 29 Feb 2008 17:01:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2008/03/01/183059.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/183059.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2008/03/01/183059.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/183059.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/183059.html</trackback:ping><description><![CDATA[&nbsp;
<h3>Spring<span style="font-family: 宋体">与</span>weblogic jndi<span style="font-family: 宋体">集成</span></h3>
<p><span style="font-family: 宋体">虽然</span>spring<span style="font-family: 宋体">本身是可以直接使用</span>jndi<span style="font-family: 宋体">来进行获取一些对象</span>,<span style="font-family: 宋体">但是在和</span>weblogic<span style="font-family: 宋体">集成的时候往往还是容易出</span></p>
<p><span style="font-family: 宋体">现问题</span>(<span style="font-family: 宋体">在</span>web<span style="font-family: 宋体">应用的时候出现问题的可能性不大</span>,<span style="font-family: 宋体">因为</span>container<span style="font-family: 宋体">已经做了很多事情了</span>.)<span style="font-family: 宋体">但是在</span>ide<span style="font-family: 宋体">或者其</span></p>
<p><span style="font-family: 宋体">他的应用环境下</span>(<span style="font-family: 宋体">不同的</span>jvm<span style="font-family: 宋体">的时候</span>),<span style="font-family: 宋体">通常找不到</span>provider_url<span style="font-family: 宋体">等属性造成无法找到</span>jndi. </p>
<p><span style="font-family: 宋体">修改配置文件如下</span>: </p>
<p>&lt;!-- <span style="font-family: 宋体">通过</span>jndi<span style="font-family: 宋体">的方式来调用</span>datasource<span style="font-family: 宋体">，即使不一定是在</span>j2ee<span style="font-family: 宋体">环境中也可以正常使用默认情况下，如果</span></p>
<p><span style="font-family: 宋体">没有指定，</span>"java:comp/env/"<span style="font-family: 宋体">将放在后面</span>jndi<span style="font-family: 宋体">名称前面</span></p>
<p>--&gt; </p>
<p>&lt;bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"&gt; </p>
<p>&lt;property name="jndiName"&gt; </p>
<p>&lt;value&gt;jdbc/myDatasource&lt;/value&gt; </p>
<p>&lt;/property&gt; </p>
<p>&lt;!-- <span style="font-family: 宋体">如果你不想使用</span> 'java:comp/env/'<span style="font-family: 宋体">前缀的话请设置下面的值为</span>true, <span style="font-family: 宋体">默认值为</span>false --&gt; </p>
<p>&lt;property name="resourceRef"&gt; </p>
<p>&lt;value&gt;false&lt;/value&gt; </p>
<p>&lt;/property&gt; </p>
<p>&lt;property name="jndiEnvironment"&gt; </p>
<p>&lt;props&gt; </p>
<p>Spring<span style="font-family: 宋体">连接</span>weblogic-DataSource<span style="font-family: 宋体">错误</span></p>
<p>&lt;!-- The value of Context.PROVIDER_URL --&gt; </p>
<p>&lt;prop key="java.naming.provider.url"&gt;t3://localhost:7001&lt;/prop&gt; </p>
<p>&lt;prop key="java.naming.factory.initial"&gt;weblogic.jndi.WLInitialContextFactory </p>
<p>&lt;/prop&gt; </p>
<p>&lt;/props&gt; </p>
<p>&lt;/property&gt; </p>
<p>&lt;/bean&gt; </p>
<p><span style="font-family: 宋体">注意在设置的时候由于不在同一个</span>jvm<span style="font-family: 宋体">里面</span>,<span style="font-family: 宋体">所以一定要设置</span>provider.url<span style="font-family: 宋体">和</span>factory.initial<span style="font-family: 宋体">的属性值</span>,<span style="font-family: 宋体">否</span></p>
<p><span style="font-family: 宋体">则会出现</span>NoInitialContextException<span style="font-family: 宋体">的异常出现</span>. </p>
<p><span style="font-family: 宋体">此外如果和其他的应用服务器集成的话可能不只是要设置上面的两个属性，还要设置相关的其他属性。详</span></p>
<p><span style="font-family: 宋体">细情况参考：</span>javax.naming.Context<span style="font-family: 宋体">类的说明文档。</span></p>
<p>http://java.sun.com/j2se/1.4.2/docs/api/javax/naming/Context.html </p>
<p><span style="font-family: 宋体">其中设置的：</span></p>
<p>&lt;property name="jndiEnvironment"&gt; </p>
<p>&lt;props&gt; </p>
<p>&lt;!-- The value of Context.PROVIDER_URL --&gt; </p>
<p>&lt;prop key="java.naming.provider.url"&gt;t3://localhost:7001&lt;/prop&gt; </p>
<p>&lt;prop key="java.naming.factory.initial"&gt;weblogic.jndi.WLInitialContextFactory </p>
<p>&lt;/prop&gt; </p>
<p>&lt;/props&gt; </p>
<p>&lt;/property&gt; <span style="font-family: 宋体">实际上就是设置</span>Context<span style="font-family: 宋体">初始化的时候设置的</span>Properties<span style="font-family: 宋体">属性。</span></p>
<p>http://java.mblogger.cn/layout/posts/11849.aspx </p>
<p>=====================================================================</p>
<p>=====================================================================</p>
<h3><span style="font-family: 宋体">各种应用服务器的不同的</span>properties<span style="font-family: 宋体">集合</span>: </h3>
<p>websphere: </p>
<p>java.naming.provider.url-&gt;iiop://websphere.machine.domain.com:900 </p>
<p>java.naming.factory.initial -&gt;com.ibm.websphere.naming.WsnInitialContextFactory </p>
<p>java.naming.factory.url.pkgs -&gt;com.ibm.ws.naming </p>
<p>org.omg.CORBA.ORBClass-&gt;com.ibm.rmi.iiop.ORB </p>
<p>org.omg.CORBA.ORBSingletonClass-&gt;com.ibm.rmi.corba.ORBSingleton </p>
<p>javax.rmi.CORBA.UtilClass-&gt;com.ibm.rmi.javax.rmi.CORBA.Util </p>
<p>javax.rmi.CORBA.StubClass-&gt;com.ibm.rmi.javax.rmi.CORBA.StubDelegateImpl </p>
<p>javax.rmi.CORBA.PortableRemoteObjectClass-&gt;com.ibm.rmi.javax.rmi.PortableRemoteObject </p>
<p>weblogic: </p>
<p>java.naming.factory.initial -&gt; weblogic.jndi.WLInitialContextFactory </p>
<p>java.naming.provider.url -&gt; t3://localhost:7001 </p>
<p>jboss: </p>
<p>ava.naming.factory.initial -&gt;org.jnp.interfaces.NamingContextFactory </p>
<p>java.naming.factory.url.pkgs-&gt;org.jboss.naming.client </p>
<p>java.naming.provider.url -&gt;jnp://10.0.0.18:1099 </p>
<p>sunone IMQ ldap: </p>
<p>java.naming.provider.url -&gt; ldap://localhost:389/dc=yusong,dc=com </p>
<p>java.naming.factory.initial -&gt; com.sun.jndi.ldap.LdapCtxFactory </p>
<p>sunone Application Server: </p>
<p>java.naming.provider.url -&gt; iiop://192.168.0.34:3700 </p>
<p>java.naming.factory.initial -&gt; com.sun.jndi.cosnaming.CNCtxFactory </p>
<p>oracle oc4j: </p>
<p>java.naming.factory.initial-&gt;com.evermind.server.ApplicationClientInitialContextFactory </p>
<p>java.naming.provider.url-&gt;ormi://localhost/bmpapp </p>
<img src ="http://www.blogjava.net/zilong/aggbug/183059.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2008-03-01 01:01 <a href="http://www.blogjava.net/zilong/archive/2008/03/01/183059.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring中session管理opersession，避免页面中数据未输出完session就被关闭了(session延迟加载)</title><link>http://www.blogjava.net/zilong/archive/2008/02/26/182334.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Tue, 26 Feb 2008 15:02:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2008/02/26/182334.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/182334.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2008/02/26/182334.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/182334.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/182334.html</trackback:ping><description><![CDATA[<br />
配置WEB.XML ，让SESSION在页面中一直打开.<br />
<br />
&lt;!-- spring中对hibernate的一个session支持，直到页面执行完后才能关闭 --&gt;<br />
&lt;filter&gt;<br />
&nbsp;&nbsp;&lt;filter-name&gt;opensession&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&lt;filter-class&gt;<br />
&nbsp;&nbsp;&nbsp;org.springframework.orm.hibernate3.support.OpenSessionInViewFilter<br />
&nbsp;&nbsp;&lt;/filter-class&gt;<br />
<br />
&lt;!--&nbsp;&nbsp;当遇到所有的.do文件都要按照此设置 --&gt;<br />
&nbsp;&lt;/filter&gt;<br />
&nbsp;&lt;filter-mapping&gt;<br />
&nbsp;&nbsp;&lt;filter-name&gt;opensession&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&lt;url-pattern&gt;*.do&lt;/url-pattern&gt;<br />
&nbsp;&lt;/filter-mapping&gt; 
<img src ="http://www.blogjava.net/zilong/aggbug/182334.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2008-02-26 23:02 <a href="http://www.blogjava.net/zilong/archive/2008/02/26/182334.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Weblogic 9.1的domain配置mysql连接池</title><link>http://www.blogjava.net/zilong/archive/2008/02/26/182152.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Tue, 26 Feb 2008 02:11:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2008/02/26/182152.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/182152.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2008/02/26/182152.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/182152.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/182152.html</trackback:ping><description><![CDATA[<p>1.在weblogic目录下的serverlib下添加mysql驱动
<p>mysql-connector-java-3.1.11-bin.jar
<p>2.在weblogic目录下的commonbin下找到commEnv.cmd打开
<p>找到set weblogic_classpath= 后边加上mysql驱动的路径
<p>例：%WL_HOME%\server\lib\mysql-connector-java-3.1.11-bin.jar <br />
(@rem set up WebLogic Server's class path<br />
<span style="background-color: yellow"><strong>set WEBLOGIC_CLASSPATH</strong></span>=%PATCH_CLASSPATH%;%JAVA_HOME%\lib\tools.jar;%WL_HOME%\server\lib\weblogic_sp.jar;%WL_HOME%\server\lib\weblogic.jar;%WL_HOME%\server\lib\webservices.jar;%WL_HOME%\server\lib\MySQL5.0 driver.zip)<br />
<p>3.创建domain
<p>4.在开始菜单打开start AdminServer for weblogic Server domain
<p>等到running状态
<p>5.打开console 输入用户名密码。
<p>6.点开Service-&gt;JDBC-&gt;Data Source
<p>7.JDBC Data Source Properties 页面
<p>Name和JNDI Name可以一样 我起名为MySQLJDBCDataSource
<p>Database Type:选择MySQL
<p>Database Driver:选择第一个com包下的驱动就可以 Next.
<p>8.Transaction Options
<p>选择倒数第二个Emulate Two-Phase Commit Next.
<p>9.Connection Properties
<p>Database Name :自己的数据库名 例如：test
<p>Host Name :主机名 例如：localhost或192.168.1.117
<p>Port :3306 (mysql默认)
<p>Database User Name:数据库用户名
<p>Password :数据库密码
<p>Confirm Password :同上 Next
<p>10.Test Database Connection
<p>可以点击Test Configuration 测试一下数据库连接。Next
<p>11.Select Targets
<p>选择发布到哪个AdminServer的JNDI树上。Next
<p>12.点击左上的Activate Changes 如果没有异常就OK了哦。
<p>友情提示：
<p>1) 如果你直接在weblogic下配连接池而不在weblogic下的domain下配置，可以跳过1，2步。
<p>2) 如果配置成功后你可以在console下的Environment-&gt;Servers页面点击你的AdminServer(admin)，然后View JNDI Tree中看到你刚配置的JNDI名。 </p>
<img src ="http://www.blogjava.net/zilong/aggbug/182152.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2008-02-26 10:11 <a href="http://www.blogjava.net/zilong/archive/2008/02/26/182152.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Weblogic9.0图解安装</title><link>http://www.blogjava.net/zilong/archive/2008/02/25/182042.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Mon, 25 Feb 2008 08:58:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2008/02/25/182042.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/182042.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2008/02/25/182042.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/182042.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/182042.html</trackback:ping><description><![CDATA[<div class="postTitle"><a href="http://blog.csdn.net/alex197963/archive/2007/06/03/1636515.aspx">&nbsp;Weblogic9.0图解安装&nbsp;</a>&nbsp;&nbsp;(详细可参考BEA官方网站：http://e-docs.bea.com/wlp/docs92/index.html)</div>
<div class="postText">初次使用Weblogic9.0图解安装<br />
<br />
<hr width="100%" size="2" />
<img height="66" alt="weblogic1.jpg" src="http://www.blogjava.net/images/blogjava_net/rickhunter/weblogic/weblogic1.jpg" width="672" border="0" /><br />
<br />
<img height="559" alt="weblogic2.jpg" src="http://www.blogjava.net/images/blogjava_net/rickhunter/weblogic/weblogic2.jpg" width="780" border="0" /><br />
<br />
<img height="559" alt="weblogic3.jpg" src="http://www.blogjava.net/images/blogjava_net/rickhunter/weblogic/weblogic3.jpg" width="780" border="0" /><br />
<br />
<img height="559" alt="weblogic4.jpg" src="http://www.blogjava.net/images/blogjava_net/rickhunter/weblogic/weblogic4.jpg" width="780" border="0" /><br />
<br />
<img height="559" alt="weblogic9.jpg" src="http://www.blogjava.net/images/blogjava_net/rickhunter/weblogic/weblogic9.jpg" width="780" border="0" /><br />
<br />
<img height="559" alt="weblogic10.jpg" src="http://www.blogjava.net/images/blogjava_net/rickhunter/weblogic/weblogic10.jpg" width="780" border="0" /><br />
<br />
<img height="559" alt="weblogic7.jpg" src="http://www.blogjava.net/images/blogjava_net/rickhunter/weblogic/weblogic7.jpg" width="780" border="0" /><br />
<br />
<img height="559" alt="weblogic8.jpg" src="http://www.blogjava.net/images/blogjava_net/rickhunter/weblogic/weblogic8.jpg" width="780" border="0" /><br />
<br />
初次使用Weblogic，需要对其进行域的<strong style="color: black; background-color: #ff9999">配置</strong>。现在我就<a name="baidusnap2"></a><strong style="color: black; background-color: #99ff99">图解</strong>说明怎样<strong style="color: black; background-color: #ff9999">配置</strong><strong style="color: black; background-color: #ffff66">Weblogic9</strong>.0<br />
<br />
<hr width="100%" size="2" />
<img height="66" alt="weblogic1.jpg" src="http://www.blogjava.net/images/blogjava_net/rickhunter/weblogic/weblogic1.jpg" width="672" border="0" /><br />
<br />
<img height="559" alt="weblogic2.jpg" src="http://www.blogjava.net/images/blogjava_net/rickhunter/weblogic/weblogic2.jpg" width="780" border="0" /><br />
<br />
<img height="559" alt="weblogic3.jpg" src="http://www.blogjava.net/images/blogjava_net/rickhunter/weblogic/weblogic3.jpg" width="780" border="0" /><br />
<br />
<img height="559" alt="weblogic4.jpg" src="http://www.blogjava.net/images/blogjava_net/rickhunter/weblogic/weblogic4.jpg" width="780" border="0" /><br />
<br />
<img height="559" alt="weblogic9.jpg" src="http://www.blogjava.net/images/blogjava_net/rickhunter/weblogic/weblogic9.jpg" width="780" border="0" /><br />
<br />
<img height="559" alt="weblogic10.jpg" src="http://www.blogjava.net/images/blogjava_net/rickhunter/weblogic/weblogic10.jpg" width="780" border="0" /><br />
<br />
<img height="559" alt="weblogic7.jpg" src="http://www.blogjava.net/images/blogjava_net/rickhunter/weblogic/weblogic7.jpg" width="780" border="0" /><br />
<br />
<img height="559" alt="weblogic8.jpg" src="http://www.blogjava.net/images/blogjava_net/rickhunter/weblogic/weblogic8.jpg" width="780" border="0" /><br />
<br />
&nbsp;<br />
&nbsp;<br />
<br />
<p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1636515</p>
</div>
<img src ="http://www.blogjava.net/zilong/aggbug/182042.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2008-02-25 16:58 <a href="http://www.blogjava.net/zilong/archive/2008/02/25/182042.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java系统中内存泄漏测试方法的研究</title><link>http://www.blogjava.net/zilong/archive/2008/02/24/181799.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Sun, 24 Feb 2008 10:23:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2008/02/24/181799.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/181799.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2008/02/24/181799.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/181799.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/181799.html</trackback:ping><description><![CDATA[<h2 class="mode_title" id="veryTitle" style="font-size: 16px" align="center"><span style="background-color: #ccffcc">Java系统中内存泄漏测试方法的研究</span></h2>
<div class="mode_table_menu"><span class="left" style="clear: left; width: 100%; text-align: left">本文链接：<span style="cursor: pointer" onclick="copyBlogURL()">http://user.qzone.qq.com/18485108/blog/1203413108</span></span></div>
<div class="lh3" id="veryContent" style="overflow: hidden; width: 100%">
<table class="contentTable" id="blogContentTable" cellspacing="0" cellpadding="0">
    <tbody>
        <tr>
            <td style="font-size: 12px; word-wrap: break-word" valign="top">
            <div id="blogContainer">
            <div id="paperTitleArea" style="display: none" align="center"><span id="paperTitle" style="display: block; font-weight: bolder; word-break: break-all"><font face="" color="#000e04">Java系统中内存泄漏测试方法的研究</font></span></div>
            <img id="paperPicArea" style="display: none" src="http://imgcache.qq.com/qzone_v4/b.gif"  alt="" /><strong><wbr>摘 要</strong><wbr> 稳定性是衡量软件系统质量的重要指标，<a onclick="showLinkBubble(this);return false" href="http://diy.yesky.com/memoery/" target="_blank" link="http://diy.yesky.com/memoery/"><font style="line-height: 1.3em" color="#003399">内存</font><wbr></a><wbr>泄漏是破坏系统稳定性的重要因素。由于采用垃圾回收机制，Java语言的内存泄漏的模式与C++等语言相比有很大的不同。全文通过与C++中的内存泄漏问题进行对比，讲述了Java内存泄漏的基本原理，以及如何借助Optimizeit profiler工具来测试内存泄漏和分析内存泄漏的原因，在实践中证明这是一套行之有效的方法。<br />
            <br />
            　　<strong><wbr>关键词</strong><wbr> Java; 内存泄漏; GC(垃圾收集器) 引用; Optimizeit<br />
            <br />
            　　<strong><wbr>问题的提出</strong><wbr><br />
            <br />
            　　笔者曾经参与开发的网管系统，系统规模庞大，涉及上百万行代码。系统主要采用Java语言开发，大体上分为客户端、服务器和数据库三个层次。在版本进入测试和试用的过程中，现场人员和测试部人员纷纷反映:系统的稳定性比较差，经常会出现服务器端运行一昼夜就死机的现象，客户端跑死的现象也比较频繁地发生。对于网管系统来讲，经常性的服务器死机是个比较严重的问题，因为频繁的死机不仅可能导致前后台数据不一致，发生错误，更会引起用户的不满，降低客户的信任度。因此，服务器端的稳定性问题必须尽快解决。<br />
            <br />
            　　<strong><wbr>解决思路</strong><wbr><br />
            <br />
            　　通过察看服务器端日志，发现死机前服务器端频繁抛出OutOfMemoryException内存溢出错误，因此初步把死机的原因定位为内存泄漏引起内存不足，进而引起内存溢出错误。如何查找引起内存泄漏的原因呢?有两种思路:第一种，安排有经验的编程人员对代码进行走查和分析，找出内存泄漏发生的位置;第二种，使用专门的内存泄漏测试工具Optimizeit进行测试。这两种方法都是解决系统稳定性问题的有效手段，使用内存测试工具对于已经暴露出来的内存泄漏问题的定位和解决非常有效;但是软件测试的理论也告诉我们，系统中永远存在一些没有暴露出来的问题，而且，系统的稳定性问题也不仅仅只是内存泄漏的问题，代码走查是提高系统的整体代码质量乃至解决潜在问题的有效手段。基于这样的考虑，我们的内存稳定性工作决定采用代码走查结合测试工具的使用，双管齐下，争取比较彻底地解决系统的稳定性问题。<br />
            <br />
            　　在代码走查的工作中，安排了对系统业务和开发语言工具比较熟悉的开发人员对应用的代码进行了交叉走查，找出代码中存在的数据库连接声明和结果集未关闭、代码冗余和低效等故障若干，取得了良好的效果，文中主要讲述结合工具的使用对已经出现的内存泄漏问题的定位方法。<br />
            <br />
            　　<strong><wbr>内存泄漏的基本原理</strong><wbr><br />
            <br />
            　　在C++语言<a onclick="showLinkBubble(this);return false" href="http://dev.yesky.com/" target="_blank" link="http://dev.yesky.com/"><font style="line-height: 1.3em" color="#003399">程序</font><wbr></a><wbr>中，使用new操作符创建的对象，在使用完毕后应该通过delete操作符显示地释放，否则，这些对象将占用堆空间，永远没有办法得到回收，从而引起内存空间的泄漏。如下的简单代码就可以引起内存的泄漏:<br />
            <br />
            void function(){<br />
            　Int[] vec = new int[5];<br />
            }<br />
            　　在function()方法执行完毕后，vec数组已经是不可达对象，在C++语言中，这样的对象永远也得不到释放，称这种现象为内存泄漏。<br />
            <br />
            　　而Java是通过垃圾收集器(Garbage Collection，GC)自动管理内存的回收，程序员不需要通过调用函数来释放内存，但它只能回收无用并且不再被其它对象引用的那些对象所占用的空间。在下面的代码中，循环申请Object对象，并将所申请的对象放入一个Vector中，如果仅仅释放对象本身，但是因为Vector仍然引用该对象，所以这个对象对GC来说是不可回收的。因此，如果对象加入到Vector后，还必须从Vector中删除，最简单的方法就是将Vector对象设置为null。<br />
            <br />
            Vector v = new Vector(10);<br />
            for (int i = 1; i &lt; 100; i++)<br />
            {<br />
            　Object o = new Object();<br />
            　v.add(o);<br />
            　o = null;<br />
            }//此时，所有的Object对象都没有被释放，因为变量v引用这些对象。<br />
            　　实际上无用，而还被引用的对象，GC就无能为力了(事实上GC认为它还有用)，这一点是导致内存泄漏最重要的原因。<br />
            <br />
            　　Java的内存回收机制可以形象地理解为在堆空间中引入了重力场，已经加载的类的静态变量和处于活动线程的堆栈空间的变量是这个空间的牵引对象。这里牵引对象是指按照Java语言规范，即便没有其它对象保持对它的引用也不能够被回收的对象，即Java内存空间中的本原对象。当然类可能被去加载，活动线程的堆栈也是不断变化的，牵引对象的集合也是不断变化的。对于堆空间中的任何一个对象，如果存在一条或者多条从某个或者某几个牵引对象到该对象的引用链，则就是可达对象，可以形象地理解为从牵引对象伸出的引用链将其拉住，避免掉到回收池中;而其它的不可达对象由于不存在牵引对象的拉力，在重力的作用下将掉入回收池。在图1中，A、B、C、D、E、F六个对象都被牵引对象所直接或者间接地&#8220;牵引&#8221;，使得它们避免在重力的作用下掉入回收池。如果TR1-A链和TR2-D链断开，则A、B、C三个对象由于失去牵引，在重力的作用下掉入回收池(被回收)，D对象也是同样的原因掉入回收池，而F对象仍然存在一个牵引链(TR3-E-F)，所以不会被回收，如图2、3所示。<br />
            <br />
            　　<wbr><img height="153" src="http://dev.yesky.com/imagelist/06/38/82l19y2gmb61.jpg" width="287" border="0"  alt="" /><wbr><br />
            　　图1 初始状态<br />
            <br />
            　　<wbr><img height="145" src="http://dev.yesky.com/imagelist/06/38/3338k33cia67.jpg" width="294" border="0"  alt="" /><wbr><br />
            　　图2 TR1-A链和TR2-D链断开，A、B、C、D掉入回收池<br />
            <br />
            　　<wbr><img height="154" src="http://dev.yesky.com/imagelist/06/38/76mk48n3sdnh.jpg" width="290" border="0"  alt="" /><wbr><br />
            　　图3 A、B、C、D四个对象被回收<br />
            <br />
            　　通过前面的介绍可以看到，由于采用了垃圾回收机制，任何不可达对象都可以由垃圾收集线程回收。因此通常说的Java内存泄漏其实是指无意识的、非故意的对象引用，或者无意识的对象保持。无意识的对象引用是指代码的开发人员本来已经对对象使用完毕，却因为编码的错误而意外地保存了对该对象的引用(这个引用的存在并不是编码人员的主观意愿)，从而使得该对象一直无法被垃圾回收器回收掉，这种本来以为可以释放掉的却最终未能被释放的空间可以认为是被&#8220;泄漏了&#8221;。<br />
            <br />
            　　这里通过一个例子来演示Java的内存泄漏。假设有一个日志类Logger，其提供一个静态的log(String msg)方法，任何其它类都可以调用Logger.Log(message)来将message的内容记录到系统的日志文件中。Logger类有一个类型为HashMap的静态变量temp，每次在执行log(message)方法的时候，都首先将message的值丢入temp中(以当前线程+当前时间为键)，在方法退出之前再从temp中将以当前线程和当前时间为键的条目删除。注意，这里当前时间是不断变化的，所以log方法在退出之前执行删除条目的操作并不能删除方法执行之初丢入的条目。这样，任何一个作为参数传给log方法的字符串最终由于被Logger的静态变量temp引用，而无法得到回收，这种违背实现者主观意图的无意识的对象保持就是我们所说的Java内存泄漏。<br />
            <strong><wbr>鉴别泄漏对象的方法<br />
            <br />
            </strong><wbr>　　一般说来，一个正常的系统在其运行稳定后其内存的占用量是基本稳定的，不应该是无限制的增长的，同样，对任何一个类的对象的使用个数也有一个相对稳定的上限，不应该是持续增长的。根据这样的基本假设，我们可以持续地观察系统运行时使用的内存的大小和各实例的个数，如果内存的大小持续地增长，则说明系统存在内存泄漏，如果某个类的实例的个数持续地增长，则说明这个类的实例可能存在泄漏情况。<br />
            <br />
            　　Optimizeit是Borland公司的产品，主要用于协助对软件系统进行代码优化和故障诊断，其功能众多，使用方便，其中的OptimizeIt Profiler主要用于内存泄漏的分析。Profiler的堆视图(如图4)就是用来观察系统运行使用的内存大小和各个类的实例分配的个数的，其界面如图四所示，各列自左至右分别为类名称、当前实例个数、自上个标记点开始增长的实例个数、占用的内存空间的大小、自上次标记点开始增长的内存的大小、被释放的实例的个数信息、自上次标记点开始增长的内存的大小被释放的实例的个数信息，表的最后一行是汇总数据，分别表示目前JVM中的对象实例总数、实例增长总数、内存使用总数、内存使用增长总数等。<br />
            <br />
            　　在实践中，可以分别在系统运行四个小时、八个小时、十二个小时和二十四个小时时间点记录当时的内存状态(即抓取当时的内存快照，是工具提供的功能，这个快照也是供下一步分析使用)，找出实例个数增长的前十位的类，记录下这十个类的名称和当前实例的个数。在记录完数据后，点击Profiler中右上角的Mark按钮，将该点的状态作为下一次记录数据时的比较点。<br />
            <br />
            　　<wbr><img height="240" src="http://dev.yesky.com/imagelist/06/38/g8164pkkn9s0.jpg" width="328" border="0"  alt="" /><wbr><br />
            　　图4 Profiler 堆视图<br />
            <br />
            　　系统运行二十四小时以后可以得到四个内存快照。对这四个内存快照进行综合分析，如果每一次快照的内存使用都比上一次有增长，可以认定系统存在内存泄漏，找出在四个快照中实例个数都保持增长的类，这些类可以初步被认定为存在泄漏。<br />
            <br />
            　　<strong><wbr>分析与定位</strong><wbr><br />
            <br />
            　　通过上面的数据收集和初步分析，可以得出初步结论:系统是否存在内存泄漏和哪些对象存在泄漏(被泄漏)，如果结论是存在泄漏，就可以进入分析和定位阶段了。<br />
            <br />
            　　前面已经谈到Java中的内存泄漏就是无意识的对象保持，简单地讲就是因为编码的错误导致了一条本来不应该存在的引用链的存在(从而导致了被引用的对象无法释放)，因此内存泄漏分析的任务就是找出这条多余的引用链，并找到其形成的原因。前面还讲到过牵引对象，包括已经加载的类的静态变量和处于活动线程的堆栈空间的变量。由于活动线程的堆栈空间是迅速变化的，处于堆栈空间内的牵引对象集合是迅速变化的，而作为类的静态变量的牵引对象的集合在系统运行期间是相对稳定的。<br />
            <br />
            　　对每个被泄漏的实例对象，必然存在一条从某个牵引对象出发到达该对象的引用链。处于堆栈空间的牵引对象在被从栈中弹出后就失去其牵引的能力，变为非牵引对象，因此，在长时间的运行后，被泄露的对象基本上都是被作为类的静态变量的牵引对象牵引。<br />
            <br />
            　　Profiler的内存视图除了堆视图以外，还包括实例分配视图(图5)和实例引用图(图6)。<br />
            <br />
            　　Profiler的实例引用图为找出从牵引对象到泄漏对象的引用链提供了非常直接的方法，其界面的第二个栏目中显示的就是从泄漏对象出发的逆向引用链。需要注意的是，当一个类的实例存在泄漏时，并非其所有的实例都是被泄漏的，往往只有一部分是被泄漏对象，其它则是正常使用的对象，要判断哪些是正常的引用链，哪些是不正常的引用链(引起泄漏的引用链)。通过抽取多个实例进行引用图的分析统计以后，可以找出一条或者多条从牵引对象出发的引用链，下面的任务就是找出这条引用链形成的原因。<br />
            <br />
            　　实例分配图提供的功能是对每个类的实例的分配位置进行统计，查看实例分配的统计结果对于分析引用链的形成具有一定的作用，因为找到分配链与引用链的交点往往就可以找到了引用链形成的原因，下面将具体介绍。<br />
            <br />
            　　<wbr><img height="241" src="http://dev.yesky.com/imagelist/06/38/18f0f5ty9383.jpg" width="326" border="0"  alt="" /><wbr><br />
            　　图5 实例分配图<br />
            <br />
            　　<wbr><img height="240" src="http://dev.yesky.com/imagelist/06/38/t22v8k9542v9.jpg" width="325" border="0"  alt="" /><wbr><br />
            　　图6 实例引用图<br />
            <br />
            　　设想一个实例对象a在方法f中被分配，最终被实例对象b所引用，下面来分析从b到a的引用链可能的形成原因。方法f在创建对象a后，对它的使用分为四种情况:1、将a作为返回值返回;2、将a作为参数调用其它方法;3、在方法内部将a的引用传递给其它对象;4、其它情况。其中情况4不会造成由b到a的引用链的生成，不用考虑。下面考虑其它三种情况:对于1、2两种情况，其造成的结果都是在另一个方法内部获得了对象a的引用，它的分析与方法f的分析完全一样(递归分析);考虑第3种情况:1、假设方法f直接将对象a的引用加入到对象b，则对象b到a的引用链就找到了，分析结束;2、假设方法f将对象a的引用加入到对象c，则接下来就需要跟踪对象c的使用，对象c的分析比对象a的分析步骤更多一些，但大体原理都是一样的，就是跟踪对象从创建后被使用的历程，最终找到其被牵引对象引用的原因。<br />
            <br />
            　　现在将泄漏对象的引用链以及引用链形成的原因找到了，内存泄漏测试与分析的工作就到此结束，接下来的工作就是修改相应的<a onclick="showLinkBubble(this);return false" href="http://design.yesky.com/" target="_blank" link="http://design.yesky.com/"><font style="line-height: 1.3em" color="#003399">设计</font><wbr></a><wbr>或者实现中的错误了。<br />
            <br />
            　　<strong><wbr>总结</strong><wbr><br />
            <br />
            　　使用上述的测试和分析方法，在实践中先后进行了三次测试，找出了好几处内存泄漏错误。系统的稳定性得到很大程度的提高，最初运行1~2天就抛出内存溢出异常，修改完成后，系统从未出现过内存溢出异常。此方法适用于任何使用Java语言开发的、对稳定性有比较高要求的软件系统。<br />
            </div>
            </td>
        </tr>
    </tbody>
</table>
</div>
<img src ="http://www.blogjava.net/zilong/aggbug/181799.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2008-02-24 18:23 <a href="http://www.blogjava.net/zilong/archive/2008/02/24/181799.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat 的数据库连接池设置</title><link>http://www.blogjava.net/zilong/archive/2008/02/19/180695.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Tue, 19 Feb 2008 07:47:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2008/02/19/180695.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/180695.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2008/02/19/180695.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/180695.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/180695.html</trackback:ping><description><![CDATA[<p style="font-size: 12pt">1．<span style="background-color: yellow">将数据库驱动程序的JAR文件放在Tomcat的&nbsp;common/lib&nbsp;中</span>；<br />
<br />
2．在<span style="background-color: yellow"><a class="common" href="http://www.soidc.net/search_article.shtml?wo=server.xml" target="_blank">server.xml</a>中设置数据源</span>，以MySQL数据库为例，如下：<br />
在&lt;GlobalNamingResources&gt;&nbsp;&lt;/GlobalNamingResources&gt;节点中加入，<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Resource<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name="jdbc/DBPool"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type="javax.sql.DataSource"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;password="root"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;driverClassName="com.mysql.jdbc.Driver"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxIdle="2"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxWait="5000"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;username="root"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url="jdbc:mysql://127.0.0.1:3306/test"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxActive="4"/&gt;<br />
&nbsp;&nbsp;&nbsp;属性说明：name，数据源名称，通常取&#8221;jdbc/XXX&#8221;的格式；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type，&#8221;javax.sql.DataSource&#8221;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;password，数据库用户密码；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;driveClassName，数据库驱动；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxIdle，最大空闲数，<a class="common" href="http://www.soidc.net/search_article.shtml?wo=%CA%FD%BE%DD%BF%E2%C1%AC%BD%D3" target="_blank">数据库连接</a>的最大空闲时间。超过空闲时间，数据库连<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;接将被标记为不可用，然后被释放。设为0表示无限制。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MaxActive，连接池的最大数据库连接数。设为0表示无限制。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxWait&nbsp;，最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;无限制。<br />
<br />
3．<span style="background-color: yellow">在你的web应用程序的<a class="common" href="http://www.soidc.net/search_article.shtml?wo=web.xml" target="_blank">web.xml</a>中设置数据源参考</span>，如下：<br />
&nbsp;&nbsp;在&lt;web-app&gt;&lt;/web-app&gt;节点中加入，<br />
&nbsp;&nbsp;&lt;resource-ref&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;description&gt;MySQL&nbsp;DB&nbsp;Connection&nbsp;Pool&lt;/description&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;res-ref-name&gt;jdbc/DBPool&lt;/res-ref-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;res-auth&gt;Container&lt;/res-auth&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;res-sharing-scope&gt;Shareable&lt;/res-sharing-scope&gt;<br />
&nbsp;&lt;/resource-ref&gt;<br />
&nbsp;&nbsp;子节点说明：&nbsp;description，描述信息；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;res-ref-name，参考数据源名字，同上一步的属性name；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;res-type，资源类型，&#8221;javax.sql.DataSource&#8221;；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;res-auth，&#8221;Container&#8221;；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;res-sharing-scope，&#8221;Shareable&#8221;；<br />
<br />
4．<span style="background-color: yellow">在web应用程序的context.xml中设置数据源链接</span>，如下：<br />
&nbsp;&nbsp;在&lt;Context&gt;&lt;/Context&gt;节点中加入，<br />
&nbsp;&nbsp;&lt;ResourceLink<br />
&nbsp;&nbsp;&nbsp;name="jdbc/DBPool"&nbsp;<br />
&nbsp;&nbsp;&nbsp;type="javax.sql.DataSource"&nbsp;<br />
&nbsp;&nbsp;&nbsp;global="jdbc/DBPool"/&gt;<br />
&nbsp;&nbsp;&nbsp;属性说明：name，同第2步和第3步的属性name值，和子节点res-ref-name值；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type，同样取&#8221;javax.sql.DataSource&#8221;；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;global，同name值。<br />
&nbsp;<br />
至此，设置完成，下面是如何使用<a class="common" href="http://www.soidc.net/search_article.shtml?wo=%CA%FD%BE%DD%BF%E2%C1%AC%BD%D3%B3%D8" target="_blank">数据库连接池</a>。<br />
1．建立一个连接池类，DBPool.java，用来创建连接池，代码如下：<br />
import&nbsp;javax.naming.Context;<br />
import&nbsp;javax.naming.InitialContext;<br />
import&nbsp;javax.naming.NamingException;<br />
import&nbsp;javax.sql.DataSource;<br />
<br />
public&nbsp;class&nbsp;DBPool&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;static&nbsp;DataSource&nbsp;pool;<br />
&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Context&nbsp;env&nbsp;=&nbsp;null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;env&nbsp;=&nbsp;(Context)&nbsp;new&nbsp;InitialContext().lookup("java:comp/env");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pool&nbsp;=&nbsp;(DataSource)env.lookup("jdbc/DBPool");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(pool==null)&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.println("'DBPool'&nbsp;is&nbsp;an&nbsp;unknown&nbsp;DataSource");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch(NamingException&nbsp;ne)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ne.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;DataSource&nbsp;getPool()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;pool;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
<br />
2．在要用到<a class="common" href="http://www.soidc.net/search_article.shtml?wo=%CA%FD%BE%DD%BF%E2%B2%D9%D7%F7" target="_blank">数据库操作</a>的类或jsp页面中，用DBPool.getPool().getConnection()，获得一个Connection对象，就可以进行数据库操作，最后别忘了对Connection对象调用close()方法，注意：这里不会关闭这个Connection，而是将这个Connection放回数据库连接池。</p>
<img src ="http://www.blogjava.net/zilong/aggbug/180695.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2008-02-19 15:47 <a href="http://www.blogjava.net/zilong/archive/2008/02/19/180695.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于提高自己JAVA水平的十大技术讨论 </title><link>http://www.blogjava.net/zilong/archive/2008/01/23/177233.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Wed, 23 Jan 2008 04:44:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2008/01/23/177233.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/177233.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2008/01/23/177233.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/177233.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/177233.html</trackback:ping><description><![CDATA[<span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">转自：http://blog.csdn.net/jcc3120/archive/2007/12/26/1968677.aspx<br />
<br />
本文列出了当今计算机软件开发和应用领域最重要十种关键<nobr><strong class="kgb" onmouseover='isShowAds = false;isShowAds2 = false;isShowGg = true;InTextAds_GgLayer="_u6280_u672F";KeyGate_ads.ShowGgAds(this,"_u6280_u672F",event)' style="border-top-width: 0px; padding-right: 0px; padding-left: 0px; font-weight: normal; border-left-width: 0px; border-bottom-width: 0px; padding-bottom: 0px; margin: 0px; cursor: hand; color: #0000ff; padding-top: 0px; border-right-width: 0px; text-decoration: underline" onclick='javascript:window.open("http://pagead2.googlesyndication.com/pagead/iclk?sa=l&amp;ai=BXjoc2UJyR5aaNYLy6wP-g_m8AaXhzR6R3_n0A8CNtwGg_goQCBgIIK2F0A0oFDgAUO_O7Oz5_____wFgnaHVgbQFoAGroK_6A6oBCjIwMDAwMzYxMjeyAQ1uZXdzLmNzZG4ubmV0yAEB2gEraHR0cDovL25ld3MuY3Nkbi5uZXQvbi8yMDA3MTIyMC8xMTE5MjcuaHRtbIACAakCvodET4JQgj7IAu251gGoAwHoA7cC9QMABAAA&amp;num=8&amp;adurl=http://www.shenmo.sh.cn/product/product-SimOffice.html&amp;client=ca-pub-5186439242807756");GgKwClickStat("技术","www.shenmo.sh.cn","afc","2000036127");' onmouseout='isShowGg = false;InTextAds_GgLayer="_u6280_u672F"'>技术</strong></nobr>排名，如果你想保证你现在以及未来的几年不失业，那么你最好跟上这些技术的发展。虽然你不必对这十种技术样样精通，但至少应该对它们非常熟悉。 </span></span></span></span></span>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　<strong>　一、XML</strong></span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　在十种技术中，最重要的一种技术我想应该非XML莫属。这里不仅仅指XML规范本身，还包括一系列有关的基于XML的语言：主要有XHTML，XSLT，XSL，DTDs，XML Schema(XSD)，XPath，XQuery和SOAP.如果你现在还对XML一无所知，那么赶快狂补吧。XML是包含类似于HTML标签的一个文本文件，在这个文件中定义了一个树型结构来描述它所保存的<nobr><strong class="kgb" onmouseover='isShowAds = true;isShowAds2 = true;KeyGate_ads.Move(this,"","%u4E00%u4E2A%u771F%u6B63%u7684%u591A%u4EFB%u52A1%u7CFB%u7EDF","-100850","数据","AIX%20V5.3%20%u7CFB%u7EDF%u7BA1%u7406","http%3A//ibm.csdn.net/ISN_J.aspx%3Faction%3DJMP%26pointid%3D2488", event)' style="border-top-width: 0px; font-weight: normal; border-left-width: 0px; border-bottom-width: 0px; cursor: hand; color: #0000ff; border-right-width: 0px; text-decoration: underline" onclick='javascript:window.open("http://s4.17luntan.com/ClickPortal/WebClick.aspx?id=-100850&amp;k=%u6570%u636E&amp;siteid=0098295a-e262-40f7-ae50-7a6fbbdb678b&amp;url=http%3A//news.csdn.net/n/20071220/111927.html&amp;gourl=http%3A//ibm.csdn.net/ISN_J.aspx%3Faction%3DJMP%26pointid%3D2488&amp;parm=F010BD73EE35170753ABD02E31B18B680220D2605B4BFC98&amp;alliedsiteid=0");' onmouseout="isShowAds = false;isShowAds2 = false">数据</strong></nobr>。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　XML最大的优点是你既可以在这个文本文件中存储结构化数据，也可以在其中存储非结构化数据——也就是说，它能包含和描述"粗糙的"文档数据，就象它描述"规则的"表格数据一样。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　XHTML是目前编写HTML的首选方法;因为XHTML本身就是格式良好的XML，与通常畸形的HTML文档相比， XHTML格式文档更容易处理。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　XSLT和XSL是对XML文档进行转换的语言。它们可以将XML文档转换成各种格式，比如另一个文本文件、PDF文件、HTML文件、逗号分割的文件，或者转换成其它的XML文档。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　DTDs 和XML Schema用来描述XML文件所包含的数据内容的类型，使你不用编写定制的代码就能对XML文档的内容进行"有效性"检查，使内容强行遵守给出的规则。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　XPath 和 XQuery是查询语言，用它们可以从XML文档中吸取单个的数据项或者数据项列表。XQuery的功能特别强大，因为它对XPath查询进行了扩展。实际上，XQuery和XML的关系就像SQL之于关系数据库一样。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　SOAP是Web services间进行通讯的标准协议。你不必知道SOAP协议的所有细节，但是你应该熟悉其常用规则及其工作原理，这样你才能使用它。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　<strong>　二、Web Services</strong></span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　Web<nobr><strong class="kgb" onmouseover='isShowAds = true;isShowAds2 = true;KeyGate_ads.Move(this,"","%u4E00%u6B3E%u5F00%u6E90%u7684%u6027%u80FD%u6D4B%u8BD5%u5DE5%u5177","-100849","服务","%u5C06%20Ajax%20%u7528%u4E8E%u591A%u5A92%u4F53","http%3A//ibm.csdn.net/ISN_J.aspx%3Faction%3DJMP%26pointid%3D2473", event)' style="border-top-width: 0px; font-weight: normal; border-left-width: 0px; border-bottom-width: 0px; cursor: hand; color: #0000ff; border-right-width: 0px; text-decoration: underline" onclick='javascript:window.open("http://s4.17luntan.com/ClickPortal/WebClick.aspx?id=-100849&amp;k=%u670D%u52A1&amp;siteid=0098295a-e262-40f7-ae50-7a6fbbdb678b&amp;url=http%3A//news.csdn.net/n/20071220/111927.html&amp;gourl=http%3A//ibm.csdn.net/ISN_J.aspx%3Faction%3DJMP%26pointid%3D2473&amp;parm=F010BD73EE35170753ABD02E31B18B680220D2605B4BFC98&amp;alliedsiteid=0");' onmouseout="isShowAds = false;isShowAds2 = false">服务</strong></nobr>是XML流行后的直接产物。因为XML可以描述数据和对象，XML大纲可以保证XML文档数据的有效性，因为XML的基于文本的规范，因而XML文档极其适合于作为一种跨平台通讯标准的基本格式。如果你还没有接触过Web服务，那么过不了多久你肯定会碰到它，所以必须熟练掌握Web服务，最好是精通它，因为它是迄今为止应用程序间跨不同种类机器、语言、平台和位置通讯的最简单的一种方式。不管你需不需要它，Web服务都会是将来互用性的主要趋势。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　XML工作组的John Bosak曾说过："XML使得Java有事可做"，那么，我们也可以说，Web服务使得所有语言都有事可做。Web服务让运行在大型机上的COBOL应用程序与运行在手持设备上的应用程序相互沟通;让Java小应用与。NET<nobr><strong class="kgb" onmouseover='isShowAds = false;isShowAds2 = false;isShowGg = true;InTextAds_GgLayer="_u670D_u52A1_u5668";KeyGate_ads.ShowGgAds(this,"_u670D_u52A1_u5668",event)' style="border-top-width: 0px; padding-right: 0px; padding-left: 0px; font-weight: normal; border-left-width: 0px; border-bottom-width: 0px; padding-bottom: 0px; margin: 0px; cursor: hand; color: #0000ff; padding-top: 0px; border-right-width: 0px; text-decoration: underline" onclick='javascript:window.open("http://pagead2.googlesyndication.com/pagead/iclk?sa=l&amp;ai=BsUWC2UJyR5aaNYLy6wP-g_m8Acrr7zfm3eSxBcCNtwHw1xwQAhgCIK2F0A0oFDgAUKvctS5gnaHVgbQFqgEKMjAwMDAzNjEyN7IBDW5ld3MuY3Nkbi5uZXTIAQHaAStodHRwOi8vbmV3cy5jc2RuLm5ldC9uLzIwMDcxMjIwLzExMTkyNy5odG1sgAIBqQK-h0RPglCCPqgDAegDtwL1AwAEAAA&amp;num=2&amp;adurl=http://www.chinanet.cc/store/server.php&amp;client=ca-pub-5186439242807756");GgKwClickStat("服务器","www.chinanet.cc","afc","2000036127");' onmouseout='isShowGg = false;InTextAds_GgLayer="_u670D_u52A1_u5668"'>服务器</strong></nobr>相互通讯，让桌面应用与Web服务器进行无缝交互，不但为商业数据处理，同时也为商业功能提供了方便的实现——并且这种实现与语言、平台、和位置无关。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　<strong>三、面向对象编程</strong></span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　许多程序员仍然认为OOP乃技术的象牙之塔，但是细细想一下过去十年里在面向对象领域里占据过统治地位的开发语言之后，你就不会这么认为了，OOP理念从Smalltalk开始，然后蔓延到C++和Pascal(Delphi)，到Java成为真正的主流，几年之后，VB.NET 和 C#的出现可以说是OOP发展到了登峰造极的地步。虽然使用这些语言不必了解OOP的概念，但如果你缺乏一些OOP的基本知识和方法，我想你很难在逐渐疲软的就业市场中找到工作。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><strong>　四、Java， C++， C#， VB.NET</strong> </span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　如果你热衷于技术，并且热爱编程，那么我想你应该轻松玩转这些高级语言，我说的玩转并不一定要你成为超级编程高手。而是能看懂用这些语言编写的代码即可。如果你还有精力用它们编码那就更好了。其实这种机会甚少。但是看代码的机会很多，学习编程的最有效的一种方式就是看源代码——浩如烟海的源代码中很多都不是用你所钟爱的开发语言编写的。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　在过去的几年里，各个语言功能的发展基本上都差不多。现在你完全可以用VB.NET来写Windows服务、Web应用或者命令行程序。即使你只用其中的一种语言写程序。我认为也完全有必要学习另外一种语言，使自己能阅读和理解它们现有的例子代码，并且能将一种语言编写的代码转换成你首选的编程语言代码。这里列出的四种语言可谓是一个强大的开发语言工具箱，如果你掌握了它们，毫无疑问你一定是一个众人仰慕的高手。这里我要声明一下：那就是我并没有要忽略和排除其它的高级语言，如：FORTRAN、COBOL、APL、ADA、Perl和Lisp等等，根据你所从事的领域不同，应该选择适合的语言和工具。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　<strong>五、JavaScript</strong></span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　Java 和JavaScript两者的名字尽管很类似，但它们之间并没有什么关系。为什么一种脚本语言会如此重要，以至于将它列入十种关键技术之一呢?仔细想一下就知道了，目前所有主流的浏览器都使用JavaScript.如果你要编写Web应用程序，那么JavaScript不可或缺。此外，JavaScript还能作为一种<nobr><strong class="kgb" onmouseover='isShowAds = false;isShowAds2 = false;isShowGg = true;InTextAds_GgLayer="_u670D_u52A1_u5668_u7AEF";KeyGate_ads.ShowGgAds(this,"_u670D_u52A1_u5668_u7AEF",event)' style="border-top-width: 0px; padding-right: 0px; padding-left: 0px; font-weight: normal; border-left-width: 0px; border-bottom-width: 0px; padding-bottom: 0px; margin: 0px; cursor: hand; color: #0000ff; padding-top: 0px; border-right-width: 0px; text-decoration: underline" onclick='javascript:window.open("http://pagead2.googlesyndication.com/pagead/iclk?sa=l&amp;ai=BsUWC2UJyR5aaNYLy6wP-g_m8Acrr7zfm3eSxBcCNtwHw1xwQAhgCIK2F0A0oFDgAUKvctS5gnaHVgbQFqgEKMjAwMDAzNjEyN7IBDW5ld3MuY3Nkbi5uZXTIAQHaAStodHRwOi8vbmV3cy5jc2RuLm5ldC9uLzIwMDcxMjIwLzExMTkyNy5odG1sgAIBqQK-h0RPglCCPqgDAegDtwL1AwAEAAA&amp;num=2&amp;adurl=http://www.chinanet.cc/store/server.php&amp;client=ca-pub-5186439242807756");GgKwClickStat("服务器端","www.chinanet.cc","afc","2000036127");' onmouseout='isShowGg = false;InTextAds_GgLayer="_u670D_u52A1_u5668_u7AEF"'>服务器端</strong></nobr>的脚本语言，如将它嵌入在ASP、ASP.NET中，或者嵌入XSLT来扩展功能。目前JavaScript在Mozilla/Netscape中是激活基于XUL界面的首选语言，它派生出了ActionScript，成为Flash MX应用的编程语言。还有就是JavaScript极有可能成为未来新设备的脚本语言以及主流应用的宏语言。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　相比之下，VBScript虽然在微软的产品中得到很好的支持，但从长远来看，没有迹象表明它会有美好前途。微软自己都趋向于用JavaScript(或者用由JavaScript派生的JScript)来编写其客户端脚本代码。因此，如果你要选择脚本语言，非JavaScript莫属。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　<strong>　六、Regular Expressions</strong></span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　从所周知，关系数据库的查询使用SQL，搜索XML文档用XPath 和XQuery，而正则表达式则用来搜索纯文本。例如，你可以用一个命令来查找或删除HTML格式文件中的注释内容。大家都用过"IndexOf"、"InStr"以及"Like"这些内建在JavaScript或VB中的文本搜索函数，这些函数虽然很容易使用，但是它们的功能却无法与正则表达式同日而语——现在每一种主流的开发语言都提供对正则表达式的存取。尽管有人认为正则表达式本身的读写艰涩难懂，但毕竟它的功能强大，使用它的领域也越来越多。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　<strong>七、Design Patterns</strong></span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　就像OOP通过创建和分类对象来简化编程一样，设计模式将普通的对象交互分类成指定的模型，这是一个从一般到具体的过程。OOP的成分使用得越多，设计模式就显得越有用武之地。所以你必须理解它们，跟上其总体理论的发展。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　<strong>　八、Flash MX</strong></span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　当你需要比HTML和CSS所能提供的更多的客户端图形和编程能力时，Flash是最佳选择。在Flash中编程比用Java小应用或者。NET代码来得快得多，也容易得多。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　在最新版本中(MX)，Flash不仅可以画图和进行动画打包，它还是个高度的可编程应用环境。具备强大的与SOAP Web服务沟通的能力，可以调用运行在远端服务器上的ColdFusion、Java或。NET代码。可以说Flash几乎无处不在，包括手持设备、置顶盒、甚至是新的平板电脑，你到处都可以见到它的身影，所以使用它实际上可以扩展和延伸你的应用程序使用领域。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><strong>　九、Linux/Windows</strong> </span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　这是当今PCs机<nobr><strong class="kgb" onmouseover='isShowAds = false;isShowAds2 = false;isShowGg = true;InTextAds_GgLayer="_u64CD_u4F5C_u7CFB_u7EDF";KeyGate_ads.ShowGgAds(this,"_u64CD_u4F5C_u7CFB_u7EDF",event)' style="border-top-width: 0px; padding-right: 0px; padding-left: 0px; font-weight: normal; border-left-width: 0px; border-bottom-width: 0px; padding-bottom: 0px; margin: 0px; cursor: hand; color: #0000ff; padding-top: 0px; border-right-width: 0px; text-decoration: underline" onclick='javascript:window.open("http://pagead2.googlesyndication.com/pagead/iclk?sa=l&amp;ai=B5nXZ2UJyR5aaNYLy6wP-g_m8AYWK6DGN0bv_A8CNtwGg_goQEBgQIK2F0A0oFDgAUK3O7xVgnaHVgbQFqgEKMjAwMDAzNjEyN7IBDW5ld3MuY3Nkbi5uZXTIAQHaAStodHRwOi8vbmV3cy5jc2RuLm5ldC9uLzIwMDcxMjIwLzExMTkyNy5odG1sqQK-h0RPglCCPsgC-bvpA6gDAegDtwL1AwAEAAA&amp;num=16&amp;adurl=http://www.hunter2006.com/pcmonitor.htm&amp;client=ca-pub-5186439242807756");GgKwClickStat("操作系统","www.hunter2006.com","afc","2000036127");' onmouseout='isShowGg = false;InTextAds_GgLayer="_u64CD_u4F5C_u7CFB_u7EDF"'>操作系统</strong></nobr>的两大阵容，如果你想在计算机行业里混，就一定要熟悉它们。对于Linux，最好能自己安装，配置，下载它的图形用户界面以及一些应用程序。自己安装Apache并会编写Web应用程序。要清醒地认识到这个世界除了Windows之外，还有Linux的存在。并且这种局面将会长期存在。反过来，如果你是一个死忠的Linux开发者，不要再继续对Windows的憎恶，要相互学习，取长补短，看看Windows有什么好的东东可以采纳。记住Windows仍然是桌面之王。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　谁也说不准你们公司什么时候会决定从Linux转向Windows，或者从Windows转向Linux.谁也说不准什么时候你会跳槽跑到另外一个使用不同平台的公司上班——或者即便不跳槽，也有可能在不同平台上开始另外一个杀手级项目——所以最好在每个平台上都积累一些经验，而不要在一棵树上吊死。</span></span></span></span></span></p>
<p><strong><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　十、SQL</span></span></span></span></span></strong></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　尽管SQL在当今众多的技术中已不是什么新东西，而且在未来的十年里它的作用很有可能被削弱，甚至整个被淘汰，但它仍然是一种基本技能——别看它是一种基本技能，至今仍有许多开发人员不懂什么是SQL或对它了解不多。不要指望基于图形用户界面的SQL构造器会帮你的忙，还是自己亲手写SQL查询吧，确定你掌握了SQL的基本语法。现在理解了SQL，不仅对以后学习XQuery有所裨益，而且可以使你很快找到简化或改进当前开发项目的途径。</span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　<strong>尾声：培养对技术的好奇心</strong></span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">　　其实，不管技术的发展趋势如何，每个人最重要的一个技能是好奇心。敢于面对挑战，在你目前或未来的工作中，新语言或新技术可能很重要，也可能不怎么重要，你所学习的东西并不一定非要针对你的工作。不要怕失败，任何新的技术对初学者来说都是困难的。大多数的失败都可以归咎于本身急功近利，希望速成。俗话说——千里之行，始于足下，应该脚踏实地，一步一个脚印地往前走。不要让时间来左右你行动，而是要利用时间来关注、研究、测试新的开发技术和工具。</span></span></span></span></span></p>
<span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">&nbsp;<br />
<br />
</span></span></span></span></span>
<p id="TBPingURL"><span style="font-family: 宋体"><span style="font-size: 14pt"><span style="font-size: 12pt"><span style="font-size: 12pt"><span style="font-size: 12pt">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1968677</span></span></span></span></span></p>
<img src ="http://www.blogjava.net/zilong/aggbug/177233.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2008-01-23 12:44 <a href="http://www.blogjava.net/zilong/archive/2008/01/23/177233.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>tomcat的数据库连接池的配置</title><link>http://www.blogjava.net/zilong/archive/2007/12/06/165728.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Thu, 06 Dec 2007 02:16:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2007/12/06/165728.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/165728.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2007/12/06/165728.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/165728.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/165728.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;tomcat的数据库连接池的配置环境：1. 数据库：mysql2. 数据库驱动程序：org.gjt.mm.mysql.DriverJNDI（Java Naming and Directory Interface）概述：Tomcat4（5）提供了一个与Java Enterprise Edition应用服务相兼容的JNDI--InitialContext实现实例。它...&nbsp;&nbsp;<a href='http://www.blogjava.net/zilong/archive/2007/12/06/165728.html'>阅读全文</a><img src ="http://www.blogjava.net/zilong/aggbug/165728.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2007-12-06 10:16 <a href="http://www.blogjava.net/zilong/archive/2007/12/06/165728.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>log4j的用法 </title><link>http://www.blogjava.net/zilong/archive/2007/12/06/165721.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Thu, 06 Dec 2007 01:54:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2007/12/06/165721.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/165721.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2007/12/06/165721.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/165721.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/165721.html</trackback:ping><description><![CDATA[<p align="left"><strong>log4j的用法</strong> <br />
<br />
一、前言：<br />
&nbsp;&nbsp;&nbsp;&nbsp; log4j 是一个开放源码项目，是广泛使用的以Java编写的日志记录包。由于log4j出色的表现，&nbsp;&nbsp;&nbsp;&nbsp; 当时在log4j完成时，log4j开发组织曾建议sun在jdk1.4中用log4j取代jdk1.4 的日志工具类，但当时jdk1.4已接近完成，所以sun拒绝使用log4j，当在java开发中实际使用最多的还是log4j，&nbsp;&nbsp;&nbsp;&nbsp; 人们遗忘了sun的日志工具类。&nbsp;&nbsp;&nbsp;&nbsp; 它的一个独有特性包括在类别中继承的概念。通过使用类别层次结构，这样就减少了日志记录输出量，并将日志记录的开销降到最低。<br />
&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; 它允许开发者控制以任意间隔输出哪些日志语句。通过使用外部配置文件，完全可以在运行时进行配置。几乎每个大的应用程序都包括其自己的日志记录或跟踪 API。经验表明日志记录是开发周期中的重要组成部分。同样，日志记录提供一些优点。首先，它可以提供运行应用程序的确切 上下文。一旦插入到代码中，生成日志记录输出就不需要人为干涉。其次，日志输出可以保存到永久媒体中以便以后研究。最后，除了在开发阶段中使用，十分丰富的日志记录包还可以用作审计工具。 <br />
&nbsp;&nbsp;&nbsp; 依照该规则，在 1996 年初，EU SEMPER（欧洲安全电子市场）项目就决定编写自己的跟踪 API。 在无数次改进、几次具体化和许多工作之后，该 API 已经演变成 log4j，一种流行的 Java 日志记录包。&nbsp; 这个包按 IBM 公共许可证分发，由开放源码权威机构认证。</p>
<p>&nbsp;&nbsp;&nbsp; 日志记录有其自己的缺点。它会降低应用程序的速度。如果太详细，它可能会使屏幕滚动变得看不见。&nbsp; 为了减低这些影响，log4j 被设计成快速且灵活的。由于应用程序很少将日志记录当作是主要功能，&nbsp; log4j API 力争易于了解和使用。<br />
&nbsp;&nbsp;&nbsp;&nbsp; log4j，它可以控制以任意间隔输出哪些日志语句。</p>
<p>二、主要组件</p>
<p>1、根类别（在类别层次结构的顶部，即全局性的日志级别）<br />
&nbsp;<br />
配置根Logger，其语法为：</p>
<p>log4j.rootLogger = [ level ] , appenderName, appenderName, ...</p>
<p>level 是日志记录的类别<br />
appenderName就是指定日志信息输出到哪个地方。您可以同时指定多个输出目的地。 </p>
<p>类别level 为 OFF、FATAL、ERROR、WARN、INFO、DEBUG、log、ALL或自定义的优先级。<br />
og4j常用的优先级FATAL&gt;ERROR&gt;WARN&gt;INFO&gt;DEBUG<br />
配置根Logger，其语法为：<br />
log4j.rootLogger = [ level ] , appenderName, appenderName, &#8230;<br />
如果为log4j.rootLogger=WARN，则意味着只有WARN,ERROR,FATAL被输出，DEBUG,INFO将被屏蔽掉。</p>
<p>举例：log4j.rootCategory=INFO,stdout,Runlog,Errorlog<br />
根日志类别为INFO，DEBUG将被屏蔽，其他的将被输出。 stdout,Runlog,Errorlog分别为3个输出目的地。</p>
<p>&nbsp;2、常用输出格式</p>
<p>&nbsp;-X号:X信息输出时左对齐；<br />
&nbsp;%p:日志信息级别<br />
&nbsp;%d{}:日志信息产生时间<br />
&nbsp;%c:日志信息所在地（类名）<br />
&nbsp;%m:产生的日志具体信息<br />
&nbsp;%n:输出日志信息换行<br />
&nbsp;举例：<br />
log4j.appender.stdout.layout.ConversionPattern= %5p %d{yyyy-MM-dd HH:mm:ss} %c %m %n<br />
log4j.appender.Runlog.layout.ConversionPattern= %5p %d{yyyy-MM-dd HH:mm:ss} %c %m %n<br />
log4j.appender.Errorlog.layout.ConversionPattern= %5p %d{yyyy-MM-dd HH:mm:ss} %c %m %n</p>
<p>3、布局<br />
使用的输出布局，其中log4j提供4种布局：<br />
org.apache.log4j.HTMLLayout（以HTML表格形式布局）<br />
org.apache.log4j.PatternLayout（可以灵活地指定布局模式），<br />
org.apache.log4j.SimpleLayout（包含日志信息的级别和信息字符串），<br />
org.apache.log4j.TTCCLayout（包含日志产生的时间、线程、类别等等信息） </p>
<p>举例：<br />
输出格式为HTML表格<br />
log4j.appender.stdout.layout=org.apache.log4j.HTMLLayout</p>
<p>输出格式为可以灵活地指定布局模式<br />
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout</p>
<p>输出格式为包含日志信息的级别和信息字符串<br />
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout</p>
<p>输出格式为包含日志产生的时间、线程、类别等等信息<br />
log4j.appender.stdout.layout=org.apache.log4j.TTCCLayout</p>
<p><br />
4、目的地</p>
<p>配置日志信息输出目的地Appender，其语法为</p>
<p><br />
log4j.appender.appenderName = fully.qualified.name.of.appender.class<br />
log4j.appender.appenderName.option1 = value1<br />
...<br />
log4j.appender.appenderName.option = valueN<br />
appenderName就是指定日志信息输出到哪个地方。您可以同时指定多个输出目的地。 </p>
<p>log4j支持的输出目的地：<br />
org.apache.log4j.ConsoleAppender 控制台<br />
org.apache.log4j.FileAppender 文件<br />
org.apache.log4j.DailyRollingFileAppender 每天产生一个日志文件<br />
org.apache.log4j.RollingFileAppender （文件大小到达指定尺寸的时候产生一个新的文件），<br />
org.apache.log4j.WriterAppender （将日志信息以流格式发送到任意指定的地方） <br />
org.apache.log4j.net.SMTPAppender 邮件<br />
org.apache.log4j.jdbc.JDBCAppender 数据库<br />
其他如：GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等</p>
<p>举例：</p>
<p><br />
输出到控制台<br />
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender（指定输出到控制台）<br />
log4j.appender.Threshold=DEBUG（指定输出类别）<br />
log4j.appender.CONSOLE.Target=System.out<br />
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout（指定输出布局）<br />
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n（指定输出格式）</p>
<p>输出到文件</p>
<p>&nbsp;&nbsp; log4j.appender.FILE=org.apache.log4j.FileAppender（指定输出到文件）<br />
&nbsp;&nbsp; log4j.appender.FILE.File=file.log（指定输出的路径及文件名）<br />
&nbsp;&nbsp; log4j.appender.FILE.Append=false<br />
&nbsp;&nbsp; log4j.appender.FILE.layout=org.apache.log4j.PatternLayout（指定输出的布局）<br />
&nbsp;&nbsp; log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n（指定输出的格式）</p>
<p>输出到文件（轮换"日志文件",当日志文件达到指定大小时，该文件就被关闭并备份，然后创建一个新的日志文件）</p>
<p>&nbsp; log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender（指定输出到文件）<br />
&nbsp; log4j.appender.ROLLING_FILE.Threshold=ERROR（指定输出类别）<br />
&nbsp; log4j.appender.ROLLING_FILE.File=rolling.log（指定输出的路径及文件名）<br />
&nbsp; log4j.appender.ROLLING_FILE.Append=true<br />
&nbsp; log4j.appender.ROLLING_FILE.MaxFileSize=10KB（指定输出到文件的大小）<br />
&nbsp; log4j.appender.ROLLING_FILE.MaxBackupIndex=1<br />
&nbsp; log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout（指定采用输出布局）<br />
&nbsp; log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n（指定采用输出格式）</p>
<p>输出到Socket<br />
&nbsp;log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender（指定输出到Socket）<br />
&nbsp;log4j.appender.SOCKET.RemoteHost=localhost（远程主机）<br />
&nbsp;log4j.appender.SOCKET.Port=5001（远程主机端口）<br />
&nbsp;log4j.appender.SOCKET.LocationInfo=true<br />
&nbsp;log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout（布局）<br />
&nbsp;log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n（输出格式）</p>
<p>输出到邮件<br />
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender（指定输出到邮件）<br />
&nbsp;log4j.appender.MAIL.Threshold=FATAL<br />
&nbsp;log4j.appender.MAIL.BufferSize=10<br />
&nbsp;log4j.appender.MAIL.From=chenyl@hollycrm.com（发件人）<br />
&nbsp;log4j.appender.MAIL.SMTPHost=mail.hollycrm.com（SMTP服务器）<br />
&nbsp;log4j.appender.MAIL.Subject=Log4J Message<br />
&nbsp;log4j.appender.MAIL.To=chenyl@hollycrm.com（收件人）<br />
&nbsp;log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout（布局）<br />
&nbsp;log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n（格式）</p>
<p>&nbsp;</p>
<p>输出到数据库<br />
&nbsp;log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender（指定输出到数据库）<br />
&nbsp;log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test（指定数据库URL）<br />
&nbsp;log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver（指定数据库driver）<br />
&nbsp;log4j.appender.DATABASE.user=root（指定数据库用户）<br />
&nbsp;log4j.appender.DATABASE.password=root（指定数据库用户密码）<br />
&nbsp;log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n')（组织SQL语句）<br />
&nbsp;log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout（布局）<br />
&nbsp;log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n（格式）</p>
<p>5、日志类别补充<br />
有时我们需要对某个特定的部分指定有别于根类别的日志类别，可以指定某个包的优先级<br />
如：<br />
&nbsp; log4j.category.com.neusoft.mbip.dm.util=ERROR ，其中com.neusoft.mbip.dm.util为我们需要特别指定日志类别的部分。<br />
&nbsp; <br />
&nbsp; 或者可以指定输出文件的优先级<br />
&nbsp; log4j.appender.Errorlog.Threshold=ERROR<br />
&nbsp; <br />
&nbsp;<br />
&nbsp;三、 常用log4j配置&nbsp; </p>
<p>常用log4j配置，一般可以采用两种方式，.properties和.xml,下面举两个简单的例子：</p>
<p>1、log4j.properties</p>
<p>### 设置org.zblog域对应的级别INFO,DEBUG,WARN,ERROR和输出地A1，A2 ##<br />
log4j.category.org.zblog=ERROR,A1 <br />
log4j.category.org.zblog=INFO,A2 </p>
<p>log4j.appender.A1=org.apache.log4j.ConsoleAppender <br />
### 设置输出地A1，为ConsoleAppender(控制台) ##<br />
log4j.appender.A1.layout=org.apache.log4j.PatternLayout <br />
### 设置A1的输出布局格式PatterLayout,(可以灵活地指定布局模式）##<br />
log4j.appender.A1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n <br />
### 配置日志输出的格式##</p>
<p>log4j.appender.A2=org.apache.log4j.RollingFileAppender <br />
### 设置输出地A2到文件（文件大小到达指定尺寸的时候产生一个新的文件）##<br />
log4j.appender.A2.File=E:/study/log4j/zhuwei.html <br />
### 文件位置##<br />
log4j.appender.A2.MaxFileSize=500KB <br />
### 文件大小##<br />
log4j.appender.A2.MaxBackupIndex=1 <br />
log4j.appender.A2.layout=org.apache.log4j.HTMLLayout <br />
##指定采用html方式输出</p>
<p>2、log4j.xml</p>
<p>&lt;?xml version="1.0" encoding="GB2312" ?&gt;<br />
&lt;!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"&gt;</p>
<p>&lt;log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"&gt;</p>
<p>&lt;appender name="org.zblog.all" class="org.apache.log4j.RollingFileAppender"&gt;<br />
&lt;!-- 设置通道ID:org.zblog.all和输出方式：org.apache.log4j.RollingFileAppender --&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;param name="File" value="E:/study/log4j/all.output.log" /&gt;&lt;!-- 设置File参数：日志输出文件名 --&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;param name="Append" value="false" /&gt;&lt;!-- 设置是否在重新启动服务时，在原有日志的基础添加新日志 --&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;layout class="org.apache.log4j.PatternLayout"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="ConversionPattern" value="%p (%c:%L)- %m%n" /&gt;&lt;!-- 设置输出文件项目和格式 --&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/layout&gt;<br />
&lt;/appender&gt;</p>
<p>&lt;appender name="org.zblog.zcw" class="org.apache.log4j.RollingFileAppender"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;param name="File" value="E:/study/log4j/zhuwei.output.log" /&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;param name="Append" value="true" /&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;param name="MaxFileSize" value="10240" /&gt; &lt;!-- 设置文件大小 --&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;layout class="org.apache.log4j.PatternLayout"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="ConversionPattern" value="%p (%c:%L)- %m%n" /&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/layout&gt;<br />
&lt;/appender&gt;</p>
<p>&lt;logger name="zcw.log"&gt; &lt;!-- 设置域名限制，即zcw.log域及以下的日志均输出到下面对应的通道中 --&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;level value="debug" /&gt;&lt;!-- 设置级别 --&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;appender-ref ref="org.zblog.zcw" /&gt;&lt;!-- 与前面的通道id相对应 --&gt;<br />
&lt;/logger&gt;</p>
<p>&lt;root&gt; &lt;!-- 设置接收所有输出的通道 --&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;appender-ref ref="org.zblog.all" /&gt;&lt;!-- 与前面的通道id相对应 --&gt;<br />
&lt;/root&gt;</p>
<p>&lt;/log4j:configuration&gt;</p>
<p><br />
3、配置文件加载方法：</p>
<p>import org.apache.log4j.Logger;<br />
import org.apache.log4j.PropertyConfigurator;<br />
import org.apache.log4j.xml.DOMConfigurator;</p>
<p>public class Log4jApp {<br />
&nbsp;&nbsp;&nbsp; public static void main(String[] args) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DOMConfigurator.configure("E:/study/log4j/log4j.xml");//加载.xml文件<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //PropertyConfigurator.configure("E:/study/log4j/log4j.properties");//加载.properties文件</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Logger log=Logger.getLogger("org.zblog.test");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log.info("测试");<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p>4、项目使用log4j<br />
在web应用中，可以将配置文件的加载放在一个单独的servlet中，并在web.xml中配置该servlet在应用启动时候加载。<br />
对于在多人项目中，可以给每一个人设置一个输出通道，这样在每个人在构建Logger时，用自己的域名称，让调试信<br />
息输出到自己的log文件中。</p>
<p>四、log4j配置举例（properties）</p>
<p>#log4j.rootLogger = [ level ] , appenderName, appenderName, <br />
#类别level 为 OFF、FATAL、ERROR、WARN、INFO、DEBUG、log、ALL或自定义的优先级<br />
#Log4j常用的优先级FATAL&gt;ERROR&gt;WARN&gt;INFO&gt;DEBUG</p>
<p>#stdout为控制台 ，Errorlog为错误记录日志 ，<br />
log4j.rootCategory=INFO,stdout,Runlog,Errorlog</p>
<p><br />
#输出的appender的格式为<br />
#log4j.appender.appenderName = fully.qualified.name.of.appender.class <br />
#log4j.appender.appenderName.option1 = value1 <br />
#log4j.appender.appenderName.option = valueN <br />
#Log4j中appender支持的输出<br />
#org.apache.log4j.ConsoleAppender 控制台<br />
#org.apache.log4j.FileAppender 文件<br />
#org.apache.log4j.DailyRollingFileAppender 每天产生一个日志文件<br />
#org.apache.log4j.RollingFileAppender （文件大小到达指定尺寸的时候产生一个新的文件），<br />
#org.apache.log4j.WriterAppender （将日志信息以流格式发送到任意指定的地方） <br />
#org.apache.log4j.net.SMTPAppender 邮件<br />
#org.apache.log4j.jdbc.JDBCAppender 数据库</p>
<p>＃定义输出的形式<br />
log4j.appender.stdout=org.apache.log4j.ConsoleAppender<br />
log4j.appender.Runlog=org.apache.log4j.DailyRollingFileAppender<br />
log4j.appender.Errorlog=org.apache.log4j.DailyRollingFileAppender</p>
<p><br />
#可以指定输出文件的优先级<br />
log4j.appender.Errorlog.Threshold=ERROR</p>
<p>#指定输出的文件<br />
log4j.appender.Runlog.File=D:\\UserInfoSyn\\WebRoot\\WEB-INF\\runlog\\runlog.log <br />
log4j.appender.Errorlog.File=D:\\UserInfoSyn\\WebRoot\\WEB-INF\\errorlog\\errorlog.log </p>
<p><br />
#Log4j的layout布局<br />
#org.apache.log4j.HTMLLayout 以HTML表格形式布局<br />
#org.apache.log4j.PatternLayout 可以灵活地指定布局模式<br />
#org.apache.log4j.SimpleLayout&nbsp; 包含日志信息的级别和信息字符串<br />
#org.apache.log4j.TTCCLayout&nbsp;&nbsp;&nbsp; 包含日志产生的时间、线程、类别等等信息</p>
<p>log4j.appender.stdout.layout=org.apache.log4j.PatternLayout<br />
log4j.appender.Runlog.layout=org.apache.log4j.PatternLayout<br />
log4j.appender.Errorlog.layout=org.apache.log4j.PatternLayout</p>
<p>#输出格式,log4j javadoc org.apache.log4j.PatternLayout <br />
#-X号:X信息输出时左对齐；<br />
#%p:日志信息级别<br />
# %d{}:日志信息产生时间<br />
# %c:日志信息所在地（类名）<br />
# %m:产生的日志具体信息<br />
# %n:%n:输出日志信息换行<br />
log4j.appender.stdout.layout.ConversionPattern= %5p %d{yyyy-MM-dd HH:mm:ss} %c %m %n<br />
log4j.appender.Runlog.layout.ConversionPattern= %5p %d{yyyy-MM-dd HH:mm:ss} %c %m %n<br />
log4j.appender.Errorlog.layout.ConversionPattern= %5p %d{yyyy-MM-dd HH:mm:ss} %c %m %n</p>
<p>#指定某个包的优先级 <br />
log4j.category.com.neusoft.mbip.dm.util=ERROR</p>
<p><br />
#示例<br />
###################<br />
# Console Appender<br />
###################<br />
#log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender<br />
#log4j.appender.Threshold=DEBUG<br />
#log4j.appender.CONSOLE.Target=System.out<br />
#log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout<br />
#log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n<br />
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n</p>
<p><br />
#####################<br />
# File Appender<br />
#####################<br />
#log4j.appender.FILE=org.apache.log4j.FileAppender<br />
#log4j.appender.FILE.File=file.log<br />
#log4j.appender.FILE.Append=false<br />
#log4j.appender.FILE.layout=org.apache.log4j.PatternLayout<br />
#log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n<br />
# Use this layout for LogFactor 5 analysis</p>
<p>########################<br />
# Rolling File????? RollingFileAppender??????????????????<br />
########################<br />
#log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender<br />
#log4j.appender.ROLLING_FILE.Threshold=ERROR<br />
# 文件位置<br />
#log4j.appender.ROLLING_FILE.File=rolling.log<br />
#log4j.appender.ROLLING_FILE.Append=true<br />
#文件大小<br />
#log4j.appender.ROLLING_FILE.MaxFileSize=10KB<br />
#指定采用输出布局和输出格式<br />
#log4j.appender.ROLLING_FILE.MaxBackupIndex=1<br />
#log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout<br />
#log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n</p>
<p>####################<br />
# Socket Appender<br />
####################<br />
#log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender<br />
#log4j.appender.SOCKET.RemoteHost=localhost<br />
#log4j.appender.SOCKET.Port=5001<br />
#log4j.appender.SOCKET.LocationInfo=true<br />
# Set up for Log Facter 5<br />
#log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout<br />
#log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n</p>
<p>########################<br />
# SMTP Appender<br />
#######################<br />
#log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender<br />
#log4j.appender.MAIL.Threshold=FATAL<br />
#log4j.appender.MAIL.BufferSize=10<br />
#log4j.appender.MAIL.From=chenyl@hollycrm.com<br />
#log4j.appender.MAIL.SMTPHost=mail.hollycrm.com<br />
#log4j.appender.MAIL.Subject=Log4J Message<br />
#log4j.appender.MAIL.To=chenyl@hollycrm.com<br />
#log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout<br />
#log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n</p>
<p>########################<br />
# JDBC Appender<br />
#######################<br />
#log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender<br />
#log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test<br />
#log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver<br />
#log4j.appender.DATABASE.user=root<br />
#log4j.appender.DATABASE.password=<br />
#log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n')<br />
#log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout<br />
#log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n</p>
<p>########################<br />
# Log Factor 5 Appender<br />
########################<br />
#log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender<br />
#log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000</p>
<p>###################<br />
#自定义Appender<br />
###################<br />
#log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender<br />
#log4j.appender.im.host = mail.cybercorlin.net<br />
#log4j.appender.im.username = username<br />
#log4j.appender.im.password = password<br />
#log4j.appender.im.recipient = corlin@cybercorlin.net<br />
#log4j.appender.im.layout=org.apache.log4j.PatternLayout<br />
#log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n</p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/zilong/aggbug/165721.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2007-12-06 09:54 <a href="http://www.blogjava.net/zilong/archive/2007/12/06/165721.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>log4j配置文件基本含义说明</title><link>http://www.blogjava.net/zilong/archive/2007/11/30/164186.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Fri, 30 Nov 2007 02:07:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2007/11/30/164186.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/164186.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2007/11/30/164186.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/164186.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/164186.html</trackback:ping><description><![CDATA[<p><strong>log4j配置文件基本含义说明<br />
</strong>&nbsp;<br />
log4j.properties配置文件讲解如下： <br />
# Set root logger level to DEBUG and its only appender to A1 <br />
#log4j中有五级logger <br />
#FATAL 0 <br />
#ERROR 3 <br />
#WARN 4 <br />
#INFO 6 <br />
#DEBUG 7 </p>
<p>配置根Logger，其语法为：<br />
#log4j.rootLogger = [ level ] , appenderName, appenderName, &#8230;<br />
log4j.rootLogger=INFO, A1 ,R<br />
#这一句设置以为着所有的log都输出<br />
#如果为log4j.rootLogger=WARN, 则意味着只有WARN,ERROR,FATAL<br />
#被输出，DEBUG,INFO将被屏蔽掉.<br />
# A1 is set to be a ConsoleAppender. <br />
#log4j中Appender有几层如控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等<br />
#ConsoleAppender输出到控制台 <br />
log4j.appender.A1=org.apache.log4j.ConsoleAppender <br />
# A1 使用的输出布局，其中log4j提供4种布局. org.apache.log4j.HTMLLayout（以HTML表格形式布局）<br />
#org.apache.log4j.PatternLayout（可以灵活地指定布局模式），<br />
#org.apache.log4j.SimpleLayout（包含日志信息的级别和信息字符串），<br />
#org.apache.log4j.TTCCLayout（包含日志产生的时间、线程、类别等等信息） </p>
<p>log4j.appender.A1.layout=org.apache.log4j.PatternLayout <br />
#灵活定义输出格式 具体查看log4j javadoc org.apache.log4j.PatternLayout <br />
#d 时间 .... <br />
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n <br />
#R 输出到文件 RollingFileAppender的扩展，可以提供一种日志的备份功能。<br />
log4j.appender.R=org.apache.log4j.RollingFileAppender <br />
#日志文件的名称<br />
log4j.appender.R.File=log4j.log <br />
#日志文件的大小<br />
log4j.appender.R.MaxFileSize=100KB <br />
# 保存一个备份文件<br />
log4j.appender.R.MaxBackupIndex=1 log4j.appender.R.layout=org.apache.log4j.TTCCLayout<br />
#log4j.appender.R.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n</p>
<p><br />
配置根Logger，其语法为：</p>
<p>log4j.rootLogger = [ level ] , appenderName, appenderName, ...</p>
<p>level 是日志记录的优先级<br />
appenderName就是指定日志信息输出到哪个地方。您可以同时指定多个输出目的地。 </p>
<p>配置日志信息输出目的地Appender，其语法为</p>
<p><br />
log4j.appender.appenderName = fully.qualified.name.of.appender.class<br />
log4j.appender.appenderName.option1 = value1<br />
...<br />
log4j.appender.appenderName.option = valueN</p>
<p>Log4j提供的appender有以下几种：<br />
org.apache.log4j.ConsoleAppender（控制台），<br />
org.apache.log4j.FileAppender（文件），<br />
org.apache.log4j.DailyRollingFileAppender（每天产生一个日志文件），<br />
org.apache.log4j.RollingFileAppender（文件大小到达指定尺寸的时候产生一个新的文件），<br />
org.apache.log4j.WriterAppender（将日志信息以流格式发送到任意指定的地方） </p>
<p>配置日志信息的格式（布局），其语法为：</p>
<p><br />
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class<br />
log4j.appender.appenderName.layout.option1 = value1<br />
....<br />
log4j.appender.appenderName.layout.option = valueN</p>
<p>Log4j提供的layout有以下几种：<br />
org.apache.log4j.HTMLLayout（以HTML表格形式布局），<br />
org.apache.log4j.PatternLayout（可以灵活地指定布局模式），<br />
org.apache.log4j.SimpleLayout（包含日志信息的级别和信息字符串），<br />
org.apache.log4j.TTCCLayout（包含日志产生的时间、线程、类别等等信息）<br />
</p>
<img src ="http://www.blogjava.net/zilong/aggbug/164186.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2007-11-30 10:07 <a href="http://www.blogjava.net/zilong/archive/2007/11/30/164186.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java开发者必去的20个英文技术网站</title><link>http://www.blogjava.net/zilong/archive/2007/10/15/152910.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Mon, 15 Oct 2007 03:10:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2007/10/15/152910.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/152910.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2007/10/15/152910.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/152910.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/152910.html</trackback:ping><description><![CDATA[<font style="font-size: 14pt; font-family: Arial" size="1">&nbsp;转之：<br />
<p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=666952</p>
&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;
<p>&nbsp;Java开发者必去的20个英文技术网站 </p>
<p><a href="http://www.javaalmanac.com/">http://www.javaalmanac.com</a> - Java开发者年鉴一书的在线版本. 要想快速查到某种Java技巧的用法及示例代码, 这是一个不错的去处. <br />
<a href="http://www.onjava.com/">http://www.onjava.com</a> - O'Reilly的Java网站. 每周都有新文章. <br />
<a href="http://java.sun.com/">http://java.sun.com</a> - 官方的Java开发者网站 - 每周都有新文章发表. <br />
<a href="http://www.developer.com/java">http://www.developer.com/java</a> - 由Gamelan.com 维护的Java技术文章网站. <br />
<a href="http://www.java.net/">http://www.java.net</a> - Sun公司维护的一个Java社区网站. <br />
<a href="http://www.builder.com/">http://www.builder.com</a> - Cnet的Builder.com网站 - 所有的技术文章, 以Java为主. <br />
<a href="http://www.ibm.com/developerworks/java">http://www.ibm.com/developerworks/java</a> - IBM的Developerworks技术网站; 这是其中的Java技术主页. <br />
<a href="http://www.javaworld.com/">http://www.javaworld.com</a> - 最早的一个Java站点. 每周更新Java技术文章. <br />
<a href="http://www.devx.com/java">http://www.devx.com/java</a> - DevX维护的一个Java技术文章网站. <br />
<a href="http://www.fawcette.com/javapro">http://www.fawcette.com/javapro</a> - JavaPro在线杂志网站. <br />
<a href="http://www.sys-con.com/java">http://www.sys-con.com/java</a> - Java Developers Journal的在线杂志网站. <br />
<a href="http://www.javadesktop.org/">http://www.javadesktop.org</a> - 位于Java.net的一个Java桌面技术社区网站. <br />
<a href="http://www.theserverside.com/">http://www.theserverside.com</a> - 这是一个讨论所有Java服务器端技术的网站. <br />
<a href="http://www.jars.com/">http://www.jars.com</a> - 提供Java评论服务. 包括各种framework和应用程序. <br />
<a href="http://www.jguru.com/">http://www.jguru.com</a> - 一个非常棒的采用Q&amp;A形式的Java技术资源社区. <br />
<a href="http://www.javaranch.com/">http://www.javaranch.com</a> - 一个论坛，得到Java问题答案的地方，初学者的好去处。 <br />
<a href="http://www.ibiblio.org/javafaq/javafaq.html">http://www.ibiblio.org/javafaq/javafaq.html</a> - comp.lang.java的FAQ站点 - 收集了来自comp.lang.java新闻组的问题和答案的分类目录. <br />
<a href="http://java.sun.com/docs/books/tutorial/">http://java.sun.com/docs/books/tutorial/</a> - 来自SUN公司的官方Java指南 - 对于了解几乎所有的java技术特性非常有帮助. <br />
<a href="http://www.javablogs.com/">http://www.javablogs.com</a> - 互联网上最活跃的一个Java Blog网站. <br />
<a href="http://java.about.com/">http://java.about.com/</a> - 来自About.com的Java新闻和技术文章网站.<br />
http://www.codechina.net 提供大量的java源代码及教程。</p>
<br />
<p id="TBPingURL">&nbsp;</p>
<br />
<br />
下面是一些我看到过的JAVA网址，觉得还不错，大家有兴趣可以都去看看。<br />
A Programmer's Guide to the World Wide Web<br />
http://www.apl.jhu.edu/~hall/WWW/<br />
学习JAVA及INTERNET相关知识的最佳网站<br />
<br />
developerWorks&nbsp; Java technology&nbsp; overview<br />
http://www.ibm.com/developer/java/<br />
IBM的JAVA开发者交流中心，有大量实用的文档及实例可供下载<br />
<br />
Developing Java Beans<br />
http://www.oreilly.com/catalog/javabeans/noframes.html<br />
讲解JAVABEEAN的开发及过程，有实例可供下载<br />
<br />
Java Programming Resources<br />
http://www.apl.jhu.edu/~hall/java/<br />
学习JAVA的一个好去处，有很多有用的知识集中在这里<br />
<br />
The Source for Java(TM) Technology<br />
http://java.sun.com/<br />
JAVA技术最全、最新、软件最丰富、文档最实用、最。。。。。<br />
这个站点如果你没去过，那千万不要跟别人予你是学JAVA的。：-）<br />
<br />
ＪＡＶＡ２０００-- Final Javascript，ASP，DHTML<br />
http://java2000.wol.com.cn/index.html<br />
大量的JavaScript源代码，去过之后，再出来的时候你已经是JAVAScript大师了<br />
站长更新的时间很频，保证了代码的及时性，还不快去DOWN<br />
<br />
Java程序库<br />
http://www.eastart.com/java.html<br />
大量的JAVA程序集中在这里，对编程有很大的提高，<br />
<br />
Java网络梦工厂<br />
http://helj2000.3322.net/<br />
提供了许多实用的JAVA文档及示例，并有部分的JAVASCRIPT源代码<br />
<br />
SCJP - Sun Certified Java Progammer Exam<br />
http://www.spaceports.com/~javaexam/<br />
这个可不得了了，想通过SUN公司的JAVA认证吗？快去这个网站走走吧<br />
提供了许多试题，并有名师讲解<br />
<br />
探索者工作室<br />
http://grwy.online.ha.cn/explorer/<br />
挺长时间不去这个地方了，因为没时间，也就忘了这是什么的集散地了：）<br />
不过，既然能上到我的书签中，自然也不会是什么省油的灯，去看看吧。<br />
<br />
</font>
<img src ="http://www.blogjava.net/zilong/aggbug/152910.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2007-10-15 11:10 <a href="http://www.blogjava.net/zilong/archive/2007/10/15/152910.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设置WSAD打开时提示选择WORKSPACE的方法</title><link>http://www.blogjava.net/zilong/archive/2007/06/16/124678.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Sat, 16 Jun 2007 10:21:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2007/06/16/124678.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/124678.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2007/06/16/124678.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/124678.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/124678.html</trackback:ping><description><![CDATA[<p>先找到WSAD的安装路径，如：<br>C:\Program Files\IBM\WebSphere Studio\Application Developer\v5.1.1\wsappdev.ini</p>
<p>[Settings]<br>DefaultWorkspace=&lt;My Documents&gt;\IBM\wsappdev51\workspace<br>ProductName=IBM WebSphere Studio Application Developer<br>Version=5.1.1<br>Full=Yes<br>KeyName=wsappdev510<br>VMArgs=-Xj9<br>LUMProductID=1 <br>*************** 加上这句话就可以了**********<br><span style="COLOR: red"><strong>SetWorkSpace=True&nbsp; <br></strong></span>******************END*********************<br>LUMProductVersion=5.1.1<br>Website=www.ibm.com/websphere/developer/zones/studio/appdev/</p>
<p>[Environment Variables]</p>
<img src ="http://www.blogjava.net/zilong/aggbug/124678.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2007-06-16 18:21 <a href="http://www.blogjava.net/zilong/archive/2007/06/16/124678.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WSAD导出系统DOC所有类文档注释</title><link>http://www.blogjava.net/zilong/archive/2007/06/05/122212.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Tue, 05 Jun 2007 10:46:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2007/06/05/122212.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/122212.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2007/06/05/122212.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/122212.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/122212.html</trackback:ping><description><![CDATA[<p>1：<br>先配置WSAD的JAVA-&gt;JAVADOC-&gt;JAVADOC命令（所安装的JDK下的BIN中的JAVADOC.EXE）</p>
<p>2:<br>右键点击要导出DOC文件的源代码包－》&#8220;导出&#8221;－》javadoc－》下一步进入&#8220;生成javadoc&#8221;－》在&#8220;使用标准Doclet(S)&#8221;-&gt;"目标"－》选择DOC存放的路径－》&#8220;完成&#8221;，便会自动将所有类的文档导出来。（当然，前提是每个类里面的注释必须符合规范）</p>
<img src ="http://www.blogjava.net/zilong/aggbug/122212.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2007-06-05 18:46 <a href="http://www.blogjava.net/zilong/archive/2007/06/05/122212.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WASD数据源JNDI配置说明</title><link>http://www.blogjava.net/zilong/archive/2007/04/20/112340.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Fri, 20 Apr 2007 15:07:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2007/04/20/112340.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/112340.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2007/04/20/112340.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/112340.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/112340.html</trackback:ping><description><![CDATA[&nbsp;
<p><span>双击新建的服务器，打开</span><span>WebSphere</span><span>服务器的配置界面：</span></p>
<p><span><span>1．&nbsp;</span></span><span>点击&#8220;环境&#8221;一项－》&#8220;添加外部文件夹&#8221;－》将工程用到的</span><span>config</span><span>文件夹添加近来。此</span><span>config</span><span>文件夹就象以前的数据源配置文件一样，是此工程公用的连接操作数据源的配置文件。</span></p>
<p><span><span>2．&nbsp;</span></span><span>点击&#8220;数据源&#8221;－》在&#8220;服务器设置&#8221;中的&#8220;</span><span>JDBC</span><span>提供程序列表&#8221;－》&#8220;添加&#8221;－》&#8220;数据库类型：</span><span>ORACLE</span><span>&#8221;－》&#8220;</span><span>JDBC</span><span>提供程序类型：</span><span>Oracle JDBC Thin Driver</span><span>&#8221;</span></p>
<p>&nbsp;</p>
<p><span>在</span><span>&#8220;</span><span>在上面选择的</span><span>JDBC</span><span>提供程序中定义的数据源：</span><span>&#8221;</span><span>一栏中－》&#8220;添加&#8221;－》&#8220;选择</span><span>JDBC</span><span>提供的数据源的类型：</span><span>Oracle JDBC Thin Driver</span><span>&#8221;－》下一步－》&#8220;名称随便起，但</span><span>JNDI</span><span>名称必须和</span><span>JNDI.XML</span><span>中的</span><span>JNDI</span><span>名称一致（<span>如：</span></span><span>jdbc/DataSource</span><span>）。然后就是在组件管理的认证别名中选择配好的别名，即<span>后面</span></span><span>4</span><span>中讲到的安全性配置的起的别名</span><span>。&#8221;</span></p>
<p>&nbsp;</p>
<p><span>在&#8220;在以上选择的数据源中定义的资源属性&#8221;一栏中的&#8220;</span><span>URL</span><span>&#8221;选中</span><span>URL</span><span>后点&#8220;编辑&#8221;－》&#8220;值&#8221;－》填入要连接的数据库的</span><span>URL</span><span>&#8220;</span><strong><span> jdbc:oracle:thin:@192.168.100.180:1521:orclcdc</span></strong><span>&#8221;</span><span>,</span></p>
<p><span><span>3．&nbsp;</span></span><span>点击&#8220;端口&#8221;一项，如果要修改服务器的端口，在&#8220;单元设置&#8221;－》&#8220;主机别名列表：&#8221;一栏中和&#8220;服务器设置&#8221;－》&#8220;</span><span>HTTP</span><span>传输列表：&#8221;一栏中的相应端口号都要改。</span></p>
<p><span><span>4．&nbsp;</span></span><span>点击&#8220;安全性&#8221;－》&#8220;单元设置&#8221;－》&#8220;</span><span>JAAS</span><span>认证条目&#8221;－》&#8220;添加&#8221;－》&#8220;<span>别名随便起，（此别名在</span></span><span>2</span><span>中配置数据源时要用到</span><span>）用户标识为：数据库名；密码为登陆数据库的密码；&#8221;</span></p>
<p><span><span>5．&nbsp;</span></span><span>点击&#8220;应用程序&#8221;－》&#8220;应用程序设置&#8221;－》将左边显示的应用程序选中，然后在右边出现的几个框里将第二个&#8220;</span><span>WAR</span><span>类载入器策略&#8221;修改为&#8220;</span><span>APPLICATION</span><span>&#8221;</span></p>
<p><span><span>6．&nbsp;</span></span><span>最后一步是打开项目中的</span><span>WEB-INF</span><span>里的</span><span>web.xml</span><span>，在右边的透视图中点击&#8220;资源&#8221;，然后在&#8220;资源引用&#8221;一栏下选中显示的资源引用，然后确定在右边的&#8220;</span><span>WebSphere</span><span>&#8221;绑定中的&#8220;</span><span>JNDI</span><span>名称&#8221;中捆绑的是</span><span>JNDI</span><span>的名称（如：</span><span>jdbc/DataSource</span><span>）</span><span>。</span></p>
<img src ="http://www.blogjava.net/zilong/aggbug/112340.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2007-04-20 23:07 <a href="http://www.blogjava.net/zilong/archive/2007/04/20/112340.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在jsp中使用smartupload组件上传文件</title><link>http://www.blogjava.net/zilong/archive/2007/04/13/110433.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Fri, 13 Apr 2007 06:10:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2007/04/13/110433.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/110433.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2007/04/13/110433.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/110433.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/110433.html</trackback:ping><description><![CDATA[<h4 class=TextColor1 id=subjcns!198FF27B48654CC!277 style="MARGIN-BOTTOM: 0px">在jsp中使用smartupload组件上传文件[转]</h4>
<div id=msgcns!198FF27B48654CC!277>
<div><font size=3>jsp对上传文件的支持不象php中支持的那么好，直接做成了函数，也不象asp中要通过组件才能实现。jsp中可以通过javabean来实现。但是我们没有必要自己去写一个上载的bean，在网上已经有了很多成型的技术，smartupload就是其中的一个。但是smartupload是将文件先读到服务器的内存中，所以上传太大的文件（超过100兆）有可能会出问题，也算是一个美中不足吧：）</font>
<p align=left><font size=3>&nbsp;&nbsp; 先说一下提交的页面，smartupload组件要求用字节流的方式来提交&lt;FORM action="upload.jsp"&nbsp; encType=multipart/form-data method=post&gt;。下面就是个例子upload.htm：</font>
<p align=left><font size=3>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br>&lt;!-- saved from url=(0057)</font><a href="http://localhost:8080/jspsmartfile/jsp/uploadTemplate.jsp"><font color=#0000ff size=3><u>http://localhost:8080/jspsmartfile/jsp/uploadTemplate.jsp</u></font></a><font size=3> --&gt;<br>&lt;HTML&gt;&lt;HEAD&gt;<br>&lt;META content="text/html; charset=gb2312" http-equiv=Content-Type&gt;<br>&lt;META content="MSHTML 5.00.2920.0" name=GENERATOR&gt;&lt;/HEAD&gt;<br>&lt;BODY bgColor=#e6e6e6&gt;&lt;BR&gt;<br>&lt;FORM action="upload.jsp"&nbsp; encType=multipart/form-data method=post&gt;<br>&lt;TABLE&gt;<br>&nbsp; &lt;TBODY&gt;<br>&nbsp; &lt;TR&gt;<br>&nbsp;&nbsp;&nbsp; &lt;TD&gt;&lt;FONT color=#000000 face=helv,helvetica size=1&gt;&amp;nbsp;&amp;nbsp;File&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :&amp;nbsp;&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&lt;INPUT&nbsp; size=60 type=file&nbsp; name="file"&gt;&lt;/TD&gt;&lt;/TR&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TR&gt;<br>&nbsp;&nbsp;&nbsp; &lt;TR&gt;<br>&nbsp;&nbsp;&nbsp; &lt;TD&gt;&lt;FONT color=#000000 face=helv,helvetica size=1&gt;&amp;nbsp;&amp;nbsp;File&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :&amp;nbsp;&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&lt;INPUT&nbsp; size=60 type=file&nbsp; name="file1"&gt;&lt;/TD&gt;&lt;/TR&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TR&gt;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp; &lt;TD&gt;&lt;FONT color=#000000 face=helv,helvetica size=1&gt;&amp;nbsp;&amp;nbsp;File&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :&amp;nbsp;&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&lt;INPUT&nbsp; size=60 type=text&nbsp; name="text"&gt;&lt;/TD&gt;&lt;/TR&gt;<br>&nbsp; &lt;TR&gt;<br>&nbsp;&nbsp;&nbsp; &lt;TD <br>align=right&gt;&lt;INPUT type=submit value=Send name="send"&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/FORM&gt;&lt;/BODY&gt;&lt;/HTML&gt;</font>
<p align=left><font size=3>&nbsp; 再来看一下接收的页面 ，我们把文件上传到服务器以后就直接把它再存入数据库中：upload.jsp</font>
<p align=left><font size=3>&lt;%@ page contentType="text/html;charset=gb2312"%&gt;<br>&lt;%@ page import="java.sql.*"%&gt;<br>&lt;%@ page import="com.jspsmart.upload.*" %&gt;<br>&lt;%@ page import="DBstep.iDBManager2000.*"%&gt;<br>&lt;%<br>&nbsp;&nbsp;&nbsp;</font><a><font color=#0000ff size=3><u>//实</u></font></a><font size=3>例化上载bean<br>&nbsp;&nbsp;&nbsp; com.jspsmart.upload.SmartUpload mySmartUpload=new com.jspsmart.upload.SmartUpload();<br>&nbsp;&nbsp;&nbsp; </font><a><font color=#0000ff size=3><u>//初</u></font></a><font size=3>始化<br>&nbsp;&nbsp;&nbsp; mySmartUpload.initialize(pageContext);&nbsp;<br>&nbsp;&nbsp;&nbsp; </font><a><font color=#0000ff size=3><u>//设</u></font></a><font size=3>置上载的最大值<br>&nbsp;&nbsp;&nbsp; mySmartUpload.setMaxFileSize(500 * 1024*1024);<br>&nbsp;&nbsp;&nbsp; </font><a><font color=#0000ff size=3><u>//上</u></font></a><font size=3>载文件<br>&nbsp;&nbsp;&nbsp; mySmartUpload.upload();<br>&nbsp;&nbsp; </font><a><font color=#0000ff size=3><u>//循</u></font></a><font size=3>环取得所有上载的文件<br>&nbsp;&nbsp; for (int i=0;i&lt;mySmartUpload.getFiles().getCount();i++){<br>&nbsp;&nbsp; </font><a><font color=#0000ff size=3><u>//取</u></font></a><font size=3>得上载的文件<br>&nbsp;&nbsp; com.jspsmart.upload.File myFile = mySmartUpload.getFiles().getFile(i);<br>&nbsp;&nbsp; if (!myFile.isMissing())<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp; </font><a><font color=#0000ff size=3><u>//取</u></font></a><font size=3>得上载的文件的文件名<br>&nbsp;&nbsp;&nbsp; String myFileName=myFile.getFileName();<br>&nbsp;&nbsp;&nbsp; </font><a><font color=#0000ff size=3><u>//取</u></font></a><font size=3>得不带后缀的文件名<br>&nbsp;&nbsp;&nbsp; String&nbsp; suffix=myFileName.substring(0,myFileName.lastIndexOf('.'));<br>&nbsp;&nbsp;&nbsp; </font><a><font color=#0000ff size=3><u>//取</u></font></a><font size=3>得后缀名<br>&nbsp;&nbsp;&nbsp; String&nbsp; ext= mySmartUpload.getFiles().getFile(0).getFileExt();&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp; </font><a><font color=#0000ff size=3><u>//取</u></font></a><font size=3>得文件的大小&nbsp; <br>&nbsp;&nbsp;&nbsp; int fileSize=myFile.getSize();<br>&nbsp;&nbsp;&nbsp; </font><a><font color=#0000ff size=3><u>//保</u></font></a><font size=3>存路径<br>&nbsp;&nbsp;&nbsp; String aa=getServletContext().getRealPath("/")+"jsp\\";<br>&nbsp;&nbsp;&nbsp; String trace=aa+myFileName;<br>&nbsp;&nbsp;&nbsp; </font><a><font color=#0000ff size=3><u>//取</u></font></a><font size=3>得别的参数<br>&nbsp;&nbsp;&nbsp; String explain=(String)mySmartUpload.getRequest().getParameter("text");<br>&nbsp;&nbsp;&nbsp; String send=(String)mySmartUpload.getRequest().getParameter("send");<br>&nbsp;&nbsp;&nbsp; </font><a><font color=#0000ff size=3><u>//将</u></font></a><font size=3>文件保存在服务器端 <br>&nbsp;&nbsp;&nbsp; myFile.saveAs(trace,mySmartUpload.SAVE_PHYSICAL);<br>&nbsp;&nbsp;&nbsp; </font><a><font color=#0000ff size=3><u>//下</u></font></a><font size=3>面的是将上载的文件保存到数据库中<br>&nbsp;&nbsp;&nbsp; </font><a><font color=#0000ff size=3><u>//将</u></font></a><font size=3>文件读到流中 <br>&nbsp;&nbsp;&nbsp; java.io.File file = new java.io.File(trace);<br>&nbsp;&nbsp;&nbsp; java.io.FileInputStream fis = new java.io.FileInputStream(file);<br>&nbsp; out.println(file.length());<br>&nbsp;&nbsp; </font><a><font color=#0000ff size=3><u>//打</u></font></a><font size=3>开数据库<br>&nbsp;&nbsp; ResultSet result=null;<br>&nbsp;&nbsp; String mSql=null;<br>&nbsp;&nbsp; PreparedStatement prestmt=null; <br>&nbsp;&nbsp; DBstep.iDBManager2000 DbaObj=new DBstep.iDBManager2000();<br>&nbsp;&nbsp; DbaObj.OpenConnection();<br>&nbsp;&nbsp; </font><a><font color=#0000ff size=3><u>//将</u></font></a><font size=3>文件写到数据库中<br>&nbsp;&nbsp; mSql="insert into marklist (markname,password,marksize,markdate,MarkBody) values (?,?,?,?,?)";<br>&nbsp;&nbsp; prestmt =DbaObj.Conn.prepareStatement(mSql);<br>&nbsp;&nbsp; prestmt.setString(1, "aaa1");<br>&nbsp;&nbsp; prestmt.setString(2, "0000");<br>&nbsp;&nbsp; prestmt.setInt(3, fileSize);<br>&nbsp;&nbsp; prestmt.setString(4, DbaObj.GetDateTime());<br>&nbsp;&nbsp; prestmt.setBinaryStream(5,fis,(int)file.length());<br>&nbsp;&nbsp; DbaObj.Conn.setAutoCommit(true) ;<br>&nbsp;&nbsp; prestmt.executeUpdate();<br>&nbsp;&nbsp; DbaObj.Conn.commit();<br>&nbsp;&nbsp; out.println(("上载成功！！！").toString());<br>&nbsp;&nbsp; }<br>&nbsp;&nbsp; else <br>&nbsp;&nbsp; { out.println(("上载失败！！！").toString()); } <br>&nbsp;&nbsp; }//与前面的if对应<br>%&gt;</font>
<p align=left><font size=3>&nbsp;&nbsp; 再说一下下载，下载分两种情况1。从数据库直接下载2。从服务器上下载</font>
<p align=left><font size=3>&nbsp; 先说从数据库直接下载的情形：就是把输入流从数据库里读出来，然后转存为文件</font>
<p align=left><font size=3>&lt;%@ page contentType="text/html; charset=gb2312" %&gt;<br>&lt;%@ page import="java.sql.*"%&gt;<br>&lt;%@ page import="java.io.*" %&gt;<br>&lt;%@ page import="DBstep.iDBManager2000.*"%&gt;<br>&lt;%<br>&nbsp;&nbsp;&nbsp; int bytesum=0;<br>&nbsp;&nbsp;&nbsp; int byteread=0;<br>&nbsp; </font><a><font color=#0000ff size=3><u>//打</u></font></a><font size=3>开数据库<br>&nbsp; ResultSet result=null;<br>&nbsp; String Sql=null;<br>&nbsp; PreparedStatement prestmt=null; <br>&nbsp; DBstep.iDBManager2000 DbaObj=new DBstep.iDBManager2000();<br>&nbsp; DbaObj.OpenConnection();<br>&nbsp;</font><a><font color=#0000ff size=3><u>//取</u></font></a><font size=3>得数据库中的数据<br>&nbsp;Sql="select&nbsp; *&nbsp; from&nbsp; t_local_zhongzhuan ";<br>&nbsp;result=DbaObj.ExecuteQuery(Sql);<br>&nbsp;result.next();</font>
<p align=left><font size=3>&nbsp;</font><a><font color=#0000ff size=3><u>//将</u></font></a><font size=3>数据库中的数据读到流中 <br>InputStream inStream=result.getBinaryStream("content"); <br>FileOutputStream fs=new FileOutputStream( "c:/dffdsafd.doc");</font>
<p align=left><font size=3>&nbsp; byte[]&nbsp; buffer =new&nbsp; byte[1444];<br>int length;<br>&nbsp;&nbsp;&nbsp; while ((byteread=inStream.read(buffer))!=-1)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println("&lt;DT&gt;&lt;B&gt;"+byteread+"&lt;/B&gt;&lt;/DT&gt;");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bytesum+=byteread;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(bytesum);<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fs.write(buffer,0,byteread);<br>&nbsp;&nbsp;&nbsp;&nbsp; }<br>%&gt;</font>
<p align=left><font size=3>再说从服务器上下载的情形：</font>
<p align=left><font size=3>&lt;%@ page contentType="text/html; charset=gb2312" %&gt;<br>&lt;%@ page import="java.io.*" %&gt;<br>&lt;%<br>&nbsp; String fileName = "zsc104.swf".toString();<br></font><a><font color=#0000ff size=3><u>f//读</u></font></a><font size=3>到流中<br>InputStream inStream=new FileInputStream("c:/zsc104.swf");<br>&nbsp;</font><a><font color=#0000ff size=3><u>//设</u></font></a><font size=3>置输出的格式 <br>&nbsp; response.reset(); <br>&nbsp; response.setContentType("bin");<br>&nbsp; response.addHeader("Content-Disposition","attachment; filename=\"" + fileName + "\"");<br>&nbsp;</font><a><font color=#0000ff size=3><u>//循</u></font></a><font size=3>环取出流中的数据 <br>&nbsp; byte[] b = new byte[100]; <br>&nbsp; int len; <br>&nbsp; while((len=inStream.read(b)) &gt;0) <br>&nbsp; response.getOutputStream().write(b,0,len); &nbsp;<br>&nbsp; inStream.close(); <br>%&gt;</font>
<p align=left><font size=3>&nbsp;&nbsp; 好了，到这里只要不是太大的文件的上传下载的操作都可以完成了。</font></p>
</div>
</div>
<img src ="http://www.blogjava.net/zilong/aggbug/110433.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2007-04-13 14:10 <a href="http://www.blogjava.net/zilong/archive/2007/04/13/110433.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>页面中hidden属性的用法</title><link>http://www.blogjava.net/zilong/archive/2007/04/12/110246.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Thu, 12 Apr 2007 10:26:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2007/04/12/110246.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/110246.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2007/04/12/110246.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/110246.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/110246.html</trackback:ping><description><![CDATA[<p><br>在页面中先设置一个hidden来传递参数以便其他页面用request.getParameter()获得，</p>
<p>hidden必须写在窗体form中，而且另一个要得到它的页面必须是form中的action指向的页</p>
<p>面，不然得不到。切记！！！</p>
<img src ="http://www.blogjava.net/zilong/aggbug/110246.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2007-04-12 18:26 <a href="http://www.blogjava.net/zilong/archive/2007/04/12/110246.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何跳出页面的Frame框架</title><link>http://www.blogjava.net/zilong/archive/2007/04/04/108415.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Wed, 04 Apr 2007 05:24:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2007/04/04/108415.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/108415.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2007/04/04/108415.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/108415.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/108415.html</trackback:ping><description><![CDATA[<div class=cnt>
<p>很多网页都是框架结构的，在很多的情况下会通过按钮点击事件或链接，跳出框架转到其它界面。例如说点击&#8220;注销登录&#8221;返回到登录界面。</p>
<p>一、通过运行脚本跳出框架有以下几种写法：</p>
<p>1.　 &lt;script language = javascript&gt;window.open('Login.aspx','_top')&lt;/script&gt;"</p>
<p>2.&nbsp;　&lt;script language = javascript&gt;window.open('Login.aspx','_parent')&lt;/script&gt;"</p>
<p>3.　&lt;script language = javascript&gt;window.parent.location.href='login.aspx'&lt;/script&gt;</p>
<p>4.&nbsp;&nbsp;&nbsp; Response.Write("&lt;script&gt;window.parent.opener=null;window.top.close();&lt;/script&gt;")</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Response.Write("&lt;script&gt;window.open('index.aspx','');&lt;/script&gt;")</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这种方法会先关闭原框架窗口，再重新打开一个新的窗口。这在很多功能界面对浏览器进行了改变设置，而回到登陆界面又用缺省设置的情况下适用。</p>
<p>二、链接跳出框架</p>
<p>这种情况就很简单了，加上<strong><span style="COLOR: red"> target="_top"</span> </strong>属性就可以了。</p>
</div>
<br>
<img src ="http://www.blogjava.net/zilong/aggbug/108415.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2007-04-04 13:24 <a href="http://www.blogjava.net/zilong/archive/2007/04/04/108415.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]Hibernate  VS  iBATIS</title><link>http://www.blogjava.net/zilong/archive/2007/03/31/107606.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Sat, 31 Mar 2007 02:49:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2007/03/31/107606.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/107606.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2007/03/31/107606.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/107606.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/107606.html</trackback:ping><description><![CDATA[
		<div>
				<div>
						<div>
								<font size="2">
										<h1>
												<span lang="EN-US">
														<font face="Times New Roman">Hibernate<span>  </span>VS<span>  </span>iBATIS</font>
												</span>
										</h1>
										<p>
												<span style="FONT-FAMILY: 宋体">
														<font size="3">转之<a href="http://blog.csdn.net/chinaewolf/"><u><font color="#0000ff">ewolf的工作专栏</font></u></a></font>
												</span>
										</p>
										<h3>
												<span style="FONT-FAMILY: 宋体">
														<font size="5">简介</font>
												</span>
										</h3>
										<p>
												<font size="3">
														<span lang="EN-US">
																<font face="Times New Roman">Hibernate </font>
														</span>
														<span style="FONT-FAMILY: 宋体">是当前最流行的</span>
														<span lang="EN-US">
																<font face="Times New Roman">O/R mapping</font>
														</span>
														<span style="FONT-FAMILY: 宋体">框架，当前版本是</span>
														<span lang="EN-US">
																<font face="Times New Roman">3.05</font>
														</span>
														<span style="FONT-FAMILY: 宋体">。它出身于</span>
														<span lang="EN-US">
																<font face="Times New Roman">sf.net</font>
														</span>
														<span style="FONT-FAMILY: 宋体">，现在已经成为</span>
														<span lang="EN-US">
																<font face="Times New Roman">Jboss</font>
														</span>
														<span style="FONT-FAMILY: 宋体">的一部分了</span>
												</font>
										</p>
										<p>
												<span lang="EN-US">
														<font face="Times New Roman">
																<font size="3">
																		<p>
																		</p>
																</font>
														</font>
												</span>
										</p>
										<p>
										</p>
										<p>
												<font size="3">
														<span lang="EN-US">
																<font face="Times New Roman">iBATIS </font>
														</span>
														<span style="FONT-FAMILY: 宋体">是另外一种优秀的</span>
														<span lang="EN-US">
																<font face="Times New Roman">O/R mapping</font>
														</span>
														<span style="FONT-FAMILY: 宋体">框架，当前版本是</span>
														<span lang="EN-US">
																<font face="Times New Roman">2.0</font>
														</span>
														<span style="FONT-FAMILY: 宋体">。目前属于</span>
														<span lang="EN-US">
																<font face="Times New Roman">apache</font>
														</span>
														<span style="FONT-FAMILY: 宋体">的一个子项目了。</span>
												</font>
										</p>
										<p>
												<span lang="EN-US">
														<font face="Times New Roman">
																<font size="3">
																		<p>
																		</p>
																</font>
														</font>
												</span>
										</p>
										<p>
										</p>
										<p>
												<font size="3">
														<span style="FONT-FAMILY: 宋体">相对</span>
														<span lang="EN-US">
																<font face="Times New Roman">Hibernate</font>
														</span>
														<span style="FONT-FAMILY: 宋体">“</span>
														<span lang="EN-US">
																<font face="Times New Roman">O/R</font>
														</span>
														<span style="FONT-FAMILY: 宋体">”而言，</span>
														<span lang="EN-US">
																<font face="Times New Roman">iBATIS </font>
														</span>
														<span style="FONT-FAMILY: 宋体">是一种“</span>
														<span lang="EN-US">
																<font face="Times New Roman">Sql Mapping</font>
														</span>
														<span style="FONT-FAMILY: 宋体">”的</span>
														<span lang="EN-US">
																<font face="Times New Roman">ORM</font>
														</span>
														<span style="FONT-FAMILY: 宋体">实现。</span>
														<span lang="EN-US">
																<font face="Times New Roman">
																</font>
														</span>
												</font>
										</p>
										<p>
												<span lang="EN-US">
														<font face="Times New Roman">
																<font size="3">
																		<p>
																		</p>
																</font>
														</font>
												</span>
										</p>
										<p>
										</p>
										<p>
												<font size="3">
														<span lang="EN-US">
																<font face="Times New Roman">Hibernate</font>
														</span>
														<span style="FONT-FAMILY: 宋体">对数据库结构提供了较为完整的封装，</span>
														<span lang="EN-US">
																<font face="Times New Roman">Hibernate</font>
														</span>
														<span style="FONT-FAMILY: 宋体">的</span>
														<span lang="EN-US">
																<font face="Times New Roman">O/R Mapping</font>
														</span>
														<span style="FONT-FAMILY: 宋体">实现了</span>
														<span lang="EN-US">
																<font face="Times New Roman">POJO </font>
														</span>
														<span style="FONT-FAMILY: 宋体">和数据库表之间的映射，以及</span>
														<span lang="EN-US">
																<font face="Times New Roman">SQL </font>
														</span>
														<span style="FONT-FAMILY: 宋体">的自动生成和执行。程序员往往只需定义好了</span>
														<span lang="EN-US">
																<font face="Times New Roman">POJO </font>
														</span>
														<span style="FONT-FAMILY: 宋体">到数据库表的映射关系，即可通过</span>
														<span lang="EN-US">
																<font face="Times New Roman">Hibernate </font>
														</span>
														<span style="FONT-FAMILY: 宋体">提供的方法完成持久层操作。程序员甚至不需要对</span>
														<span lang="EN-US">
																<font face="Times New Roman">SQL </font>
														</span>
														<span style="FONT-FAMILY: 宋体">的熟练掌握，</span>
														<span lang="EN-US">
																<font face="Times New Roman"> Hibernate/OJB </font>
														</span>
														<span style="FONT-FAMILY: 宋体">会根据制定的存储逻辑，自动生成对应的</span>
														<span lang="EN-US">
																<font face="Times New Roman">SQL </font>
														</span>
														<span style="FONT-FAMILY: 宋体">并调用</span>
														<span lang="EN-US">
																<font face="Times New Roman">JDBC </font>
														</span>
														<span style="FONT-FAMILY: 宋体">接口加以执行。</span>
												</font>
										</p>
										<p>
												<span lang="EN-US">
														<font face="Times New Roman">
																<font size="3">
																		<p>
																		</p>
																</font>
														</font>
												</span>
										</p>
										<p>
										</p>
										<p>
												<font size="3">
														<span style="FONT-FAMILY: 宋体">而</span>
														<span lang="EN-US">
																<font face="Times New Roman">iBATIS </font>
														</span>
														<span style="FONT-FAMILY: 宋体">的着力点，则在于</span>
														<span lang="EN-US">
																<font face="Times New Roman">POJO </font>
														</span>
														<span style="FONT-FAMILY: 宋体">与</span>
														<span lang="EN-US">
																<font face="Times New Roman">SQL</font>
														</span>
														<span style="FONT-FAMILY: 宋体">之间的映射关系。也就是说，</span>
														<span lang="EN-US">
																<font face="Times New Roman">iBATIS</font>
														</span>
														<span style="FONT-FAMILY: 宋体">并不会为程序员在运行期自动生成</span>
														<span lang="EN-US">
																<font face="Times New Roman">SQL </font>
														</span>
														<span style="FONT-FAMILY: 宋体">执行。具体的</span>
														<span lang="EN-US">
																<font face="Times New Roman">SQL </font>
														</span>
														<span style="FONT-FAMILY: 宋体">需要程序员编写，然后通过映射配置文件，将</span>
														<span lang="EN-US">
																<font face="Times New Roman">SQL</font>
														</span>
														<span style="FONT-FAMILY: 宋体">所需的参数，以及返回的结果字段映射到指定</span>
														<span lang="EN-US">
																<font face="Times New Roman">POJO</font>
														</span>
														<span style="FONT-FAMILY: 宋体">。</span>
												</font>
										</p>
										<p>
												<font size="3">
														<span style="FONT-FAMILY: 宋体">使用</span>
														<span lang="EN-US">
																<font face="Times New Roman">iBATIS </font>
														</span>
														<span style="FONT-FAMILY: 宋体">提供的</span>
														<span lang="EN-US">
																<font face="Times New Roman">ORM</font>
														</span>
														<span style="FONT-FAMILY: 宋体">机制，对业务逻辑实现人员而言，面对的是纯粹的</span>
														<span lang="EN-US">
																<font face="Times New Roman">Java</font>
														</span>
														<span style="FONT-FAMILY: 宋体">对象，</span>
												</font>
										</p>
										<p>
												<font size="3">
														<span style="FONT-FAMILY: 宋体">这一层与通过</span>
														<span lang="EN-US">
																<font face="Times New Roman">Hibernate </font>
														</span>
														<span style="FONT-FAMILY: 宋体">实现</span>
														<span lang="EN-US">
																<font face="Times New Roman">ORM </font>
														</span>
														<span style="FONT-FAMILY: 宋体">而言基本一致，而对于具体的数据操作，</span>
														<span lang="EN-US">
																<font face="Times New Roman">Hibernate</font>
														</span>
														<span style="FONT-FAMILY: 宋体">会自动生成</span>
														<span lang="EN-US">
																<font face="Times New Roman">SQL </font>
														</span>
														<span style="FONT-FAMILY: 宋体">语句，而</span>
														<span lang="EN-US">
																<font face="Times New Roman">iBATIS </font>
														</span>
														<span style="FONT-FAMILY: 宋体">则要求开发者编写具体的</span>
														<span lang="EN-US">
																<font face="Times New Roman">SQL </font>
														</span>
														<span style="FONT-FAMILY: 宋体">语句。相对</span>
														<span lang="EN-US">
																<font face="Times New Roman">Hibernate</font>
														</span>
														<span style="FONT-FAMILY: 宋体">而言，</span>
														<span lang="EN-US">
																<font face="Times New Roman">iBATIS </font>
														</span>
														<span style="FONT-FAMILY: 宋体">以</span>
														<span lang="EN-US">
																<font face="Times New Roman">SQL</font>
														</span>
														<span style="FONT-FAMILY: 宋体">开发的工作量和数据库移植性上的让步，为系统设计提供了更大的自由空间。</span>
												</font>
										</p>
										<p>
												<span lang="EN-US">
														<font size="3">
																<font face="Times New Roman">
																		<p>
																		</p>
																</font>
														</font>
												</span>
										</p>
										<p>
										</p>
										<h3>
												<span style="FONT-FAMILY: 宋体">
														<font size="5">二者的对比：</font>
												</span>
										</h3>
										<p style="TEXT-INDENT: -18pt; tab-stops: list 18.0pt">
												<font face="Times New Roman">
														<span lang="EN-US">
																<font size="3">1．</font>
																<span style="FONT: 7pt 'Times New Roman'">  </span>
														</span>
														<span lang="EN-US">
																<font size="3">iBATIS</font>
														</span>
												</font>
												<font size="3">
														<span style="FONT-FAMILY: 宋体">非常简单易学，</span>
														<span lang="EN-US">
																<font face="Times New Roman">Hibernate</font>
														</span>
														<span style="FONT-FAMILY: 宋体">相对较复杂，门槛较高。</span>
												</font>
										</p>
										<p style="TEXT-INDENT: -18pt; tab-stops: list 18.0pt">
												<span lang="EN-US">
														<font face="Times New Roman">
																<font size="3">2．</font>
																<span style="FONT: 7pt 'Times New Roman'">  </span>
														</font>
												</span>
												<span style="FONT-FAMILY: 宋体">
														<font size="3">二者都是比较优秀的开源产品</font>
												</span>
										</p>
										<p style="TEXT-INDENT: -18pt; tab-stops: list 18.0pt">
												<span lang="EN-US">
														<font face="Times New Roman">
																<font size="3">3．</font>
																<span style="FONT: 7pt 'Times New Roman'">  </span>
														</font>
												</span>
												<font size="3">
														<span style="FONT-FAMILY: 宋体">当系统属于二次开发</span>
														<span lang="EN-US">
																<font face="Times New Roman">,</font>
														</span>
														<span style="FONT-FAMILY: 宋体">无法对数据库结构做到控制和修改</span>
														<span lang="EN-US">
																<font face="Times New Roman">,</font>
														</span>
														<span style="FONT-FAMILY: 宋体">那</span>
														<span lang="EN-US">
																<font face="Times New Roman">iBATIS</font>
														</span>
														<span style="FONT-FAMILY: 宋体">的灵活性将比</span>
														<span lang="EN-US">
																<font face="Times New Roman">Hibernate</font>
														</span>
														<span style="FONT-FAMILY: 宋体">更适合</span>
												</font>
										</p>
										<p style="TEXT-INDENT: -18pt; tab-stops: list 18.0pt">
												<span lang="EN-US">
														<font face="Times New Roman">
																<font size="3">4．</font>
																<span style="FONT: 7pt 'Times New Roman'">  </span>
														</font>
												</span>
												<font size="3">
														<span style="FONT-FAMILY: 宋体">系统数据处理量巨大，性能要求极为苛刻，这往往意味着我们必须通过经过高度优化的</span>
														<span lang="EN-US">
																<font face="Times New Roman">SQL</font>
														</span>
														<span style="FONT-FAMILY: 宋体">语句（或存储过程）才能达到系统性能设计指标。在这种情况下</span>
														<span lang="EN-US">
																<font face="Times New Roman">iBATIS</font>
														</span>
														<span style="FONT-FAMILY: 宋体">会有更好的可控性和表现。</span>
												</font>
										</p>
										<p style="TEXT-INDENT: -18pt; tab-stops: list 18.0pt">
												<font face="Times New Roman">
														<span lang="EN-US">
																<font size="3">5．</font>
																<span style="FONT: 7pt 'Times New Roman'">  </span>
														</span>
														<span lang="EN-US">
																<font size="3">iBATIS</font>
														</span>
												</font>
												<font size="3">
														<span style="FONT-FAMILY: 宋体">需要手写</span>
														<span lang="EN-US">
																<font face="Times New Roman">sql</font>
														</span>
														<span style="FONT-FAMILY: 宋体">语句，也可以生成一部分，</span>
														<span lang="EN-US">
																<font face="Times New Roman">Hibernate</font>
														</span>
														<span style="FONT-FAMILY: 宋体">则基本上可以自动生成，偶尔会写一些</span>
														<span lang="EN-US">
																<font face="Times New Roman">Hql</font>
														</span>
														<span style="FONT-FAMILY: 宋体">。同样的需求</span>
														<span lang="EN-US">
																<font face="Times New Roman">,iBATIS</font>
														</span>
														<span style="FONT-FAMILY: 宋体">的工作量比</span>
														<span lang="EN-US">
																<font face="Times New Roman">Hibernate</font>
														</span>
														<span style="FONT-FAMILY: 宋体">要大很多。类似的，如果涉及到数据库字段的修改，</span>
														<span lang="EN-US">
																<font face="Times New Roman">Hibernate</font>
														</span>
														<span style="FONT-FAMILY: 宋体">修改的地方很少，而</span>
														<span lang="EN-US">
																<font face="Times New Roman">iBATIS</font>
														</span>
														<span style="FONT-FAMILY: 宋体">要把那些</span>
														<span lang="EN-US">
																<font face="Times New Roman">sql mapping</font>
														</span>
														<span style="FONT-FAMILY: 宋体">的地方一一修改。</span>
												</font>
										</p>
										<p style="TEXT-INDENT: -18pt; tab-stops: list 18.0pt">
												<span lang="EN-US">
														<font face="Times New Roman">
																<font size="3">6．</font>
																<span style="FONT: 7pt 'Times New Roman'">  </span>
														</font>
												</span>
												<font size="3">
														<span style="FONT-FAMILY: 宋体">以数据库字段一一对应映射得到的</span>
														<span lang="EN-US">
																<font face="Times New Roman">PO</font>
														</span>
														<span style="FONT-FAMILY: 宋体">和</span>
														<span lang="EN-US">
																<font face="Times New Roman">Hibernte</font>
														</span>
														<span style="FONT-FAMILY: 宋体">这种对象化映射得到的</span>
														<span lang="EN-US">
																<font face="Times New Roman">PO</font>
														</span>
														<span style="FONT-FAMILY: 宋体">是截然不同的，本质区别在于这种</span>
														<span lang="EN-US">
																<font face="Times New Roman">PO</font>
														</span>
														<span style="FONT-FAMILY: 宋体">是扁平化的，不像</span>
														<span lang="EN-US">
																<font face="Times New Roman">Hibernate</font>
														</span>
														<span style="FONT-FAMILY: 宋体">映射的</span>
														<span lang="EN-US">
																<font face="Times New Roman">PO</font>
														</span>
														<span style="FONT-FAMILY: 宋体">是可以表达立体的对象继承，聚合等等关系的，这将会直接影响到你的整个软件系统的设计思路。</span>
												</font>
										</p>
										<p style="TEXT-INDENT: -18pt; tab-stops: list 18.0pt">
												<font face="Times New Roman">
														<span lang="EN-US">
																<font size="3">7．</font>
																<span style="FONT: 7pt 'Times New Roman'">  </span>
														</span>
														<span lang="EN-US">
																<font size="3">Hibernate</font>
														</span>
												</font>
												<font size="3">
														<span style="FONT-FAMILY: 宋体">现在已经是主流</span>
														<span lang="EN-US">
																<font face="Times New Roman">O/R Mapping</font>
														</span>
														<span style="FONT-FAMILY: 宋体">框架，从文档的丰富性，产品的完善性，版本的开发速度都要强于</span>
														<span lang="EN-US">
																<font face="Times New Roman">iBATIS</font>
														</span>
												</font>
										</p>
										<p style="TEXT-INDENT: -18pt; tab-stops: list 18.0pt">
												<span lang="EN-US">
														<font face="Times New Roman">
																<font size="3">8．</font>
																<span style="FONT: 7pt 'Times New Roman'">  </span>
														</font>
												</span>
												<font size="3">
														<span style="FONT-FAMILY: 宋体">最关键的一句话是</span>
														<span lang="EN-US">
																<font face="Times New Roman">iBATIS</font>
														</span>
														<span style="FONT-FAMILY: 宋体">的作者说的：</span>
												</font>
										</p>
										<p>
												<span lang="EN-US">
														<font face="Times New Roman" size="3">If you are starting a new project and you're in full control of your object model and database design, Hibernate is a good choice of O/R tool.</font>
												</span>
										</p>
										<p>
												<span lang="EN-US">
														<font face="Times New Roman" size="3">If you are accessing any 3rd party databases (e.g. vendor supplied), or you're working with a legacy database, or even just a really poorly designed database, then an O/R mapper might not be capable of handling the situation. That's were an SQL Mapper comes in handy</font>
												</span>
												<span lang="EN-US">
														<font face="Times New Roman" size="3">
																<font size="2">
																		<h3> </h3>
																		<h3>
																				<span lang="EN-US">结论:</span>
																		</h3>
																</font>
																<span lang="EN-US">结论:</span>
																<p>
																		<span lang="EN-US">Hibernate 和iBATIS可以说是互相补充,共同发展的关系.具体你想用什么要看实际情况.如果看了上面的文字还是拿不定注意,那就Just to try it.实践是检验真理的唯一标准.鞋合不合适,只有试了才知道</span>
																</p>
														</font>
												</span>
										</p>
								</font>
								<br />
								<br />
								<p>Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=413018<br /></p>
						</div>
				</div>
		</div>
		<img height="1" alt="" src="http://c.services.spaces.live.com/CollectionWebService/c.gif?space=21958978&amp;page=RSS%ef%bc%9aHibernate++VS++iBATIS&amp;referrer=" width="1" border="0" />
		<img style="POSITION: absolute" height="0px" alt="" src="http://c.live.com/c.gif?NC=31263&amp;NA=1149&amp;PI=81873&amp;RF=&amp;DI=3919&amp;PS=85545&amp;TP=21958978.spaces.live.com&amp;GT1=21958978;2052" width="0px" />
		<br />文章来源:<a href="http://21958978.spaces.live.com/Blog/cns!A7DF246804AD47BB!195.entry">http://21958978.spaces.live.com/Blog/cns!A7DF246804AD47BB!195.entry</a><img src ="http://www.blogjava.net/zilong/aggbug/107606.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2007-03-31 10:49 <a href="http://www.blogjava.net/zilong/archive/2007/03/31/107606.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]iBatis：O/R Mapping解决方案</title><link>http://www.blogjava.net/zilong/archive/2007/03/31/107605.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Sat, 31 Mar 2007 02:49:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2007/03/31/107605.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/107605.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2007/03/31/107605.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/107605.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/107605.html</trackback:ping><description><![CDATA[
		<div>
				<div>
						<div>
								<a href="http://blog.csdn.net/lixinye0123/archive/2006/04/19/669112.aspx">
										<img height="13" src="http://21958978.spaces.live.com/images/zhuan.gif" width="15" border="0" />
										<u>
												<font color="#800080"> iBatis：O/R Mapping解决方案</font>
										</u>
								</a>
						</div>
						<p>j2ee的O/R方案真是多，和Hibernate相比，iBatis最大的特点就是小巧，上手很快。看iBatis的文档2小时就会用了，这个O/R Mapping特点就是简单易用。只要有SQL基础，相信你不用教程也能看明白。最新版本2.0（<a href="http://www.ibatis.com/common/download.html"><u><font color="#0000ff">下载</font></u></a>）。 
</p>
						<p>构建ibatis基础代码<br />ibatis 基础代码包括： 
</p>
						<p>
								<br />1． ibatis 实例配置<br />一个典型的配置文件如下（具体配置项目的含义见后）：<br />&lt;?xml version="1.0" encoding="UTF-8" ?&gt;<br />&lt;!DOCTYPE sqlMapConfig<br />PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"<br />"<a href="http://www.ibatis.com/dtd/sql-map-config-2.dtd"><u><font color="#0000ff">http://www.ibatis.com/dtd/sql-map-config-2.dtd</font></u></a>"&gt;<br />&lt;sqlMapConfig&gt;<br />&lt;settings<br />cacheModelsEnabled="true"<br />enhancementEnabled="true"<br />lazyLoadingEnabled="true"<br />errorTracingEnabled="true"<br />maxRequests="32"<br />maxSessions="10"<br />maxTransactions="5"<br />useStatementNamespaces="false"<br />/&gt;<br />&lt;transactionManager type="JDBC"&gt;<br />IBATIS Developer’s Guide Version 1.0<br />September 2, 2004 So many open source projects. Why not Open your Documents?<br />&lt;dataSource type="SIMPLE"&gt;<br />&lt;property name="JDBC.Driver"<br />value="com.p6spy.engine.spy.P6SpyDriver"/&gt;<br />&lt;property name="JDBC.ConnectionURL"<br />value="jdbc:mysql://localhost/sample"/&gt;<br />&lt;property name="JDBC.Username" value="user"/&gt;<br />&lt;property name="JDBC.Password" value="mypass"/&gt;<br />&lt;property name="Pool.MaximumActiveConnections"<br />value="10"/&gt;<br />&lt;property name="Pool.MaximumIdleConnections" value="5"/&gt;<br />&lt;property name="Pool.MaximumCheckoutTime"<br />value="120000"/&gt;<br />&lt;property name="Pool.TimeToWait" value="500"/&gt;<br />&lt;property name="Pool.PingQuery" value="select 1 from<br />ACCOUNT"/&gt;<br />&lt;property name="Pool.PingEnabled" value="false"/&gt;<br />&lt;property name="Pool.PingConnectionsOlderThan"<br />value="1"/&gt;<br />&lt;property name="Pool.PingConnectionsNotUsedFor"<br />value="1"/&gt;<br />&lt;/dataSource&gt;<br />&lt;/transactionManager&gt;<br />&lt;sqlMap resource="com/ibatis/sample/User.xml"/&gt;<br />&lt;/sqlMapConfig&gt; 
</p>
						<p>
								<br />2． POJO（Plain Ordinary Java Object）<br />下面是我们用作示例的一个POJO:<br />public class User implements Serializable {<br />private Integer id;<br />private String name;<br />private Integer sex;<br />private Set addresses = new HashSet();<br />/** default constructor */<br />public User() {<br />}<br />public Integer getId() {<br />return this.id;<br />IBATIS Developer’s Guide Version 1.0<br />September 2, 2004 So many open source projects. Why not Open your Documents?<br />}<br />public void setId(Integer id) {<br />this.id = id;<br />}<br />public String getName() {<br />return this.name;<br />}<br />public void setName(String name) {<br />this.name = name;<br />}<br />public Integer getSex() {<br />return this.sex;<br />}<br />public void setSex(Integer sex) {<br />this.sex = sex;<br />}<br />} 
</p>
						<div>
								<br />3． 映射文件<br />与Hibernate 不同。因为需要人工编写SQL 代码，ibatis 的映射文件一般采<br />用手动编写（通过Copy/Paste，手工编写映射文件也并没想象中的麻烦）。<br />针对上面POJO 的映射代码如下：<br />&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;!DOCTYPE sqlMap<br />PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"<br />"<a href="http://www.ibatis.com/dtd/sql-map-2.dtd"><u><font color="#0000ff">http://www.ibatis.com/dtd/sql-map-2.dtd</font></u></a>"&gt;<br />&lt;sqlMap namespace="User"&gt;<br />&lt;typeAlias alias="user" type="com.ibatis.sample.User"/&gt;<br />&lt;select id="getUser"<br />parameterClass="java.lang.String"<br />resultClass="user"&gt;<br />&lt;![CDATA[<br />select<br />name,<br />sex<br />from t_user<br />IBATIS Developer’s Guide Version 1.0<br />September 2, 2004 So many open source projects. Why not Open your Documents?<br />where name = #name#<br />]]&gt;<br />&lt;/select&gt;<br />&lt;update id="updateUser"<br />parameterClass="user"&gt;<br />&lt;![CDATA[<br />UPDATE t_user<br />SET<br />name=#name#,<br />sex=#sex#<br />WHERE id = #id#<br />]]&gt;<br />&lt;/update&gt;<br />&lt;insert id="insertUser"<br />parameterClass="user"<br />&gt;<br />INSERT INTO t_user (<br />name,<br />sex)<br />VALUES (<br />#name#,<br />#sex#<br />)<br />&lt;/insert&gt;<br />&lt;delete id="deleteUser"<br />parameterClass="java.lang.String"&gt;<br />delete from t_user<br />where id = #value#<br />&lt;/delete&gt;<br />&lt;/sqlMap&gt;<br />从上面的映射文件可以看出，通过&lt;insert&gt;、&lt;delete&gt;、&lt;update&gt;、<br />&lt;select&gt;四个节点，我们分别定义了针对TUser 对象的增删改查操作。在这<br />四个节点中，我们指定了对应的SQL 语句，以update节点为例：<br />……<br />&lt;update id="updateUser" ⑴<br />parameterClass="user"&gt; ⑵<br />&lt;![CDATA[ ⑶<br />UPDATE t_user ⑷<br />SET (<br />IBATIS Developer’s Guide Version 1.0<br />September 2, 2004 So many open source projects. Why not Open your Documents?<br />name=#name#, ⑸<br />sex=#sex# ⑹<br />)<br />WHERE id = #id# ⑺<br />]]&gt;<br />&lt;/update&gt;<br />……<br /><br />⑴ ID<br />指定了操作ID，之后我们可以在代码中通过指定操作id 来执行此节点所定<br />义的操作，如：<br />sqlMap.update("updateUser",user);<br />ID设定使得在一个配置文件中定义两个同名节点成为可能（两个update节<br />点，以不同id区分）<br /><br />⑵ parameterClass<br />指定了操作所需的参数类型， 此例中update 操作以<br />com.ibatis.sample.User 类型的对象作为参数，目标是将提供的User<br />实例更新到数据库。<br />parameterClass="user"中，user为“com.ibatis.sample.User”<br />类的别名，别名可通过typeAlias节点指定，如示例配置文件中的：<br />&lt;typeAlias alias="user" type="com.ibatis.sample.User"/&gt;<br /><br />⑶ &lt;![CDATA[……]]&gt;<br />通过&lt;![CDATA[……]]&gt;节点，可以避免SQL 中与XML 规范相冲突的字符对<br />XML映射文件的合法性造成影响。<br /><br />⑷ 执行更新操作的SQL，这里的SQL 即实际数据库支持的SQL 语句，将由<br />ibatis填入参数后交给数据库执行。<br /><br />⑸ SQL中所需的用户名参数，“#name#”在运行期会由传入的user对象的name<br />属性填充。<br /><br />⑹ SQL 中所需的用户性别参数“#sex#”，将在运行期由传入的user 对象的<br />sex属性填充。<br /><br />⑺ SQL中所需的条件参数“#id#”，将在运行期由传入的user对象的id属性<br />填充。<br /><br />对于这个示例，ibatis在运行期会读取id 为“updateUser”的update节点<br />的SQL定义，并调用指定的user对象的对应getter方法获取属性值，并用此<br />属性值，对SQL中的参数进行填充后提交数据库执行。<br />此例对应的应用级代码如下，其中演示了ibatis SQLMap的基本使用方法：<br />String resource ="com/ibatis/sample/SqlMapConfig.xml";<br />Reader reader;<br />reader = Resources.getResourceAsReader(resource);<br /><font style="BACKGROUND-COLOR: #ffff00">XmlSqlMapClientBuilder xmlBuilder =<br />new XmlSqlMapClientBuilder();<br />SqlMapClient sqlMap = xmlBuilder.buildSqlMap(reader);</font></div>
						<div>
								<font style="BACKGROUND-COLOR: #ffff00">（上面代码调试不过可用一下代码代替：</font>
						</div>
						<div>
								<font style="BACKGROUND-COLOR: #00ff00">Reader reader = Resources.getResourceAsReader( resource );<br />  SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);）<br /></font>//sqlMap系统初始化完毕，开始执行update操作<br />try{<br />sqlMap.startTransaction();<br />User user = new User();<br />user.setId(new Integer(1));<br />user.setName("Erica");<br />user.setSex(new Integer(1));<br />sqlMap.update("updateUser",user);<br />sqlMap.commitTransaction();<br />finally{<br />sqlMap.endTransaction();<br />}<br />其中，SqlMapClient是ibatis运作的核心，所有操作均通过SqlMapClient<br />实例完成。<br />可以看出，对于应用层而言，程序员面对的是传统意义上的数据对象，而非JDBC<br />中烦杂的ResultSet，这使得上层逻辑开发人员的工作量大大减轻，同时代码更<br />加清晰简洁。<br />数据库操作在映射文件中加以定义，从而将数据存储逻辑从上层逻辑代码中独立<br />出来。<br />而底层数据操作的SQL可配置化，使得我们可以控制最终的数据操作方式，通过<br />SQL的优化获得最佳的数据库执行效能，这在依赖SQL自动生成的“全自动”ORM<br />机制中是所难以实现的。<br />IBATIS Developer’s Guide Version 1.0<br />September 2, 2004 So many open source projects. Why not Open your Documents?<br />ibatis配置<br />结合上面示例中的ibatis配置文件。下面是对配置文件中各节点的说明：<br />&lt;?xml version="1.0" encoding="UTF-8" ?&gt;<br />&lt;!DOCTYPE sqlMapConfig<br />PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"<br />"<a href="http://www.ibatis.com/dtd/sql-map-config-2.dtd"><u><font color="#0000ff">http://www.ibatis.com/dtd/sql-map-config-2.dtd</font></u></a>"&gt;<br />&lt;sqlMapConfig&gt;<br />&lt;settings ⑴<br />cacheModelsEnabled="true"<br />enhancementEnabled="true"<br />lazyLoadingEnabled="true"<br />errorTracingEnabled="true"<br />maxRequests="32"<br />maxSessions="10"<br />maxTransactions="5"<br />useStatementNamespaces="false"<br />/&gt;<br />&lt;transactionManager type="JDBC"&gt; ⑵<br />&lt;dataSource type="SIMPLE"&gt; ⑶<br />&lt;property name="JDBC.Driver"<br />value="com.p6spy.engine.spy.P6SpyDriver"/&gt;<br />&lt;property name="JDBC.ConnectionURL"<br />value="jdbc:mysql://localhost/sample"/&gt;<br />&lt;property name="JDBC.Username" value="user"/&gt;<br />&lt;property name="JDBC.Password" value="mypass"/&gt;<br />&lt;property name="Pool.MaximumActiveConnections"<br />value="10"/&gt;<br />&lt;property name="Pool.MaximumIdleConnections" value="5"/&gt;<br />&lt;property name="Pool.MaximumCheckoutTime"<br />value="120000"/&gt;<br />&lt;property name="Pool.TimeToWait" value="500"/&gt;<br />&lt;property name="Pool.PingQuery" value="select 1 from<br />ACCOUNT"/&gt;<br />&lt;property name="Pool.PingEnabled" value="false"/&gt;<br />&lt;property name="Pool.PingConnectionsOlderThan"<br />value="1"/&gt;<br />&lt;property name="Pool.PingConnectionsNotUsedFor"<br />value="1"/&gt;<br />&lt;/dataSource&gt;<br />IBATIS Developer’s Guide Version 1.0<br />September 2, 2004 So many open source projects. Why not Open your Documents?<br />&lt;/transactionManager&gt;<br />&lt;sqlMap resource="com/ibatis/sample/User.xml"/&gt; ⑷<br />&lt;sqlMap resource="com/ibatis/sample/Address.xml"/&gt;<br />&lt;/sqlMapConfig&gt;<br /><br />⑴ Settings 节点<br />参数 描述<br />cacheModelsEnabled 是否启用SqlMapClient上的缓存机制。<br />建议设为"true"<br />enhancementEnabled 是否针对POJO启用字节码增强机制以提升<br />getter/setter的调用效能，避免使用Java<br />Reflect所带来的性能开销。<br />同时，这也为Lazy Loading带来了极大的性能<br />提升。<br />建议设为"true"<br />errorTracingEnabled 是否启用错误日志，在开发期间建议设为"true"<br />以方便调试<br />lazyLoadingEnabled 是否启用延迟加载机制，建议设为"true"<br />maxRequests 最大并发请求数（Statement并发数）<br />maxTransactions 最大并发事务数<br />maxSessions 最大Session 数。即当前最大允许的并发<br />SqlMapClient数。<br />maxSessions设定必须介于<br />maxTransactions和maxRequests之间，即<br />maxTransactions&lt;maxSessions=&lt;<br />maxRequests<br />useStatementNamespaces 是否使用Statement命名空间。<br />这里的命名空间指的是映射文件中，sqlMap节点<br />的namespace属性，如在上例中针对t_user<br />表的映射文件sqlMap节点：<br />&lt;sqlMap namespace="User"&gt;<br />这里，指定了此sqlMap节点下定义的操作均从<br />属于"User"命名空间。<br />在useStatementNamespaces="true"的情<br />况下，Statement调用需追加命名空间，如：<br />IBATIS Developer’s Guide Version 1.0<br />September 2, 2004 So many open source projects. Why not Open your Documents?<br />sqlMap.update("User.updateUser",use<br />r);<br />否则直接通过Statement名称调用即可，如：<br />sqlMap.update("updateUser",user);<br />但请注意此时需要保证所有映射文件中，<br />Statement定义无重名。<br /><br />⑵ transactionManager节点<br />transactionManager 节点定义了ibatis 的事务管理器，目前提供了以下几<br />种选择：<br />Ø JDBC<br />通过传统JDBC Connection.commit/rollback实现事务支持。<br />Ø JTA<br />使用容器提供的JTA服务实现全局事务管理。<br />Ø EXTERNAL<br />外部事务管理，如在EJB中使用ibatis，通过EJB的部署配置即可实现自<br />动的事务管理机制。此时ibatis 将把所有事务委托给外部容器进行管理。<br />此外，通过Spring 等轻量级容器实现事务的配置化管理也是一个不错的选<br />择。关于结合容器实现事务管理，参见“高级特性”中的描述。<br /><br />⑶ dataSource节点<br />dataSource从属于transactionManager节点，用于设定ibatis运行期使<br />用的DataSource属性。<br />type属性： dataSource节点的type属性指定了dataSource的实现类型。<br />可选项目：<br />Ø SIMPLE：<br />SIMPLE是ibatis内置的dataSource实现，其中实现了一个简单的<br />数据库连接池机制， 对应ibatis 实现类为<br />com.ibatis.sqlmap.engine.datasource.SimpleDataSourceFactory。<br />Ø DBCP:<br />基于Apache DBCP 连接池组件实现的DataSource 封装，当无容器提<br />供DataSource 服务时，建议使用该选项，对应ibatis 实现类为<br />com.ibatis.sqlmap.engine.datasource.DbcpDataSourceFactory。<br />Ø JNDI：<br />使用J2EE 容器提供的DataSource 实现，DataSource 将通过指定<br />的JNDI Name 从容器中获取。对应ibatis 实现类为<br />com.ibatis.sqlmap.engine.datasource.JndiDataSourceFacto<br />ry。<br />dataSource的子节点说明（SIMPLE&amp;DBCP）：<br />IBATIS Developer’s Guide Version 1.0<br />September 2, 2004 So many open source projects. Why not Open your Documents?<br />参数 描述<br />JDBC.Driver JDBC 驱动。<br />如：org.gjt.mm.mysql.Driver<br />JDBC.ConnectionURL 数据库URL。<br />如：jdbc:mysql://localhost/sample<br /><strong><font style="BACKGROUND-COLOR: #ffff00">如果用的是SQLServer JDBC Driver，需要<br />在url后追加<font color="#0000ff">SelectMethod=Cursor</font>以获得<br />JDBC事务的多Statement支持。<br /></font></strong>JDBC.Username 数据库用户名<br />JDBC.Password 数据库用户密码<br />Pool.MaximumActiveConn<br />ections<br />数据库连接池可维持的最大容量。<br />Pool.MaximumIdleConnec<br />tions<br />数据库连接池中允许的挂起（idle）连接数。<br />以上子节点适用于SIMPLE 和DBCP 模式，分别针对SIMPLE 和DBCP 模式的<br />DataSource私有配置节点如下：<br />SIMPLE:<br />参数 描述<br />Pool.MaximumCheckoutTi<br />me<br />数据库联接池中，连接被某个任务所允许占用的<br />最大时间，如果超过这个时间限定，连接将被强<br />制收回。（毫秒）<br />Pool.TimeToWait 当线程试图从连接池中获取连接时，连接池中无<br />可用连接可供使用，此时线程将进入等待状态，<br />直到池中出现空闲连接。此参数设定了线程所允<br />许等待的最长时间。（毫秒）<br />Pool.PingQuery 数据库连接状态检测语句。<br />某些数据库在连接在某段时间持续处于空闲状态<br />时会将其断开。而连接池管理器将通过此语句检<br />测池中连接是否可用。<br />检测语句应该是一个最简化的无逻辑SQL。<br />如“select 1 from t_user”，如果执行此语句<br />成功，连接池管理器将认为此连接处于可用状态。<br />Pool.PingEnabled 是否允许检测连接状态。<br />Pool.PingConnectionsOl<br />derThan<br />对持续连接时间超过设定值（毫秒）的连接进行<br />检测。<br />IBATIS Developer’s Guide Version 1.0<br />September 2, 2004 So many open source projects. Why not Open your Documents?<br />Pool.PingConnectionsNo<br />tUsedFor<br />对空闲超过设定值（毫秒）的连接进行检测。<br />DBCP:<br />参数 描述<br />Pool.MaximumWait 当线程试图从连接池中获取连接时，连接池中无<br />可用连接可供使用，此时线程将进入等待状态，<br />直到池中出现空闲连接。此参数设定了线程所允<br />许等待的最长时间。（毫秒）<br />Pool.ValidationQuery 数据库连接状态检测语句。<br />某些数据库在连接在某段时间持续处于空闲状态<br />时会将其断开。而连接池管理器将通过此语句检<br />测池中连接是否可用。<br />检测语句应该是一个最简化的无逻辑SQL。<br />如“select 1 from t_user”，如果执行此语句<br />成功，连接池管理器将认为此连接处于可用状态。<br />Pool.LogAbandoned 当数据库连接被废弃时，是否打印日志。<br />Pool.RemoveAbandonedTi<br />meout<br />数据库连接被废弃的最大超时时间<br />Pool.RemoveAbandoned 当连接空闲时间超过<br />RemoveAbandonedTimeout时，是否将其废<br />弃。<br />JNDI由于大部分配置是在应用服务器中进行，因此ibatis中的配置相对简单，下面<br />是分别使用JDBC和JTA事务管理的JDNI配置：<br />使用JDBC事务管理的JNDI DataSource配置<br />&lt;transactionManager type="JDBC" &gt;<br />&lt;dataSource type="JNDI"&gt;<br />&lt;property name="DataSource"<br />value="java:comp/env/jdbc/myDataSource"/&gt;<br />&lt;/dataSource&gt;<br />&lt;/transactionManager&gt;<br />&lt;transactionManager type="JTA" &gt;<br />&lt;property name="UserTransaction"<br />value="java:/ctx/con/UserTransaction"/&gt;<br />&lt;dataSource type="JNDI"&gt;<br />&lt;property name="DataSource"<br />value="java:comp/env/jdbc/myDataSource"/&gt;<br />&lt;/dataSource&gt;<br />IBATIS Developer’s Guide Version 1.0<br />September 2, 2004 So many open source projects. Why not Open your Documents?<br />&lt;/transactionManager&gt;<br /><br />⑷ sqlMap节点<br />sqlMap 节点指定了映射文件的位置，配置中可出现多个sqlMap 节点，以指定<br />项目内所包含的所有映射文件。<br /><br /></div>
						<p>Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=669112</p>
				</div>
		</div>
		<img height="1" alt="" src="http://c.services.spaces.live.com/CollectionWebService/c.gif?space=21958978&amp;page=RSS%ef%bc%9aiBatis%ef%bc%9aO/R+Mapping%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88&amp;referrer=" width="1" border="0" />
		<img style="POSITION: absolute" height="0px" alt="" src="http://c.live.com/c.gif?NC=31263&amp;NA=1149&amp;PI=81873&amp;RF=&amp;DI=3919&amp;PS=85545&amp;TP=21958978.spaces.live.com&amp;GT1=21958978;2052" width="0px" />
		<br />文章来源:<a href="http://21958978.spaces.live.com/Blog/cns!A7DF246804AD47BB!196.entry">http://21958978.spaces.live.com/Blog/cns!A7DF246804AD47BB!196.entry</a><img src ="http://www.blogjava.net/zilong/aggbug/107605.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2007-03-31 10:49 <a href="http://www.blogjava.net/zilong/archive/2007/03/31/107605.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]如何的到某一月的第三个星期三的日期？？？？</title><link>http://www.blogjava.net/zilong/archive/2007/03/31/107599.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Sat, 31 Mar 2007 02:49:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2007/03/31/107599.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/107599.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2007/03/31/107599.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/107599.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/107599.html</trackback:ping><description><![CDATA[
		<div>
				<div>public static Date getDateofMonth(int year,int month){<br />Calendar cal=Calendar.getInstance();<br />cal.set(cal.MONTH,month-1);<br />cal.set(cal.YEAR,year);<br />cal.set(cal.DAY_OF_MONTH,1);<br />int dayofweek=cal.get(cal.DAY_OF_WEEK);<br />if(dayofweek&gt;4){<br />cal.set(cal.WEEK_OF_MONTH,4);<br />}else{<br />cal.set(cal.WEEK_OF_MONTH,3);<br />}<br />cal.set(cal.DAY_OF_WEEK,4);<br />return cal.getTime();<br />}</div>
				<div>
						<br />调用getDateofMonth(2007,2);<br />就行了，哈哈，谢谢大家的帮助</div>
				<div>**************************************************************</div>
				<div>Calendar cal = Calendar.getInstance();<br />cal.setTime(new Date());<br />cal.set(Calendar.MONTH,某月的月份);//注意这个月份是从0开始的<br />cal.set(Calendar.WEEK_OF_MONTH,3);<br />cal.set(Calendar.DAY_OF_WEEK,Calendar.WEDNESDAY);<br />cal.getTime();//这个应该就是你要的日期了</div>
				<div> </div>
				<div>******************************************************</div>
				<div> </div>
				<div>Calendar c = Calendar.getInstance();<br />c.setTime(new Date());<br />c.set(Calendar.YEAR,2007);//2007 current year<br />c.set(Calendar.MONTH,(4-1));//4 current month<br />c.set(Calendar.DATE,1);<br />c.set(Calendar.WEEK_OF_MONTH,<br />c.get(Calendar.DAY_OF_WEEK)&gt;Calendar.WEDNESDAY?4:3);<br />c.set(Calendar.DAY_OF_WEEK,Calendar.WEDNESDAY);<br />c.getTime();</div>
				<div>System.out.println(c.getTime());</div>
				<div> </div>
		</div>
		<img height="1" alt="" src="http://c.services.spaces.live.com/CollectionWebService/c.gif?space=21958978&amp;page=RSS%ef%bc%9a%e5%a6%82%e4%bd%95%e7%9a%84%e5%88%b0%e6%9f%90%e4%b8%80%e6%9c%88%e7%9a%84%e7%ac%ac%e4%b8%89%e4%b8%aa%e6%98%9f%e6%9c%9f%e4%b8%89%e7%9a%84%e6%97%a5%e6%9c%9f%ef%bc%9f%ef%bc%9f%ef%bc%9f%ef%bc%9f&amp;referrer=" width="1" border="0" />
		<img style="POSITION: absolute" height="0px" alt="" src="http://c.live.com/c.gif?NC=31263&amp;NA=1149&amp;PI=81873&amp;RF=&amp;DI=3919&amp;PS=85545&amp;TP=21958978.spaces.live.com&amp;GT1=21958978;2052" width="0px" />
		<br />文章来源:<a href="http://21958978.spaces.live.com/Blog/cns!A7DF246804AD47BB!204.entry">http://21958978.spaces.live.com/Blog/cns!A7DF246804AD47BB!204.entry</a><img src ="http://www.blogjava.net/zilong/aggbug/107599.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2007-03-31 10:49 <a href="http://www.blogjava.net/zilong/archive/2007/03/31/107599.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]J2EE应用性能问题的常用优化项目</title><link>http://www.blogjava.net/zilong/archive/2007/03/31/107598.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Sat, 31 Mar 2007 02:49:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2007/03/31/107598.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/107598.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2007/03/31/107598.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/107598.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/107598.html</trackback:ping><description><![CDATA[
		<div>
				<div>作者tag:<a href="http://tag.csdn.net/tag/jvm/1.html"><u><font color="#0000ff">jvm</font></u></a> <a href="http://tag.csdn.net/tag/算法/1.html"><u><font color="#0000ff">算法</font></u></a> <a href="http://tag.csdn.net/tag/应用服务器/1.html"><u><font color="#0000ff">应用服务器</font></u></a> <a href="http://tag.csdn.net/tag/j2ee/1.html"><u><font color="#0000ff">j2ee</font></u></a> <a href="http://tag.csdn.net/tag/大小/1.html"><u><font color="#0000ff">大小</font></u></a>  
<div style="CLEAR: both"></div><div><div><a href="http://blog.csdn.net/bigxiaowei/archive/2007/03/13/1527474.aspx"><img height="13" src="http://21958978.spaces.live.com/images/authorship.gif" width="15" border="0" /><u><font color="#800080"> J2EE应用性能问题的常用优化项目</font></u></a></div><div><img height="60" alt="" src="http://www.innovatedigital.com/publicimg/speek6.gif" width="500" /><br /><p>        性能问题的最明显表现是网页的响应时间变慢。在J2EE系统中，经常体现有下面更为基本的症状： 
</p><li>应用服务器资源的使用情况 
</li><li>JVM堆的使用情况 
</li><li>系统资源的使用情况 
</li><li>数据库资源的使用情况 
</li><li>网络活动 
<p>        这些现象表明J2EE应用依赖很多外部资源，并且是运行在一个层次化的执行模式的环境中：<img height="199" alt="" src="http://www.innovatedigital.com/publicimg/sp6-1.gif" width="188" /><br /></p><p>        由于Java虚拟机和应用服务器掩盖了操作系统和硬件的特性，所以在设计软件系统时，架构工程师更应该深刻理解整个操作环境。 
</p><p>        在设计软件系统时，架构工程师应把性能和可扩展性放在首位，然后开始寻找容易解决的问题，反应时间缓慢通常的原因是访问数据库效率低和过多地调用远程对象和方法。接下来，架构工程师可继续寻找不明显的原因，例如算法的累积影响和不必要的开销。 
</p><p>        现在市场上的各个J2EE应用服务器有很多配置项目。这里只简单介绍一些常见的性能优化配置项目。 
</p><p>        很多应用服务器都有一些与J2EE规范有关的操作系统配置项目或非标准的特性，这可以提高系统性能。应该化时间来理解这些性能配置。 
</p><h3>Java虚拟机堆和垃圾回收设置</h3><p>        任何Java应用的性能调整基础都涉及到堆的大小和垃圾回收设置。（这里主要讨论Sun HotSpor JVM）. 
</p><p>        堆可分为三代，年轻的（新的），年老的和持久的。Hotspot JVM的内存基本配置包括最大堆大小，初始堆大小和年轻一代堆的大小。当配置最大堆大小时可参考下面一些指导： </p></li><li>最大大小应小于物理内存，避免虚存的页面调度。 
</li><li>需要减去其他进程使用的内存 
</li><li>在负载测试时进行优化 
<p>        注意不要将最大堆大小设置得过大。堆越大，内存中保存的对象越多。内存中对象越多，回收过程时间越长。 
</p><p>        配置初试堆大小的一般性策略包括： 
</p><h3> </h3><p></p></li><li>将初始大小设置为最大堆大小 
</li><li>将初始大小设置为最大堆大小的1/4到1/2 
<p>        对于年轻一代堆大小，Sun 推荐是设置为最大堆大小的1/3。 
</p><p>        也可以选择不同的垃圾回收算法。首先是增量垃圾回收。该算法的意思是减少单个对象回收停顿时间，这样的结果是整体回收性能的下降。该算法将相互引用的对象分组，然后尝试按组回收。尝试回收的部分越小，回收处理的时间往往会越少。 
</p><p>        1.4.1版的HotSpot JVM增加了两个垃圾回收算法：并行算法和并发算法。 
</p><p>        在年轻一代堆中实现了并行算法。在多处理器的机器上，这种回收算法使用了多线程来提高性能。虽然这个算法会暂停所有的应用线程，但是由于利用了多个CPU使得回收时间非常快。在年轻一代堆中，该算法显著地减少了回收带来的停顿。 
</p><p>        在年老一代堆中实现了并发算法。在应用中最大限度地执行并发。回收过程分为4个阶段，覆盖了可回收对象的标记和清除操作。前两个过程会暂停应用线程，后两阶段可与应用并发执行。并发垃圾回收算法的"最大限度并发"特点可以使JVM利用更大的堆和多个CPU。因此应关注由于采用缺省的mark-compact(标记-压缩)和stop-the-world（停顿所有处理）等垃圾回收算法所带来的延迟和吞吐量问题。 
</p><p></p><h3>处理线程</h3><p></p><p>        J2EE应用服务器是多线程的应用。应用服务器的线程是一种资源池，处理请求和和应用服务器的内部功能等任务共享这些资源。 
</p><p>        很多应用服务器允许为特定的任务或应用配置不同大小的线程池。通常需要增加这些线程池的大小以满足应用负载的需要。 
</p><p>        架构工程师应该避免将线程池大小设置过大，这是因为会增加上下文交换的次数，从而降低应用的性能。线程池的大小通常应该能最大利用机器上的CPU，同时又不能使CPU过载。 
</p><p></p><h3>EJB配置项目</h3><p></p><p>         在应用服务器中，很多不同类型的EJB是以资源池的方式实现的。通常这些池大小和初始Bean的数量会明显影响应用的性能。 
</p><p>        架构工程师应该避免将这些池大小设置的过大，这样会导致不必要地消耗JVM和操作系统内存。另外，将初始Bean数量设置过高会使得应用服务器的启动时间长的难以接受。 
</p><p>        在应用服务器中，缓存很多不同类型的EJB。缓存大小和超时设置通常也会对应用性能带来显著影响。 
</p><p>         架构工程师应该避免将缓寸大小设置过大，这同样会不必要地消耗大量JVM和操作系统内存。此外，应避免设置过长的超时--例如当EJB不用时，仍被缓存---，这也会导致不必要地消耗大量内存。 
</p><p></p><h3>数据库配置项目</h3><p></p><p>        J2EE规范要求应用服务器厂商必须提供数据库连接资源池功能。通常增加数据库连接池的大小会提高性能。架构工程师应该考虑不同类型的SQL操作（例如事务型和批处理型）应使用不同的连接池。如果一个消息Bean执行批处理操作，那么应该为此另创建一个连接池，而不要与事务型操作使用同一个连接池。 
</p><p>        很多J2EE应用服务器提供了Prepared Statement 的缓存功能。创建Prepared Statement是很耗费资源的。在事务型的J2EE应用中通常执行很多同样的SQL语句，只是参数不同而已。所以在应用中应发挥数据库配置项目的作用，尽量使用Prepared Statement。 <br /><br /></p><p>Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1527474</p></li></div></div></div>
		</div>
		<img height="1" alt="" src="http://c.services.spaces.live.com/CollectionWebService/c.gif?space=21958978&amp;page=RSS%ef%bc%9aJ2EE%e5%ba%94%e7%94%a8%e6%80%a7%e8%83%bd%e9%97%ae%e9%a2%98%e7%9a%84%e5%b8%b8%e7%94%a8%e4%bc%98%e5%8c%96%e9%a1%b9%e7%9b%ae&amp;referrer=" width="1" border="0" />
		<img style="POSITION: absolute" height="0px" alt="" src="http://c.live.com/c.gif?NC=31263&amp;NA=1149&amp;PI=81873&amp;RF=&amp;DI=3919&amp;PS=85545&amp;TP=21958978.spaces.live.com&amp;GT1=21958978;2052" width="0px" />
		<br />文章来源:<a href="http://21958978.spaces.live.com/Blog/cns!A7DF246804AD47BB!207.entry">http://21958978.spaces.live.com/Blog/cns!A7DF246804AD47BB!207.entry</a><img src ="http://www.blogjava.net/zilong/aggbug/107598.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2007-03-31 10:49 <a href="http://www.blogjava.net/zilong/archive/2007/03/31/107598.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]构造高性能J2EE应用的10个技巧</title><link>http://www.blogjava.net/zilong/archive/2007/03/31/107595.html</link><dc:creator>阿伟</dc:creator><author>阿伟</author><pubDate>Sat, 31 Mar 2007 02:49:00 GMT</pubDate><guid>http://www.blogjava.net/zilong/archive/2007/03/31/107595.html</guid><wfw:comment>http://www.blogjava.net/zilong/comments/107595.html</wfw:comment><comments>http://www.blogjava.net/zilong/archive/2007/03/31/107595.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zilong/comments/commentRss/107595.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zilong/services/trackbacks/107595.html</trackback:ping><description><![CDATA[
		<div>
				<div>构建高性能的J2EE应用不但需要了解常用的实施技巧。下面介绍最常用的10种有效方法，可帮助架构设计师们快速成为这方面的专家。 
<p></p><h3>Java性能的基础----内存管理</h3><p></p><p>        任何Java应用，单机的或J2EE的性能基础都可归结到你的应用是如何管理内存的问题。Java的内存管理包括两个重要任务：内存的分配和内存的回收。在内存的分配中，目标是要减少需要创建的对象。 内存回收是导致性能下降的普遍原因。也就是说，内存中的对象越多，垃圾回收越困难。所以我们对创建对象的态度应该越保守越好。 
</p><p>        在J2EE应用中常见的两个内存有关的问题是：游离的对象（也被称为内存泄露）和对象循环（指大量频繁创建和删除-在Java中体现为解除引用---对象）。 
</p><p>        我们应注意确保所有可到达的对象实际是活的，即这些对象不但在内存中，而且也要在执行的代码中是存在的。当对象在应用中已经没有用了，而我们却忘记了删除对该对象的引用时，游离的对象就出现了。 
</p><p>        我们知道垃圾回收会占用CPU时间。短期对象的大量创建增加了垃圾回收的频率会造成性能下降。 
</p><p></p><h3>不要在Servlet中实现业务逻辑</h3><p></p><p>        在构建J2EE应用时，架构工程师通常会使用到J2EE的基本部分，Servlet。 
</p><p>        如果架构师不使用Session Beans, Entity Beans, 或 Message Beans, 那么改进性能的方法就很少。只能采用增加CPU或更多的物理服务器等方法。EJB使用了缓存（cache）和资源池等方法可以提高性能和扩展性。 
</p><p></p><h3>尽可能使用本地接口访问EJB</h3><p></p><p>        在早期的J2EE （遵循EJB1.X规范）应用中，访问EJB是`通过RMI使用远程接口实现的。随着EJB2.0的出现，可以通过本地接口访问EJB，不再使用RMI，在同一个JVM中使用远程方法已经少多了。但是现在还是有一些使用EJB1.X实现的应用和不知道使用本地接口的一些EJB新手。为说明这点，我们作个比较： 
</p><p>        1. 客户端应用调用本地Stub 
</p><p>        2. 该Stub装配参数 
</p><p>        3. 该Stub传到skeleton 
</p><p>        4. 该skeleton分解参数 
</p><p>        5. 该skeleton调用EJB对象 
</p><p>        6. EJB对象执行容器服务 
</p><p>        7. EJB对象调用企业BEAN实例 
</p><p>        8. 企业BEA执行操作 
</p><p>        9. 执行组装/分解步骤然后返回 
</p><p>        与远程接口处理相比较，本地接口的EJB方法是： 
</p><p>                1. 客户端调用本地对象 
</p><p>                2. 本地对象执行容器服务 
</p><p>                3. 本地对象调用企业Bean实例 
</p><p>                4. 企业Bean实例执行操作 
</p><p>                5. 没有其他返回步骤 
</p><p>        如果你不需要从远程的客户端访问一个特殊EJB，就应该使用本地方法。 
</p><p></p><h3>在实现Session Bean的服务中封装对实体EJB的访问</h3><p></p><p>        从Servlet访问实体EJB不但效率低而且难于维护。使用Session Fa?ade（会话外观）模式可把对实体EJB的访问封装在会话EJB中，在该会话EJB中通过使用本地接口访问实体EJB而避免过多的远程调用。 
</p><p>        这项技术会有额外的性能和扩展方面的好处，这是因为会话和实体EJB可以使用缓存和资源池技术来进行改进。另外，由于负载的需要，会话和实体EJB可被扩展部署到其他硬件设备上，这比将Servlet层复制扩展到其他硬件设备上要简单的多。 
</p><p></p><h3>尽量粗粒度访问远程EJB</h3><p></p><p>         当访问远程EJB时，调用set/get方法将产生过多的网络请求，同时也导致远程接口处理的过载。为避免这种情况，可考虑将数据属性集中在一个对象中，这样通过一次对远程EJB的调用就可以传递所有数据。这项技术就是数据传输对象（Data Transfer Object）模式。 
</p><p></p><h3>优化SQL</h3><p></p><p>        J2EE的架构设计工程师和开发人员通常不是SQL专家或经验丰富的数据库管理员。首先应该确保SQL使用了数据库提供的索引支持。在某些情况下，将数据库的索引和数据分开存放会提高性能。但要知道，增加额外的索引可以提高SELECT性能但也会降低INSERT的性能。对于某些数据库，关联表之间的排序会严重影响性能。可以多向数据库管理员咨询。 
</p><p></p><h3>避免在实体EJB中过多执行SQL</h3><p></p><p>        有时候，通过实体EJB访问数据会执行多个SQL语句。根据J2EE 规范，第一步，将调用实体Bean的find(发现)方法；第二步，在第一次调用实体EJB的业务方法时，容器会调用ejbLoad()从数据库中获得信息。 
</p><p>        很多CMP(容器管理持久性)在调用发现方法时就缓存了实体数据，所以在调用ejbLoad()时就不再访问数据库了。应该避免使用BMP(Bean管理的持久性)或者自己实现缓存算法避免二次访问数据库。 
</p><p></p><h3>使用Fast Lane Reader 模式访问只读数据</h3><p></p><p>        J2EE应用经常要以只读方式访问大量长时间不变的数据，而不是访问单个实体，例如浏览在线产品目录。在这种只读情况下，使用实体EJB访问数据会导致严重过载并且实现很麻烦。实体EJB 适合于对单个实体的粗粒度访问，访问大量的列表只读数据时效率不高。不管是使用CMP还是BMP，一定需要编写代码操作多个实体EJB及其关联。这将导致访问多个数据库并存在大量的也是不必要的事务开销。 
</p><p></p><h3>利用Java Messaging Servce(消息服务)</h3><p></p><p>        J2EE规范在JMS中提供了内置的异步处理服务。当涉及到系统需求时，应该了解在什么情况下应该采用JMS进行异步处理的设计。一旦确定要执行一些异步处理，那么同步处理的任务就应该越少越好，将数据库密集的操作安排在稍后的异步处理中完成。 
</p><p></p><h3>缓存JNDI Lookup查找</h3><p></p><p>        很多操作在进行JNDI查找时要消耗大量资源。通常应该缓存JNDI资源避免网络调用和某些处理的过载。可以缓存的JNDI查找包括： 
</p><p>        EJB Home Interfaces 
</p><p>        Data Sources 
</p><p>        JMS Connection Factories 
</p><p>        JMS Destinations/Topics 
</p><p>        一些JNDI包实现了缓存功能。但是调用对EJB主接口的narrow方法时，这种功能作用有限。 
</p><p>        缓存查找的设计应该使用共享的IntialContext实例，尽管构建它很麻烦。这是因为需要访问多种数据源，包括应用资源文件JNDI.properties,系统属性的各项参数,传入到构造函数的各项参数。<br /></p><p><font color="#cc6600">（北京铸锐数码科技有限公司 www.InnovateDigital.com）</font></p></div>
		</div>
		<img height="1" alt="" src="http://c.services.spaces.live.com/CollectionWebService/c.gif?space=21958978&amp;page=RSS%ef%bc%9a%e6%9e%84%e9%80%a0%e9%ab%98%e6%80%a7%e8%83%bdJ2EE%e5%ba%94%e7%94%a8%e7%9a%8410%e4%b8%aa%e6%8a%80%e5%b7%a7&amp;referrer=" width="1" border="0" />
		<img style="POSITION: absolute" height="0px" alt="" src="http://c.live.com/c.gif?NC=31263&amp;NA=1149&amp;PI=81873&amp;RF=&amp;DI=3919&amp;PS=85545&amp;TP=21958978.spaces.live.com&amp;GT1=21958978;2052" width="0px" />
		<br />文章来源:<a href="http://21958978.spaces.live.com/Blog/cns!A7DF246804AD47BB!211.entry">http://21958978.spaces.live.com/Blog/cns!A7DF246804AD47BB!211.entry</a><img src ="http://www.blogjava.net/zilong/aggbug/107595.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zilong/" target="_blank">阿伟</a> 2007-03-31 10:49 <a href="http://www.blogjava.net/zilong/archive/2007/03/31/107595.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>