愚人碼頭

          知恥而后勇,知不足而進(jìn)
          隨筆 - 33, 文章 - 1, 評(píng)論 - 26, 引用 - 0
          數(shù)據(jù)加載中……

          2005年11月2日

          對(duì)hibernate的新認(rèn)識(shí)

               摘要:   閱讀全文

          posted @ 2008-01-30 11:14 船夫 閱讀(1955) | 評(píng)論 (7)編輯 收藏

          轉(zhuǎn):Javascript事件處理

               摘要:   閱讀全文

          posted @ 2007-12-26 13:00 船夫 閱讀(351) | 評(píng)論 (0)編輯 收藏

          轉(zhuǎn):提升JSP應(yīng)用程序的七大絕招

          提升JSP應(yīng)用程序的七大絕招
          你時(shí)常被客戶抱怨JSP頁(yè)面響應(yīng)速度很慢嗎?你想過當(dāng)客戶訪問次數(shù)劇增時(shí),你的WEB應(yīng)用能承受日益增加的訪 問量嗎?本文講述了調(diào)整JSP和servlet的一些非常實(shí)用的方法,它可使你的servlet和JSP頁(yè)面響應(yīng)更快,擴(kuò)展性更強(qiáng)。而且在用戶數(shù)增加的情 況下,系統(tǒng)負(fù)載會(huì)呈現(xiàn)出平滑上長(zhǎng)的趨勢(shì)。在本文中,我將通過一些實(shí)際例子和配置方法使得你的應(yīng)用程序的性能有出人意料的提升。其中,某些調(diào)優(yōu)技術(shù)是在你的 編程工作中實(shí)現(xiàn)的。而另一些技術(shù)是與應(yīng)用服務(wù)器的配置相關(guān)的。在本文中,我們將詳細(xì)地描述怎樣通過調(diào)整servlet和JSP頁(yè)面,來提高你的應(yīng)用程序的 總體性能。在閱讀本文之前,假設(shè)你有基本的servlet和JSP的知識(shí)。
          方法一:在servlet的init()方法中緩存數(shù)據(jù)

          當(dāng)應(yīng)用服務(wù)器初始化servlet實(shí)例之后,為客戶端請(qǐng)求提供服務(wù)之前,它會(huì)調(diào)用這個(gè)servlet的init()方法。在一個(gè)servlet的生命周 期中,init()方法只會(huì)被調(diào)用一次。通過在init()方法中緩存一些靜態(tài)的數(shù)據(jù)或完成一些只需要執(zhí)行一次的、耗時(shí)的操作,就可大大地提高系統(tǒng)性能。

          例如,通過在init()方法中建立一個(gè)JDBC連接池是一個(gè)最佳例子,假設(shè)我們是用jdbc2.0的DataSource接口來取得數(shù)據(jù)庫(kù)連接,在通 常的情況下,我們需要通過JNDI來取得具體的數(shù)據(jù)源。我們可以想象在一個(gè)具體的應(yīng)用中,如果每次SQL請(qǐng)求都要執(zhí)行一次JNDI查詢的話,那系統(tǒng)性能將 會(huì)急劇下降。解決方法是如下代碼,它通過緩存DataSource,使得下一次SQL調(diào)用時(shí)仍然可以繼續(xù)利用它:

          public class ControllerServlet extends HttpServlet
          {
          private javax.sql.DataSource testDS = null;
          public void init(ServletConfig config) throws ServletException
          {
          super.init(config);
          Context ctx = null;
          try
          {
          ctx = new InitialContext();
          testDS = (javax.sql.DataSource)ctx.lookup("jdbc/testDS");
          }
          catch(NamingException ne)
          {
          ne.printStackTrace();
          }
          catch(Exception e)
          {
          e.printStackTrace();
          }
          }

          public javax.sql.DataSource getTestDS()
          {
          return testDS;
          }
          ...
          ...
          }

          方法 2:禁止servlet和JSP 自動(dòng)重載(auto-reloading)

          Servlet/JSP提供了一個(gè)實(shí)用的技術(shù),即自動(dòng)重載技術(shù),它為開發(fā)人員提供了一個(gè)好的開發(fā)環(huán)境,當(dāng)你改變servlet和JSP頁(yè)面后而不必重啟 應(yīng)用服務(wù)器。然而,這種技術(shù)在產(chǎn)品運(yùn)行階段對(duì)系統(tǒng)的資源是一個(gè)極大的損耗,因?yàn)樗鼤?huì)給JSP引擎的類裝載器(classloader)帶來極大的負(fù)擔(dān)。因 此關(guān)閉自動(dòng)重載功能對(duì)系統(tǒng)性能的提升是一個(gè)極大的幫助。

          方法 3: 不要濫用HttpSession

          在很多應(yīng) 用中,我們的程序需要保持客戶端的狀態(tài),以便頁(yè)面之間可以相互聯(lián)系。但不幸的是由于HTTP具有天生無(wú)狀態(tài)性,從而無(wú)法保存客戶端的狀態(tài)。因此一般的應(yīng)用 服務(wù)器都提供了session來保存客戶的狀態(tài)。在JSP應(yīng)用服務(wù)器中,是通過HttpSession對(duì)像來實(shí)現(xiàn)session的功能的,但在方便的同 時(shí),它也給系統(tǒng)帶來了不小的負(fù)擔(dān)。因?yàn)槊慨?dāng)你獲得或更新session時(shí),系統(tǒng)者要對(duì)它進(jìn)行費(fèi)時(shí)的序列化操作。你可以通過對(duì)HttpSession的以下 幾種處理方式來提升系統(tǒng)的性能:

          ? 如果沒有必要,就應(yīng)該關(guān)閉JSP頁(yè)面中對(duì)HttpSession的缺省設(shè)置: 如果你沒有明確指定的話,每個(gè)JSP頁(yè)面都會(huì)缺省地創(chuàng)建一個(gè)HttpSession。如果你的JSP中不需要使用session的話,那可以通過如下的JSP頁(yè)面指示符來禁止它:

          <%@ page session="false"%>

          ? 不要在HttpSession中存放大的數(shù)據(jù)對(duì)像:如果你在HttpSession中存放大的數(shù)據(jù)對(duì)像的話,每當(dāng)對(duì)它進(jìn)行讀寫時(shí),應(yīng)用服務(wù)器都將對(duì)其進(jìn)行 序列化,從而增加了系統(tǒng)的額外負(fù)擔(dān)。你在HttpSession中存放的數(shù)據(jù)對(duì)像越大,那系統(tǒng)的性能就下降得越快。

          ? 當(dāng)你不需要HttpSession時(shí),盡快地釋放它:當(dāng)你不再需要session時(shí),你可以通過調(diào)用HttpSession.invalidate()方法來釋放它。

          ? 盡量將session的超時(shí)時(shí)間設(shè)得短一點(diǎn):在JSP應(yīng)用服務(wù)器中,有一個(gè)缺省的session的超時(shí)時(shí)間。當(dāng)客戶在這個(gè)時(shí)間之后沒有進(jìn)行任何操作的話, 系統(tǒng)會(huì)將相關(guān)的session自動(dòng)從內(nèi)存中釋放。超時(shí)時(shí)間設(shè)得越大,系統(tǒng)的性能就會(huì)越低,因此最好的方法就是盡量使得它的值保持在一個(gè)較低的水平。

          方法 4: 將頁(yè)面輸出進(jìn)行壓縮

          壓縮是解決數(shù)據(jù)冗余的一個(gè)好的方法,特別是在網(wǎng)絡(luò)帶寬不夠發(fā)達(dá)的今天。有的瀏覽器支持gzip(GNU zip)進(jìn)行來對(duì)HTML文件進(jìn)行壓縮,這種方法可以戲劇性地減少HTML文件的下載時(shí)間。因此,如果你將servlet或JSP頁(yè)面生成的HTML頁(yè)面 進(jìn)行壓縮的話,那用戶就會(huì)覺得頁(yè)面瀏覽速度會(huì)非常快。但不幸的是,不是所有的瀏覽器都支持gzip壓縮,但你可以通過在你的程序中檢查客戶的瀏覽器是否支 持它。下面就是關(guān)于這種方法實(shí)現(xiàn)的一個(gè)代碼片段:

          public void doGet(HttpServletRequest request, HttpServletResponse response)
          throws IOException, ServletException
          {
          OutputStream out = null
          String encoding = request.getHeader("Accept-Encoding");
          if (encoding != null && encoding.indexOf("gzip") != -1)
          {
          request.setHeader("Content-Encoding" , "gzip");
          out = new GZIPOutputStream(request.getOutputStream());
          }
          else if (encoding != null && encoding.indexOf("compress") != -1)
          {
          request.setHeader("Content-Encoding" , "compress");
          out = new ZIPOutputStream(request.getOutputStream());
          }
          else
          {
          out = request.getOutputStream();
          }
          ...
          ...
          }

          方法 5: 使用線程池

          應(yīng)用服務(wù)器缺省地為每個(gè)不同的客戶端請(qǐng)求創(chuàng)建一個(gè)線程進(jìn)行處理,并為它們分派service()方法,當(dāng)service()方法調(diào)用完成后,與之相應(yīng)的 線程也隨之撤消。由于創(chuàng)建和撤消線程會(huì)耗費(fèi)一定的系統(tǒng)資源,這種缺省模式降低了系統(tǒng)的性能。但所幸的是我們可以通過創(chuàng)建一個(gè)線程池來改變這種狀況。另外, 我們還要為這個(gè)線程池設(shè)置一個(gè)最小線程數(shù)和一個(gè)最大線程數(shù)。在應(yīng)用服務(wù)器啟動(dòng)時(shí),它會(huì)創(chuàng)建數(shù)量等于最小線程數(shù)的一個(gè)線程池,當(dāng)客戶有請(qǐng)求時(shí),相應(yīng)地從池從 取出一個(gè)線程來進(jìn)行處理,當(dāng)處理完成后,再將線程重新放入到池中。如果池中的線程不夠地話,系統(tǒng)會(huì)自動(dòng)地增加池中線程的數(shù)量,但總量不能超過最大線程數(shù)。 通過使用線程池,當(dāng)客戶端請(qǐng)求急劇增加時(shí),系統(tǒng)的負(fù)載就會(huì)呈現(xiàn)的平滑的上升曲線,從而提高的系統(tǒng)的可伸縮性。

          方法 6: 選擇正確的頁(yè)面包含機(jī)制

          在JSP中有兩種方法可以用來包含另一個(gè)頁(yè)面:1、使用include指示符(<%@ includee file=”test.jsp” %>)。2、使用jsp指示符(<jsp:includee page=”test.jsp” flush=”true”/>)。在實(shí)際中我發(fā)現(xiàn),如果使用第一種方法的話,可以使得系統(tǒng)性能更高。

          方法 7:正確地確定javabean的生命周期

          JSP的一個(gè)強(qiáng)大的地方就是對(duì)javabean的支持。通過在JSP頁(yè)面中使用<jsp:useBean>標(biāo)簽,可以將javabean直接插入到一個(gè)JSP頁(yè)面中。它的使用方法如下:

          <jsp:useBean id="name" scope="page|request|session|application" class=
          "package.className" type="typeName">
          </jsp:useBean>

          其中scope屬性指出了這個(gè)bean的生命周期。缺省的生命周期為page。如果你沒有正確地選擇bean的生命周期的話,它將影響系統(tǒng)的性能。

          舉例來說,如果你只想在一次請(qǐng)求中使用某個(gè)bean,但你卻將這個(gè)bean的生命周期設(shè)置成了session,那當(dāng)這次請(qǐng)求結(jié)束后,這個(gè)bean將仍然 保留在內(nèi)存中,除非session超時(shí)或用戶關(guān)閉瀏覽器。這樣會(huì)耗費(fèi)一定的內(nèi)存,并無(wú)謂的增加了JVM垃圾收集器的工作量。因此為bean設(shè)置正確的生命 周期,并在bean的使命結(jié)束后盡快地清理它們,會(huì)使用系統(tǒng)性能有一個(gè)提高

          其它一些有用的方法

          ? 在字符串連接操作中盡量不使用“+”操作符:在java編程中,我們常常使用“+”操作符來將幾個(gè)字符串連接起來,但你或許從來沒有想到過它居然會(huì)對(duì)系統(tǒng) 性能造成影響吧?由于字符串是常量,因此JVM會(huì)產(chǎn)生一些臨時(shí)的對(duì)像。你使用的“+”越多,生成的臨時(shí)對(duì)像就越多,這樣也會(huì)給系統(tǒng)性能帶來一些影響。解決 的方法是用StringBuffer對(duì)像來代替“+”操作符。

          ? 避免使用System.out.println()方法:由于System.out.println()是一種同步調(diào)用,即在調(diào)用它時(shí),磁盤I/O操作必 須等待它的完成,因此我們要盡量避免對(duì)它的調(diào)用。但我們?cè)谡{(diào)試程序時(shí)它又是一個(gè)必不可少的方便工具,為了解決這個(gè)矛盾,我建議你最好使用Log4j工具 (http://Jakarta.apache.org ),它既可以方便調(diào)試,而不會(huì)產(chǎn)生System.out.println()這樣的方法。

          ? ServletOutputStream 與 PrintWriter的權(quán)衡:使用PrintWriter可能會(huì)帶來一些小的開銷,因?yàn)樗鼘⑺械脑驾敵龆嫁D(zhuǎn)換為字符流來輸出,因此如果使用它來作為 頁(yè)面輸出的話,系統(tǒng)要負(fù)擔(dān)一個(gè)轉(zhuǎn)換過程。而使用ServletOutputStream作為頁(yè)面輸出的話就不存在一個(gè)問題,但它是以二進(jìn)制進(jìn)行輸出的。因 此在實(shí)際應(yīng)用中要權(quán)衡兩者的利弊。

          總結(jié)

          本文的目的是通過對(duì)servlet和JSP的一些調(diào)優(yōu)技術(shù)來極大地提高你 的應(yīng)用程序的性能,并因此提升整個(gè)J2EE應(yīng)用的性能。通過這些調(diào)優(yōu)技術(shù),你可以發(fā)現(xiàn)其實(shí)并不是某種技術(shù)平臺(tái)(比如J2EE和.NET之爭(zhēng))決定了你的應(yīng) 用程序的性能,重要是你要對(duì)這種平臺(tái)有一個(gè)較為深入的了解,這樣你才能從根本上對(duì)自己的應(yīng)用程序做一個(gè)優(yōu)化! 

          Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1448910

          posted @ 2007-12-25 17:04 船夫 閱讀(232) | 評(píng)論 (0)編輯 收藏

          轉(zhuǎn)載一篇測(cè)試筆記,用于備忘

               摘要:   閱讀全文

          posted @ 2007-12-25 14:43 船夫 閱讀(274) | 評(píng)論 (0)編輯 收藏

          JSP編譯過程

          很久以來,都知道JSP其實(shí)就是Servlet,今天心血來潮,想把里面的具體代碼看一遍,并記錄心得。
          一個(gè)編譯好的JSP類如下:
          public
           final class index_jsp extends HttpJspBase
              
          implements JspSourceDependent
          //上述類為index.jsp被編譯后得到的類
          //HttpJspBase是extends HttpServlet的一個(gè)類
          //JspSourceDependent是一個(gè)接口,只聲明了一個(gè)方法、、getDependants(),返回當(dāng)前page所依賴的文件的名稱,文件包括以下幾種
          //1) files that are included by page directives 
          //2) files that are included by include-prelude and include-coda in jsp:config 
          //3) files that are tag files and referenced 
          //4) TLDs referenced
          其核心方法為:
            public void _jspService(HttpServletRequest request, HttpServletResponse response)
                  
          throws IOException, ServletException{
          .
          }
          該方法重載HttpJspBase中的_jspService方法,進(jìn)行頁(yè)面解析,包括對(duì)scriptlet的加載,html的生成,自定義Tag的解析等等
          HttpJspBase的service再對(duì)_jspService再進(jìn)行調(diào)用,最終生成HTML頁(yè)面

          posted @ 2007-12-18 12:06 船夫 閱讀(1911) | 評(píng)論 (1)編輯 收藏

          Annotation初步了解

          今天在看Tapestry代碼的時(shí)候,突然想了解一下annotation到底是干什么的,有什么好處?花了3個(gè)小時(shí)的時(shí)間,從JDK API開始,大致了解了一下。

          annotation實(shí)際上就是給一些特定的類和其屬性,方法等加上一些注釋(annotation),這些注釋是以屬性name,value進(jìn)行設(shè)置的,這些屬性在Annotation Class中以方法的形式存在,如下:
          @Documented                //是否需要產(chǎn)生javadoc
          @Target(java.lang.annotation.ElementType.METHOD)   //應(yīng)用目標(biāo),這里是應(yīng)用到field屬性上面
          @Retention(RetentionPolicy.RUNTIME)   //該策略指明該注釋會(huì)被加載到j(luò)vm中,即在運(yùn)行時(shí),我們可以得到該注釋的內(nèi)容,另外兩個(gè)策略,SOURCE, CLASS都不會(huì)加載到j(luò)vm中
          public @interface TestAnnoation {
              String value();   //屬性value
              String time();     //屬性time
          }
          以上為自定義的annotation,是應(yīng)用在成員變量上的,使用該annotation情況如下
          public class Test {
              @TestAnnoation(time
          ="12:30",value="20")
              
          public String test(){
                    System.out.println("test!");
                    return null;
              };
          }

          可以使用java的反射來進(jìn)行獲取,通過:
          Class cls = Class.forName("Test");
          cls.isAnnotationPresent(AnnotationClass.
          class);//判斷是否存在annotation
          TestAnnotation ta = (TestAnnotation)cls.getAnnotation(AnnotationClass.class);//獲得AnnotationClass實(shí)例,后調(diào)用這個(gè)實(shí)例可以獲得在AnnotationClass中定義的一些屬性
          System.out.println(ta.time()); //輸出注釋time內(nèi)容
          System.out.println(ta.value()); //輸出注釋value內(nèi)容

          我個(gè)人認(rèn)為annotation的好處是將一些配置直接寫在代碼上,很直觀;以前在使用hibernate的時(shí)候,PO對(duì)象和對(duì)應(yīng)的mapping xml是分開的,不夠直觀,若是使用annotation就會(huì)很直觀的看出這個(gè)對(duì)象的映射屬性以及它的一些特殊屬性(如lazy=true)之類的,在JPA中就把這種配置方式換成了annotation。

          在JE上有很多關(guān)于使用annotation和xml的爭(zhēng)論,我認(rèn)為在小規(guī)模使用上可以使用annotation,就像JPA這種,每個(gè)PO上面都需要進(jìn)行配置,即使使用XML也不能簡(jiǎn)化;而在大規(guī)模使用,如spring所維護(hù)的一些service的事務(wù)配置上避免使用annotation,因?yàn)槊總€(gè)service類中都需要配置,而使用AOP根據(jù)XML配置可以一下就搞定。

          關(guān)于ElementType的其他屬性:
          TYPE(類型), FIELD(屬性), METHOD(方法), PARAMETER(參數(shù)), CONSTRUCTOR(構(gòu)造函數(shù)),LOCAL_VARIABLE(局部變量), ANNOTATION_TYPE,PACKAGE(包),其中的TYPE(類型)是指可以用在Class,Interface,Enum和 Annotation類型上.

          posted @ 2007-12-17 16:33 船夫 閱讀(325) | 評(píng)論 (1)編輯 收藏

          禁食了,腎結(jié)石患者還能吃什么?

          當(dāng)腎結(jié)石、膀胱結(jié)石發(fā)生以后,患者在劇烈的疼痛中常向醫(yī)生討教:腎臟、尿道里那來的石頭呢?手術(shù)之后要怎樣才能預(yù)防它復(fù)發(fā)呢?
          結(jié)石的形成,主要原因就是飲食。它是由飲食中可形成結(jié)石的有關(guān)成分?jǐn)z入過多引起的。再細(xì)一點(diǎn)解釋是:
          草酸積存過多。體內(nèi)草酸的大量積存,是導(dǎo)致腎尿結(jié)石的 因素之一。如菠菜、豆類、葡萄、可可、茶葉、桔子、番茄、土豆、李子、竹筍等這些人們普遍愛吃的東西,正是含草酸較高的食物。醫(yī)生通過研究發(fā)現(xiàn):200克 菠菜中,含草酸725.6毫克,如果一人一次將200克菠菜全部吃掉,食后8小時(shí),檢查尿中草酸排泄量為20-25毫克,相當(dāng)于正常人24小時(shí)排出的草酸 平均總量。
          嘌呤代謝失常。動(dòng)物內(nèi)臟、海產(chǎn)食品、花生、豆角、菠菜等,均含有較多的嘌呤成分。嘌呤進(jìn)入體內(nèi)后,要進(jìn)行新陳代謝,它代謝的最終產(chǎn)物是尿酸。尿酸可促使尿中草酸鹽沉淀。如果,一次過多地食用了含嘌呤豐富的食物,嘌呤的代謝又失常,草酸鹽便在尿中沉積而形成尿結(jié)石
          脂肪攝取太多。各種動(dòng)物的肉類,尤其是肥豬肉,都是脂肪多的食品。多吃了體內(nèi)脂肪必然增高,脂肪會(huì)減少腸道中可結(jié)合的鈣,因而引起對(duì)草酸鹽的吸收增多,如果一旦出現(xiàn)排泄功能故障,如出汗多、喝水少,尿量少,腎結(jié)石很可能就在這種情況下形成。所以,醫(yī)生們常講,為了預(yù)防得結(jié)石病,熱天要多喝點(diǎn)水,吃了油水多的食物時(shí),也要多喝點(diǎn)水,以促進(jìn)排尿暢通,稀釋尿液成分,就減少了得結(jié)石的危險(xiǎn)。
          糖分增高。糖是人體的重要養(yǎng)分,要經(jīng)常適量增補(bǔ),但一下子增加太多,尤其是乳糖,也會(huì)使結(jié)石形成創(chuàng)造條件。專家們發(fā)現(xiàn):不論正常人或結(jié)石病人,在食用100克蔗糖后,過2小時(shí)去檢查他們的尿,發(fā)現(xiàn)尿中的鈣和草酸濃度均上升,若是服用乳糖,它更能促進(jìn)鈣的吸收,更可能導(dǎo)致草酸鈣在體內(nèi)的積存而形成尿結(jié)石
          蛋白質(zhì)過量。對(duì)腎結(jié)石成分進(jìn)行化驗(yàn)分析,發(fā)現(xiàn)結(jié)石中的草酸鈣占87.5%。這么大比重的草酸鈣的來源就是因?yàn)榈鞍踪|(zhì)里除含有草酸的原料——甘氨酸、羥脯氨酸之外,蛋白質(zhì)還能促進(jìn)腸道功能對(duì)鈣的吸收。如果經(jīng)常過量食用高蛋白質(zhì)的食物,便使腎臟和尿中的鈣、草酸、尿酸的成分普遍增高。如果不能及時(shí)有效地通過腎臟功能把多余的鈣、草酸、尿酸排出體外,這樣,得腎臟結(jié)石、輸尿管結(jié)石癥的條件就形成了。當(dāng)今世界經(jīng)濟(jì)發(fā)達(dá)國(guó)家腎結(jié)石發(fā)病率增高的主要原因就是如此。
          從以上幾種易形成腎結(jié)石的因素來看,要預(yù)防腎結(jié)石病 的發(fā)生,就必須改變只顧單求一種營(yíng)養(yǎng)和追求營(yíng)養(yǎng)過甚的觀念。這就是說,在人類的日常飲食中,不能因?yàn)槟撤N食物好吃、營(yíng)養(yǎng)價(jià)值高,就一味地只顧去吃這種食 物。必須注意食物的搭配,各種食物都適量進(jìn)食,即使是檢查出身體缺乏某種營(yíng)養(yǎng)素需要某種食物來補(bǔ)充時(shí),也不宜一次大量進(jìn)食,因?yàn)槿梭w的消化、吸收功能是有限的。消化、吸收不了的養(yǎng)分就要通過排泄器官排泄出去,這樣也會(huì)增加泌尿系統(tǒng)的負(fù)擔(dān),即便不患腎結(jié)石病,也對(duì)健康不利。特別是當(dāng)檢查出確認(rèn)是腎結(jié)石癥時(shí),在患病期間,要限制病人吃那些易促使結(jié)石形成的食物。
          結(jié)石是尿石癥的一種,多在炎熱的夏天形成,因?yàn)橄奶齑罅砍龊梗踔馏w內(nèi)脫水,使排尿減少,再加之夏季暴露于陽(yáng)光下時(shí)間長(zhǎng),紫外線照射皮膚有助于體內(nèi)維生素D和維生素A合成增多,維生素D和維生素A可促進(jìn)小腸吸收鈣離子,尿液中排泄鈣增多,尿內(nèi)結(jié)石物質(zhì)易產(chǎn)生結(jié)晶核,從而形成結(jié)石。冬季天氣寒冷,人的尿量增多,已形成的小結(jié)石被尿液沖刷,向下移動(dòng),此時(shí)引起腎絞痛癥狀。所以,腎結(jié)石常為“夏季形成冬季發(fā)病”。

          人們的飲食品種是多樣的,人體新陳代謝是復(fù)雜的,所以腎結(jié)石的成分也是多樣的。常見結(jié)石按成分可分為五種:一草酸鈣結(jié)石:最為常見,占腎結(jié)石的80以上,在酸性或中性尿中形成,發(fā)病多為青壯年,以男性多見。二磷酸鈣結(jié)石:占結(jié)石的6-9,在堿性尿中形成,也以男性青壯年多發(fā)。三尿酸結(jié)石:占結(jié)石的6,在酸性尿中形成,當(dāng)尿PH值大于6.7時(shí)結(jié)石溶解,以男性多見。四磷酸鎂胺結(jié)石:占結(jié)石的10,在堿性尿中形成,尿PH值小于7.2時(shí)結(jié)石溶解,以女性多見。五胱氨酸結(jié)石:少見,約占結(jié)石的1-2,在酸性尿中形成,尿PH值大于7.0時(shí)結(jié)石溶解。

          大量飲水對(duì)所有成分尿石都有防治作用。在炎熱的夏天,每日尿量少于1200毫升時(shí),尿石生長(zhǎng)的危險(xiǎn)性顯著增大。如能使每日飲水量在2000-4000毫升,這樣可維持每日尿量在2000毫升以上。磁化水對(duì)防治草酸鈣結(jié)石更有效,可將全日飲水量分別于晨起、餐間、睡前給予。清晨飲水量可達(dá)500-1000毫升。為了保持夜間尿量,睡前飲水500毫升,睡眠中起床排尿后再飲水300-500毫升,余下水分別于餐間飲服。大量飲水可促使小的結(jié)石排出,稀釋尿液可防止尿石結(jié)晶形成,并能延緩結(jié)石增長(zhǎng)速度。

          1985年國(guó)外學(xué)者Vehlensieck認(rèn)為,多飲水和飲食療法可使2/3復(fù)發(fā)結(jié)石病人不再生新結(jié)石。下面介紹幾種腎結(jié)石的飲食療法。

          ⑴草酸鈣結(jié)石:宜低鈣及低草酸飲食。少食牛奶及乳制品、豆制品、肉類、動(dòng)物內(nèi)臟(如肝、心臟、腎、腸等),還有巧克力、濃茶、芝麻醬、蛋黃、香菇、菠菜、蝦皮、蘿卜、可可、芹菜、土豆等。近年來發(fā)現(xiàn)食物中纖維素可減少尿鈣的形成,如麥麩食品中的麥麩面包、米糠也有同樣作用,對(duì)復(fù)發(fā)性高鈣尿結(jié)石有效,維生素B1、維生素B6缺乏使尿草酸增多,應(yīng)增加富含此類維生素的食物,如谷物、干果、硬果等。

          ⑵磷酸鈣結(jié)石及磷酸鎂銨結(jié)石:其低鈣飲食同草酸鈣結(jié)石相同。在低磷食物中,宜少食肉類、魚類及骨頭湯。

          ⑶尿結(jié)石: 應(yīng)限制蛋白質(zhì)的攝入量,每日蛋白質(zhì)的總攝入量應(yīng)在48-80克(0.8-1.0克/公斤/日)之間。一般帶葉的蔬菜每市斤約含10克蛋白質(zhì)、瘦肉類每50 克約含蛋白質(zhì)10克、谷類每市斤含蛋白質(zhì)35-60克。要增加新鮮蔬菜和水果的食量。蔬菜和水果含維生素B1及維生素C,它們?cè)隗w內(nèi)最后代謝產(chǎn)物是堿性 的,尿酸在堿性尿內(nèi)易于溶解,故有利于治療。常規(guī)治療:每隔1-2日用一次清涼飲食(生水果、果汁及生菜),至少每周1次清涼飲食。少食或忌用肉類、動(dòng)物 內(nèi)臟、肉湯、肉汁、沙丁魚、蟹、菠菜、濃茶、咖啡,烈性的香料及調(diào)味品也宜少用。
          現(xiàn)實(shí)生活中很多疾病的發(fā)生和日常飲食是密切相關(guān)的,如果能做到起居有時(shí),飲食有節(jié),甚至大部分癌癥也可能避免。現(xiàn)在就腎結(jié)石病這一頑癥來提醒大家如何用飲食來預(yù)防,或使已經(jīng)患了腎結(jié)石者,結(jié)石增大的速度減慢,甚至縮小、溶解而排出體外。

          (一)多飲白開水 多飲水使尿液得到稀釋,鈣離子和草酸根的濃度就會(huì)降低,形成不了草酸鈣結(jié)石。研究表明,增加50%的尿量,可使腎結(jié)石發(fā)病率下降86%。

          (二)合理補(bǔ)鈣,尤其飲食上補(bǔ)鈣 腎結(jié)石患者往往“談鈣色變”,錯(cuò)誤地認(rèn)為腎結(jié)石的元兇是鈣,其實(shí)不然,腎結(jié)石患者也需要補(bǔ)鈣。目前醫(yī)學(xué)界從兩個(gè)不同的角度來解釋,腎結(jié)石患者為什么要補(bǔ)鈣。

          第一是補(bǔ)充鈣能與胃腸道中蔬菜含有的草酸結(jié)合成不溶性的草酸鈣,隨糞便排出體外,減少了部分被腸胃吸收和經(jīng)腎臟排出體外的草酸,從而減少了形成腎結(jié)石的幾率。

          第二是日本學(xué)者提出的“酸堿平衡學(xué)說”。即血液呈酸性時(shí),結(jié)石容易形成。呈堿性時(shí),抑制結(jié)石形成。缺鈣時(shí)血液偏酸性,合理補(bǔ)鈣,血液偏堿,這樣反而有利于抑制結(jié)石形成。

          (三)限量攝入糖類 美國(guó)科學(xué)家最新一項(xiàng)研究結(jié)果表明,高糖食品的攝入,可以使患腎結(jié)石的機(jī)會(huì)增加,因此,要注意少吃甜食。

          (四)少吃草酸鹽含量高的食物 含草酸鹽高的食物有番茄、菠菜、草莓、甜菜、巧克力等,過高的草酸鹽攝入也是導(dǎo)致腎結(jié)石的主要原因之一。

          (五)少吃豆制品 大豆食品含草酸鹽和磷酸鹽都高,能同腎臟中的鈣融合,形成結(jié)石

          (六)睡前慎喝牛奶 睡眠不好的人,睡前喝杯牛奶有助于睡眠。但在睡眠后,尿量減少、濃縮,尿中各種有形物質(zhì)增加。而飲牛奶后2~3小時(shí),正是鈣通過腎臟排泄的高峰。鈣通過腎臟在短時(shí)間內(nèi)驟然增多,容易形成結(jié)石。因此腎結(jié)石患者,睡前就不應(yīng)喝含鈣高的牛奶。

          (七)勿過量服用魚肝油 魚肝油富含維生素D,有促進(jìn)腸膜對(duì)鈣磷吸收的功能,驟然增加尿液中鈣磷的排泄,勢(shì)必產(chǎn)生沉淀,容易形成結(jié)石

          (八)多食黑木耳 黑木耳中富含多種礦物質(zhì)和微量元素,能對(duì)各種結(jié)石產(chǎn)生強(qiáng)烈的化學(xué)反應(yīng),使結(jié)石剝脫、分化、溶解,排出體外。

          posted @ 2007-12-17 12:04 船夫 閱讀(1402) | 評(píng)論 (0)編輯 收藏

          XSL取得當(dāng)前循環(huán)的位置

          最近在一個(gè)項(xiàng)目中用到了XSLT,目的是將返回的XML數(shù)據(jù)記錄通過XSL轉(zhuǎn)換為HTML,在for-each的循環(huán)中取得當(dāng)前記錄的位置,通過實(shí)踐,找到了解決的辦法,主要是使用xsl的position函數(shù)
          1 <xsl:for-each select="QRoleInline-list/QRoleInline">
          2 <xsl:if test="not(position() = 1)"><xsl:text>,</xsl:text></xsl:if><xsl:value-of select="@roleName"/>
          3 </xsl:for-each>
          使用position函數(shù)可以取得當(dāng)前行在循環(huán)中的位置,從1開始。上述代碼是判斷如果位置為第一個(gè), 則需要加逗號(hào)。

          還有一個(gè)函數(shù)current()是負(fù)責(zé)取到當(dāng)前節(jié)點(diǎn)對(duì)象的。

          posted @ 2007-12-14 11:33 船夫 閱讀(525) | 評(píng)論 (0)編輯 收藏

          走出ClassLoader迷局 --轉(zhuǎn)至sharajava的博克http://www.aygfsteel.com/sharajava/archive/2006/07/25/59946.html

          : 這個(gè)問題經(jīng)常出現(xiàn)在編寫框架代碼 , 需要?jiǎng)討B(tài)加載很多類和資源的時(shí)候 . 通常當(dāng)你需要?jiǎng)討B(tài)加載資源的時(shí)候 , 你至少有三個(gè) ClassLoader 可以選擇 :

          2??????? 系統(tǒng)類加載器或叫作應(yīng)用類加載器 (system classloader or application classloader)

          2??????? 當(dāng)前類加載器

          2??????? 當(dāng)前線程類加載器

          上面的問題指的是最后一種類加載器 . 哪種類加載器是正確的選擇呢 ?

          第一種選擇可以很容易地排除 : 系統(tǒng)類加載器 (system classloader). 這個(gè)類加載器處理 -classpath 下的類加載工作 , 可以通過 ClassLoader.getSystemClassLoader() 方法調(diào)用 . ClassLoader 下所有的 getSystemXXX() 的靜態(tài)方法都是通過這個(gè)方法定義的 . 在你的代碼中 , 你應(yīng)該盡量少地調(diào)用這個(gè)方法 , 以其它的類加載器作為代理 . 否則你的代碼將只能工作在簡(jiǎn)單的命令行應(yīng)用中 , 這個(gè)時(shí)候系統(tǒng)類加載器 (system classloader) JVM 最后創(chuàng)建的類加載器 . 一但你把代碼移到 EJB, Web 應(yīng)用或 Java Web Start 應(yīng)用中 , 一定會(huì)出問題 .

          ????? 所以我們來看第二種選擇 : 當(dāng)前上下文環(huán)境下的類加載器 . 根據(jù)定義 , 當(dāng)前類加載器就是你當(dāng)前方法所屬的類的加載器 . 在運(yùn)行時(shí)類之間動(dòng)態(tài)聯(lián)編 , 及調(diào)用 Class.forName,() Class.getResource() 等類似方法時(shí) , 這個(gè)類加載器會(huì)被隱含地使用 . It is also used by syntactic constructs like X.class class literals.

          ??? 線程上下文類型加載器是在Java 2平臺(tái)上被引入的. 每一個(gè)線程都有一個(gè)類加載器與之對(duì)應(yīng)(除非這個(gè)線程是被本地代碼創(chuàng)建的). 這個(gè)類加載器是通過Thread.setContextClassLoaser()方法設(shè)置的. 如果你不在線程構(gòu)造后調(diào)用這個(gè)方法, 這個(gè)線程將從它的父線程中繼承相應(yīng)的上下文類加載器. 如果在整個(gè)應(yīng)用中你不做任何特殊設(shè)置, 所有的線程將都以系統(tǒng)類加載器(system classloader)作為自己的線程上下文類加載器. 自從WebJ2EE應(yīng)用服務(wù)器使用成熟的類加載器機(jī)制來實(shí)現(xiàn)諸如JNDI, 線程池, 組件熱部署等功能以來, 這種在整個(gè)應(yīng)用中不做任何線程類加載器設(shè)置的情況就很少了.

          ??? 為什么線程上下文類加載器存在于如此重要的位置呢? 這個(gè)概念在J2SE中的引入并不引人注目. 很多開發(fā)人員對(duì)這一概念迷惑的原因是Sun公司在這方面缺乏適當(dāng)?shù)闹敢臀臋n.

          ??? 事實(shí)上, 上下文類加載器提供了類加載機(jī)制的后門, 這一點(diǎn)也在J2SE中被引入了. 通常, JVM中的所有類加載器被組織成了有繼承層次的結(jié)構(gòu), 每一個(gè)類加載器(除了引導(dǎo)JVM的原始類加載器)都有一個(gè)父加載器. 每當(dāng)被請(qǐng)示加載類時(shí), 類加載器都會(huì)首先請(qǐng)求其父類加載器, 只有當(dāng)父類加載器不能加載時(shí), 才會(huì)自己進(jìn)行類加載.

          ?? 有時(shí)候這種類加載的順序安排不能正常工作, 通常當(dāng)必須動(dòng)態(tài)加載應(yīng)用程序開發(fā)人員提供的資源的時(shí)候. JNDI為例: 它的內(nèi)容(J2SE1.3開始)就在rt.jar中的引導(dǎo)類中實(shí)現(xiàn)了, 但是這些JNDI核心類需要?jiǎng)討B(tài)加載由獨(dú)立廠商實(shí)現(xiàn)并部署在應(yīng)用程序的classpath下的JNDI提供者. 這種情況就要求一個(gè)父classloader(本例, 就是引導(dǎo)類加載器)去加載對(duì)于它其中一個(gè)子classloader(本例, 系統(tǒng)類加載器)可見的類. 這時(shí)通常的類加載代理機(jī)制不能實(shí)現(xiàn)這個(gè)要求. 解決的辦法(workaround)就是, JNDI核心類使用當(dāng)前線程上下文的類加載器, 這樣, 就基本的類加載代理機(jī)制的相反方向建立了一條有效的途徑.

          ??? 另外, 上面一段可能讓你想起一些其它的事情: XML解析Java API(JAXP). 是的, 當(dāng)JAXP只是J2SE的擴(kuò)展進(jìn), 它很自然地用當(dāng)前類加載器來引導(dǎo)解析器的實(shí)現(xiàn). 而當(dāng)JAXP被加入到J2SE1.4的核心類庫(kù)中時(shí), 它的類加載也就改成了用當(dāng)前線程類加載器, JNDI的情況完全類似(也使很多程序員很迷惑). 明白為什么我說來自Sun的指導(dǎo)很缺乏了吧?

          ?? 在以上的介紹之后, 我們來看關(guān)鍵問題: 這兩種選擇(當(dāng)前類加載器和當(dāng)前線程類加載器)都不是在所有環(huán)境下都適用. 有些人認(rèn)為當(dāng)前線程類加載器應(yīng)該成為新的標(biāo)準(zhǔn)策略. 但是, 如果這樣, 當(dāng)多個(gè)線程通過共享數(shù)據(jù)進(jìn)行交互的時(shí), 將會(huì)呈現(xiàn)出一幅極其復(fù)雜的類加載的畫面, 除非它們?nèi)渴褂昧送粋€(gè)上下文的類加載器. 進(jìn)一步說, 在某些遺留下來的解決方案中, 委派到當(dāng)前類加載器的方法已經(jīng)是標(biāo)準(zhǔn). 比如對(duì)Class.forName(String)的直接調(diào)用(這也是我為什么推薦盡量避免對(duì)這個(gè)方法進(jìn)行調(diào)用的原因). 即使你努力去只調(diào)用上下文相關(guān)的類加載器, 仍然會(huì)有一些代碼會(huì)不由你控制. 這種不受控制的類加載委派機(jī)制是混入是很危險(xiǎn)的.

          ??? 更嚴(yán)重的問題, 某些應(yīng)用服務(wù)器把環(huán)境上下文及當(dāng)前類加載器設(shè)置到不同的類加載器實(shí)例上, 而這些類加載器有相同的類路徑但卻沒有委派機(jī)制中的父子關(guān)系. 想想這為什么十分可怕. 要知道類加載器定義并加載的類實(shí)例會(huì)帶有一個(gè)JVM內(nèi)部的ID號(hào). 如果當(dāng)前類加載器加載一個(gè)類X的實(shí)例, 這個(gè)實(shí)例調(diào)用JNDI查找類Y的實(shí)例, 些時(shí)的上下文的類加載器也可以定義了加載類Y實(shí)例. 這個(gè)類Y的定義就與當(dāng)前類加載器看到的類Y的定義不同. 如果進(jìn)行強(qiáng)制類型轉(zhuǎn)換, 則產(chǎn)生異常.

          ?? 這種混亂的情況還將在Java中存在一段時(shí)間. 對(duì)于那些需要?jiǎng)討B(tài)加載資源的J2SEAPI, 我們來猜想它們的類加策略. 例如:

          ????????? JNDI 使用線程上下文類加載器

          ????????? Class.getResource() Class.forName()使用當(dāng)前類加載器

          ????????? JAXP(J2SE 1.4 及之后)使用線程上下文類加載器

          ????????? java.util.ResourceBundle 使用調(diào)用者的當(dāng)前類加載器

          ????????? URL protocol handlers specified via java.protocol.handler.pkgs system property are looked up in the bootstrap and system classloaders only

          ????????? Java 序列化API默認(rèn)使用調(diào)用者當(dāng)前的類加載器

          這些類及資源的加載策略問題, 肯定是J2SE領(lǐng)域中文檔最及說明最缺乏的部分了.

          posted @ 2006-07-27 15:23 船夫 閱讀(315) | 評(píng)論 (0)編輯 收藏

          看星星的日子

          今天晚上吃完晚飯,往回走的路上,不經(jīng)意間抬頭,看到了很多的星星,我跟同事都停下腳步,抬頭分辨哪個(gè)是北極星,哪里是北斗七星,聊得非常興起。
          想起來自從到了成都之后,算上這次都只看過兩次星星,第一次是大一軍訓(xùn)的時(shí)候,在華陽(yáng)看到的,第二次就是今天晚上了。成都市里面不要指望會(huì)看到星星,因?yàn)闈饷艿脑瓢阉械男切嵌颊谧×恕?br />昨天聽老唐說他看到夜空中有一條“白帶”,他說好像是銀河,他之前從來都沒有看過銀河,跟他比起來我真可以算是幸運(yùn)多了。小時(shí)候,到了夏天,家里人和鄰居都跑到院子里面納涼,我就躺在母親的懷里面,邊享受母親扇子帶來的涼爽,邊抬頭看星星,東北的星空真的是非常清晰,那時(shí)候,母親給我講哪個(gè)是銀河,哪個(gè)是牛郎織女,哪個(gè)是勺子星(北斗七星),還給我講牛郎織女的故事,說一到了七月初七就會(huì)下雨,那是因?yàn)榕@珊涂椗鄷?huì)的淚水,還說從來沒說過謊的小孩子趴在黃瓜架下面可以聽到他們的哭聲,想想現(xiàn)在認(rèn)識(shí)的那幾顆星星都是那個(gè)時(shí)候記下來的,書本上學(xué)的好像都不知道被我丟到哪里去了。那時(shí)候看到的星空現(xiàn)在回想起來真的是非常漂亮,就像冰心在繁星中描述的一樣。
          已經(jīng)很多年沒在家里面過夏天了,過年的時(shí)候倒是有回去,但是天氣太冷,實(shí)在沒那種興致去看星星。
          長(zhǎng)大了,反而覺得快樂只存在于回憶中了,這是成長(zhǎng)的代價(jià)嗎?

          posted @ 2006-07-25 23:53 船夫 閱讀(264) | 評(píng)論 (0)編輯 收藏

          惰性已經(jīng)在充分的滋長(zhǎng)

          已經(jīng)封閉開發(fā)了近三個(gè)月了,由剛開始的熱情高漲到現(xiàn)在的熱情全無(wú),我已經(jīng)逐漸被自己的惰性所吞噬,已經(jīng)快慢慢的丟失了真正的自我。

          經(jīng)過了這么一段時(shí)間,曾經(jīng)對(duì)新技術(shù)非常感興趣的我已經(jīng)完全失去了這種熱情。

          知恥而后勇,我要克服自己的這種情緒,重新開始,用嶄新的眼光去對(duì)待每一天

          posted @ 2006-07-25 23:22 船夫 閱讀(228) | 評(píng)論 (0)編輯 收藏

          項(xiàng)目中遇到的一個(gè)Spring事務(wù)管理的問題

          今天從CVS上checkout項(xiàng)目的時(shí)候,出現(xiàn)了一個(gè)問題,我以前寫的模塊功能本來是好的,但是checkout之后就出了問題,我想一定是配置文件更新出錯(cuò)了,努力尋找,發(fā)現(xiàn)沒有問題.后來經(jīng)同事說他更改了一個(gè)方法,而我的代碼中有對(duì)那個(gè)方法的調(diào)用,終于知道了問題的所在.
          程序中拋出的異常是
          java.lang.IllegalStateException:?No?value?for?key?[org.hibernate.impl.SessionFactoryImpl@7a3d45f0]?bound?to?thread?[Servlet.Engine.Transports?:?0]
          我發(fā)現(xiàn)是在我spring的sevice方法中調(diào)用了他的方法,他的方法又調(diào)用了另一個(gè)service方法,導(dǎo)致出現(xiàn)了這個(gè)問題.

          這個(gè)問題只要把他的那個(gè)方法修改一下,或者從我的service方法中移出就可以解決.

          我想spring中肯定應(yīng)該有些配置能使兩個(gè)service方法處于同一個(gè)事務(wù)中,但是我還沒找到.希望知道的高手能提點(diǎn)一下,謝謝

          posted @ 2006-07-24 18:40 船夫 閱讀(657) | 評(píng)論 (0)編輯 收藏

          在WSAD 5.1中使用log4j遇到的問題

          使用log4j作為日志輸出工具,設(shè)置根級(jí)別為warn,然后分別設(shè)置了hibernate和spring等的級(jí)別為debug,自己項(xiàng)目的級(jí)別也設(shè)置為debug,但是很奇怪的事情出現(xiàn)了:
          我啟動(dòng)wasd的測(cè)試服務(wù)器,打出來的日志只有我本項(xiàng)目的debug級(jí)以上的信息,spring和hibernate的都打不出來;
          我使用main函數(shù)運(yùn)行我項(xiàng)目中的一個(gè)方法,所有的debug信息,spring和hibernate以及我本項(xiàng)目的debug信息一樣都沒少。
          我的配置是絕對(duì)沒有問題的,我實(shí)在想不出來怎么會(huì)出現(xiàn)這種問題,見鬼了,哪位高手遇到過這種情況,告知一下解決方法,謝謝

          posted @ 2006-07-21 01:23 船夫 閱讀(554) | 評(píng)論 (4)編輯 收藏

          好久沒有思考過什么了,整個(gè)大腦都仿佛已經(jīng)失去了這個(gè)能力,每天忙著要么是做項(xiàng)目,要么就是忙著發(fā)呆,發(fā)呆自己能想些什么,做些什么,腦袋真的已經(jīng)生銹了。
          整個(gè)人再也沒有高中時(shí)候的那種反應(yīng),看來這個(gè)大學(xué)讀的是虧了,直到現(xiàn)在還改變不了這種壞習(xí)慣。其實(shí)我很清楚,我這樣對(duì)自己說完全是找個(gè)借口,這樣才能使自己感到?jīng)]有那么的空虛,少些對(duì)自己的自責(zé)。不過我發(fā)現(xiàn),很久以來,都沒有那種自責(zé)的心理了,不會(huì)在為自己的懶散感到自責(zé),真的是很奇怪,在高中的時(shí)候,中午或周末多玩兒了一會(huì)兒,或是做錯(cuò)了一道不該做錯(cuò)的題,都會(huì)感到非常的愧疚,為此而一直自責(zé)。現(xiàn)在長(zhǎng)大了,每天充斥在腦子里面的都是,怎樣才能賺錢,學(xué)什么才能讓自己更加有發(fā)展,思考的越來越現(xiàn)實(shí),反而發(fā)現(xiàn)自己的動(dòng)力越來越不足,天哪,我是怎么了?
          買房子,結(jié)婚?現(xiàn)實(shí)圍繞在我的身邊,把我壓得好緊,女友說我脾氣太好,沒有男子氣概?難道我對(duì)她發(fā)脾氣才是好的嗎??jī)傻胤志樱瑸榱松畛鋈ケ疾ǎM苜嵒貋硪粭澐孔樱y道我愿意嗎?她爸和她媽對(duì)我的印象也不是很好,我知道我這個(gè)人太笨了,不會(huì)說話,不會(huì)討別人喜歡,啊~~~~~~~~~~~我實(shí)在是受不了了,我已經(jīng)對(duì)自己失望透頂了,誰(shuí)能告訴我這個(gè)時(shí)候應(yīng)該能做什么?????
          我要改變這一切,我要改變自己,我要提高自己的能力,我要改變他人對(duì)我的看法,我要做一個(gè)讓所有人都滿意的人,我他媽的是為了什么活得這么累啊,愛情,不是應(yīng)該兩個(gè)人之間事嗎?干嘛有那么多外在因素要影響我呢?
          25歲,這個(gè)世界讓我變得衰老~~~

          posted @ 2006-07-21 01:14 船夫 閱讀(203) | 評(píng)論 (0)編輯 收藏

          表的外鍵約束[ZT]

          1。創(chuàng)建測(cè)試表
          SQL> create table lesson(lesson_name varchar2(20), classroom varchar2(10));

          表已創(chuàng)建。

          SQL> create table teacher(name varchar2(20),lesson_name varchar2(20));

          表已創(chuàng)建。

          SQL> alter table lesson add constraint pk_lesson primary key(lesson_name);

          表已更改。

          SQL> alter table teacher add constraint fk_lessonname foreign key(lesson_name)
          2 references lesson(lesson_name);

          表已更改。


          2。插入測(cè)試數(shù)據(jù)
          SQL> insert into lesson values('english','class 1');

          已創(chuàng)建 1 行。

          SQL> insert into lesson values('music','class 2');

          已創(chuàng)建 1 行。


          3。測(cè)試有外鍵的字段是否可以為空
          SQL> insert into teacher values('wang','hello');
          insert into teacher values('wang','hello')
          *
          ERROR 位于第 1 行:
          ORA-02291: 違反完整約束條件 (SYSTEM.FK_LESSONNAME) - 未找到父項(xiàng)關(guān)鍵字

          SQL> insert into teacher values('wang','music');

          已創(chuàng)建 1 行。

          SQL> insert into teacher values('wang',null);

          已創(chuàng)建 1 行。


          結(jié)論:有外鍵約束的字段可以為空。如果不為空的話,則一定要滿足外鍵的約束關(guān)系

          posted @ 2006-03-16 15:44 船夫 閱讀(328) | 評(píng)論 (0)編輯 收藏

          outer和left outer join有什么區(qū)別??

          outer和left outer join有什么區(qū)別??

          使用關(guān)系代數(shù)合并數(shù)據(jù)
          1 關(guān)系代數(shù)
          合并數(shù)據(jù)集合的理論基礎(chǔ)是關(guān)系代數(shù),它是由E.F.Codd于1970年提出的。
          在關(guān)系代數(shù)的形式化語(yǔ)言中:
          ?        用表、或者數(shù)據(jù)集合表示關(guān)系或者實(shí)體。
          ?        用行表示元組。
          ?        用列表示屬性。
          關(guān)系代數(shù)包含以下8個(gè)關(guān)系運(yùn)算符
          ?        選取――返回滿足指定條件的行。
          ?        投影――從數(shù)據(jù)集合中返回指定的列。
          ?        笛卡爾積――是關(guān)系的乘法,它將分別來自兩個(gè)數(shù)據(jù)集合中的行以所有可能的方式進(jìn)行組合。
          ?        并――關(guān)系的加法和減法,它可以在行的方向上合并兩個(gè)表中的數(shù)據(jù),就像把一個(gè)表壘在另一個(gè)表之上一樣。
          ?        交――返回兩個(gè)數(shù)據(jù)集合所共有的行。
          ?        差――返回只屬于一個(gè)數(shù)據(jù)集合的行。
          ?        連接――在水平方向上合并兩個(gè)表,其方法是:將兩個(gè)表中在共同數(shù)據(jù)項(xiàng)上相互匹配的那些行合并起來。
          ?        除――返回兩個(gè)數(shù)據(jù)集之間的精確匹配。
          此外,作為一種實(shí)現(xiàn)現(xiàn)代關(guān)系代數(shù)運(yùn)算的方法,SQL還提供了:
          ?        子查詢――類似于連接,但更靈活;在外部查詢中,方式可以使用表達(dá)式、列表或者數(shù)據(jù)集合的地方都可以使用子查詢的結(jié)果。
          本章將主要講述多種類型的連接、簡(jiǎn)單的和相關(guān)的子查詢、幾種類型的并、關(guān)系除以及其他的內(nèi)容。
          2 使用連接
          2.1 連接類型
          在關(guān)系代數(shù)中,連接運(yùn)算是由一個(gè)笛卡爾積運(yùn)算和一個(gè)選取運(yùn)算構(gòu)成的。首先用笛卡爾積完成對(duì)兩個(gè)數(shù)據(jù)集合的乘運(yùn)算,然后對(duì)生成的結(jié)果集合進(jìn)行選取運(yùn)算,確保只把分別來自兩個(gè)數(shù)據(jù)集合并且具有重疊部分的行合并在一起。連接的全部意義在于在水平方向上合并兩個(gè)數(shù)據(jù)集合(通常是表),并產(chǎn)生一個(gè)新的結(jié)果集合,其方法是將一個(gè)數(shù)據(jù)源中的行于另一個(gè)數(shù)據(jù)源中和它匹配的行組合成一個(gè)新元組。
          SQL提供了多種類型的連接方式,它們之間的區(qū)別在于:從相互交疊的不同數(shù)據(jù)集合中選擇用于連接的行時(shí)所采用的方法不同。
          連接類型        定義
          內(nèi)連接        只連接匹配的行
          左外連接        包含左邊表的全部行(不管右邊的表中是否存在與它們匹配的行),以及右邊表中全部匹配的行
          右外連接        包含右邊表的全部行(不管左邊的表中是否存在與它們匹配的行),以及左邊表中全部匹配的行
          全外連接        包含左、右兩個(gè)表的全部行,不管另外一邊的表中是否存在與它們匹配的行。
          (H)(theta)連接        使用等值以外的條件來匹配左、右兩個(gè)表中的行
          交叉連接        生成笛卡爾積-它不使用任何匹配或者選取條件,而是直接將一個(gè)數(shù)據(jù)源中的每個(gè)行與另一個(gè)數(shù)據(jù)源的每個(gè)行都一一匹配
          在INFORMIX中連接表的查詢
          如果FROM子句指定了多于一個(gè)表引用,則查詢會(huì)連接來自多個(gè)表的行。連接條件指定各列之間(每個(gè)表至少一列)進(jìn)行連接的關(guān)系。因?yàn)檎诒容^連接條件中的列,所以它們必須具有一致的數(shù)據(jù)類型。
          SELECT語(yǔ)句的FROM子句可以指定以下幾種類型的連接
          FROM子句關(guān)鍵字        相應(yīng)的結(jié)果集
          CROSS JOIN        笛卡爾乘積(所有可能的行對(duì))
          INNER JOIN        僅對(duì)滿足連接條件的CROSS中的列
          LEFT OUTER JOIN        一個(gè)表滿足條件的行,和另一個(gè)表的所有行
          RIGHT OUTER JOIN        與LEFT相同,但兩個(gè)表的角色互換
          FULL OUTER JOIN        LEFT OUTER 和 RIGHT OUTER中所有行的超集

          2.2 內(nèi)連接(Inner Join)
          內(nèi)連接是最常見的一種連接,它頁(yè)被稱為普通連接,而E.FCodd最早稱之為自然連接。
          下面是ANSI SQL-92標(biāo)準(zhǔn)
          select *
          from  t_institution i
          inner join t_teller t
          on i.inst_no = t.inst_no
          where i.inst_no = "5801"
          其中inner可以省略。
          等價(jià)于早期的連接語(yǔ)法
          select *
          from t_institution i, t_teller t
          where i.inst_no = t.inst_no
          and i.inst_no = "5801"

          2.3 外連接
          2.3.1        左外連接(Left Outer Jion)
          select *
          from  t_institution i
          left outer join t_teller t
          on i.inst_no = t.inst_no
          其中outer可以省略。
          2.3.2        右外連接(Rigt Outer Jion)
          select *
          from  t_institution i
          right outer join t_teller t
          on i.inst_no = t.inst_no
          2.3.3        全外連接(Full Outer)
          全外連接返回參與連接的兩個(gè)數(shù)據(jù)集合中的全部數(shù)據(jù),無(wú)論它們是否具有與之相匹配的行。在功能上,它等價(jià)于對(duì)這兩個(gè)數(shù)據(jù)集合分別進(jìn)行左外連接和右外連接,然后再使用消去重復(fù)行的并操作將上述兩個(gè)結(jié)果集合并為一個(gè)結(jié)果集。
          在現(xiàn)實(shí)生活中,參照完整性約束可以減少對(duì)于全外連接的使用,一般情況下左外連接就足夠了。在數(shù)據(jù)庫(kù)中沒有利用清晰、規(guī)范的約束來防范錯(cuò)誤數(shù)據(jù)情況下,全外連接就變得非常有用了,你可以使用它來清理數(shù)據(jù)庫(kù)中的數(shù)據(jù)。
          select *
          from  t_institution i
          full outer join t_teller t
          on i.inst_no = t.inst_no
          2.3.4        外連接與條件配合使用
          當(dāng)在內(nèi)連接查詢中加入條件是,無(wú)論是將它加入到j(luò)oin子句,還是加入到where子句,其效果是完全一樣的,但對(duì)于外連接情況就不同了。當(dāng)把條件加入到j(luò)oin子句時(shí),SQL Server、Informix會(huì)返回外連接表的全部行,然后使用指定的條件返回第二個(gè)表的行。如果將條件放到where子句中,SQL Server將會(huì)首先進(jìn)行連接操作,然后使用where子句對(duì)連接后的行進(jìn)行篩選。下面的兩個(gè)查詢展示了條件放置位子對(duì)執(zhí)行結(jié)果的影響:
          條件在join子句
          select *
          from  t_institution i
          left outer join t_teller t
          on i.inst_no = t.inst_no
          and i.inst_no = “5801”
          結(jié)果是:
          inst_no    inst_name            inst_no    teller_no  teller_name
          5801       天河區(qū)               5801       0001       tom
          5801       天河區(qū)               5801       0002       david
          5802       越秀區(qū)
          5803       白云區(qū)
          條件在where子句
          select *
          from  t_institution i
          left outer join t_teller t
          on i.inst_no = t.inst_no
          where i.inst_no = “5801”
          結(jié)果是:
          inst_no    inst_name            inst_no    teller_no  teller_name
          5801       天河區(qū)               5801       0001       tom
          5801       天河區(qū)               5801       0002       david

          2.4 自身連接
          自身連接是指同一個(gè)表自己與自己進(jìn)行連接。這種一元連接通常用于從自反關(guān)系(也稱作遞歸關(guān)系)中抽取數(shù)據(jù)。例如人力資源數(shù)據(jù)庫(kù)中雇員與老板的關(guān)系。
          下面例子是在機(jī)構(gòu)表中查找本機(jī)構(gòu)和上級(jí)機(jī)構(gòu)的信息。
          select s.inst_no superior_inst, s.inst_name sup_inst_name, i.inst_no, i.inst_name
          from t_institution i
          join t_institution s
          on i.superior_inst = s.inst_no

          結(jié)果是:
          superior_inst sup_inst_name        inst_no    inst_name
          800           廣州市               5801       天河區(qū)
          800           廣州市               5802       越秀區(qū)
          800           廣州市               5803       白云區(qū)

          2.5 交叉(無(wú)限制) 連接
          交叉連接用于對(duì)兩個(gè)源表進(jìn)行純關(guān)系代數(shù)的乘運(yùn)算。它不使用連接條件來限制結(jié)果集合,而是將分別來自兩個(gè)數(shù)據(jù)源中的行以所有可能的方式進(jìn)行組合。數(shù)據(jù)集合中一的每個(gè)行都要與數(shù)據(jù)集合二中的每一個(gè)行分別組成一個(gè)新的行。例如,如果第一個(gè)數(shù)據(jù)源中有5個(gè)行,而第二個(gè)數(shù)據(jù)源中有4個(gè)行,那么在它們之間進(jìn)行交叉連接就會(huì)產(chǎn)生20個(gè)行。人們將這種類型的結(jié)果集稱為笛卡爾乘積。
          大多數(shù)交叉連接都是由于錯(cuò)誤操作而造成的;但是它們卻非常適合向數(shù)據(jù)庫(kù)中填充例子數(shù)據(jù),或者預(yù)先創(chuàng)建一些空行以便為程序執(zhí)行期間所要填充的數(shù)據(jù)保留空間。
          select *
          from  t_institution i
          cross join t_teller t
          在交叉連接中沒有on條件子句

          3 APPENDIX
          3.1 A 參考資料與資源
          ?        《Microsoft SQL Server 2000 Bile》Paul Nielsen
          ?        Paul Nielsen的Web站點(diǎn)
          www.isnotnull.com
          3.2 注文章所有SQL在IBM Informix Dynamic Server Version 9.40.TC2E1測(cè)試通過

          posted @ 2006-03-06 13:02 船夫 閱讀(1643) | 評(píng)論 (0)編輯 收藏

          HTML中Target的四個(gè)保留字

          _parent:在當(dāng)前FRAMESET位置顯示新href。  
          _top:在當(dāng)前整個(gè)窗口位置顯示新href,比如本身FRAMESET位于另一個(gè)FRAMESET中。  
          _self:強(qiáng)制在當(dāng)前FRAME中顯示新href。  
          _blank:在新窗口中顯示href

          posted @ 2005-12-21 09:40 船夫 閱讀(2038) | 評(píng)論 (0)編輯 收藏

          java實(shí)現(xiàn)文件傳輸

               摘要:   1import java.awt.*;   2import java.awt.event.*;   3import javax.swing.*;   4import javax.swing.event.*;   5i...  閱讀全文

          posted @ 2005-12-20 11:22 船夫 閱讀(3058) | 評(píng)論 (5)編輯 收藏

          Document 和 Document.all 分別什么時(shí)候用

          如果與a,form對(duì)象,image對(duì)象,applet對(duì)象相對(duì)應(yīng)的html標(biāo)記中設(shè)定了name性質(zhì),它的值將被用作document對(duì)象的屬性名,用來引用相應(yīng)的對(duì)象,其他的對(duì)象則不可以。

            另外,input等如果作為form的子元素,則直接用inputName或者document.inputName來引用此對(duì)象就是錯(cuò)誤的,必須使用formName.inputName引用,否則就可以使用inputName來引用.

            另外應(yīng)該注意到有很多平時(shí)用的元素都沒有name.

            如果想引用一個(gè)有id的元素,只能用Id或者document.getElementById,document.all.id來引用
          但是象這樣的元素,所以象<a href="......" name="linkname" id="linkid">......</a>這樣的
          可以用

          linkid.href;
          linkname.href;
          document.all.linkid.href;
          document.all.linkname.href;
          document.getElementById("linkid").href;
          document.getElementsByName("linkname")[0].href來引用

            all是一個(gè)集合,包含所有html對(duì)像的集合,寫一個(gè)程式,可以存取到所有的對(duì)像。像這樣:

          <script language="javascript">
          var obj="";
          for(i=0;i<document.all.length;i++)
          obj+=document.all[i].tagName+";";
          alert(obj);
          </script>

            注意要把程式放到</html>之后哦。

          作者:  來源:CSDN

          posted @ 2005-12-20 10:24 船夫 閱讀(680) | 評(píng)論 (0)編輯 收藏

          氣死老師的試卷答案


          1.地理
          地理教過,中國(guó)產(chǎn)煤最多的地方是遼寧省撫順,產(chǎn)鐵最多是遼寧省鞍山, 所以撫順被稱為中國(guó)的“煤都”,鞍山稱為“鐵都”。某次考試,試卷上:中國(guó)的煤都是(黑的),中國(guó)的鐵都是(硬的)。考完還說:老師怎么出那么簡(jiǎn)單的題目?

          2、 語(yǔ)文考試

          一次語(yǔ)文考試的附加題,問普羅米修斯是什么文學(xué)作品里面的人物,一個(gè)同學(xué)填:哈里-波特。還有一次,問左忠毅公叫什么名字,一個(gè)同學(xué)寫:左冷禪。

          3、泰坦尼克號(hào)


          一次政治時(shí)政題:我國(guó)的( )號(hào)考察船去北極考察。我的答案:泰坦尼克號(hào)。

          4 . 解釋“逝世”一詞


          語(yǔ)文考試。解釋“逝世”一詞。我答:“去死”(本來想寫“死去”)老師大怒……

          5 .一行白鷺上西天


          小學(xué),一同學(xué)背詩(shī),前面3句背得那么費(fèi)勁。最后一句:“一行白鷺上西天。”全班暈!

          6、 高一語(yǔ)文摸底考試

          高一語(yǔ)文摸底考試,“何當(dāng)共剪西窗燭”,填下句。我答:“夫妻對(duì)坐到天明”。正確答案:“卻話巴山夜雨時(shí)”。

          7.詩(shī)句填空

          一次語(yǔ)文考試,詩(shī)句填空是白居易的《題大林寺桃花》中的一句“( ),不知轉(zhuǎn)入此中 來”,正解應(yīng)是“常恨春歸無(wú)覓處”,我前排一個(gè)同學(xué)愣是填了“常恨村姑無(wú)覓處”。

          8、 生物考試

          生物考試一填圖題,問一個(gè)細(xì)胞圖是什么生物的,正解是“母果蠅”,我班一人答:“女果蠅”。生物組老師開會(huì)研究N久,決定給0分。

          9、填詩(shī)詞下句

          高中時(shí)候也是填詩(shī)詞下句。上句是:“洛陽(yáng)親友如相問”;我一個(gè)同學(xué)填:“就說我在岳陽(yáng)樓

          10、 一動(dòng)也不動(dòng)

          高中一次語(yǔ)文考試,也是填下一句:“蚍蜉撼大樹,( )”。我有一同學(xué)填:一動(dòng)也不動(dòng)。很符合事實(shí)。

          11、雞型!

          高中時(shí),生物考試,問:雞的消化類型是什么型?我不會(huì),答:雞型!結(jié)果老師在全班點(diǎn)名批評(píng)!

          12、對(duì)子

          上句是:“西塞山前白鷺飛”,同學(xué)憋半天憋不出,于是瞎寫:“東村河邊黑龜爬”!

          13、古詩(shī)下句

          高中語(yǔ)文考試,寫古詩(shī)下句。上句是:“待到山花爛漫時(shí)”,我們班一人居然填了:我便奮力把花采。

          14、初中時(shí)考語(yǔ)文

          初中時(shí)考語(yǔ)文,題目問老舍先生的著名作品的名字。一同學(xué)想不起,我告訴他:茶館。結(jié)果那位聽成:茶壺蓋。被老師痛罵!

          15、拿出芭蕉

          以前同學(xué)讀課文,其中有一句:拿出芭蕉扇扇扇。本來停頓應(yīng)該是拿出芭蕉扇,扇扇。那同學(xué)直接讀成:拿出芭蕉,扇扇扇!

          16、“賣”娥冤

          初中的時(shí)候一次上課把竇娥冤的竇讀成“賣”娥冤。全班爆笑我還不知道為什么

          17、 數(shù)學(xué)考試

          還有一次是數(shù)學(xué)考試,最后一道大題是兩個(gè)解法判斷哪個(gè)正確。我想了半天沒想出來,順便提了幾個(gè)詞:公說公有理!婆說婆有理!看看都沒理!想想全有理……結(jié)果數(shù)學(xué)老師把我的解法整個(gè)年級(jí)她教的四個(gè)班都讀一遍以后,我就聞名了!

          18、《詠梅》

          高中語(yǔ)文課正上毛澤東的《詠梅》,早自習(xí)要求背誦。老師點(diǎn)人回答:“——她在叢中笑下面,XX回答!” XX正在吃東西,半天說不出話來,憋出一句“笑也不出聲!”全班爆笑!


          19.天才學(xué)生

          考試寫:“天生我才必有用”的下句。有位天才學(xué)生答:“老鼠兒子會(huì)打洞”。我們整辦公室的語(yǔ)文老師集體毫無(wú)形象的狂笑!


          20.英語(yǔ)考試

          英語(yǔ)考試: HOW ARE YOU?這么翻譯?答案——怎么是你? HOW OLD ARE YOU?怎么翻譯?答案——怎么老是你?

          21.中國(guó)學(xué)生在美國(guó)

          試題:如果一位中國(guó)學(xué)生在美國(guó)加州目睹了一起交通事故,警察來了以后問你知不知道事情的經(jīng)過,應(yīng)該怎么對(duì)他說?一個(gè)人回答:one car come one car go,two car peng peng,one car die。

          22.名字太短

          A君在做語(yǔ)文試卷時(shí),被一道填空題“《這里的黎明靜悄悄》的作者是誰(shuí)”難住。苦思良久,A君毅然在空欄上寫著“霍利菲爾德”。
          一旁的監(jiān)考老師笑問:“怎么不寫泰森呢?”
          A君道:“他的名字太短了,不像!”

          23.一副跳棋

          B君在作文中要描述一個(gè)人的外貌,遇一字不會(huì),遂悄聲問同桌:“一副眼鏡的‘副’字怎么寫?”
          同桌告訴他:“就是一副跳棋的‘副’嘛。”
          后老師批閱B君的作文,見上面寫道:“他高高的鼻梁上架著一副跳棋。”(

          24.一代更比一代浪


          題目:長(zhǎng)江后浪推前浪__________________

          有位學(xué)生答:一代更比一代浪

          posted @ 2005-12-15 11:18 船夫 閱讀(391) | 評(píng)論 (0)編輯 收藏

          Velocity 簡(jiǎn)介

          1.Velocity 的使用

          Velocity是一個(gè)開放源嗎的模版引擎,由apache.org小組負(fù)責(zé)開發(fā),現(xiàn)在最新的版本是Velocity1.3.1,http://jakarta.apache.org/velocity/index.html 可以了解Velocity的最新信息。
          Velocity允許我們?cè)谀0嬷性O(shè)定變量,然后在運(yùn)行時(shí),動(dòng)態(tài)的將數(shù)據(jù)插入到模版中,替換這些變量。
          例如:
          <html>
          <body>HELLO $CUSTOMERNAME</body>
          </html>
          我們可以在運(yùn)行時(shí)得到客戶的名字,然后把它插入到這個(gè)模版中替換變量$CUSTOMERNAME,整個(gè)替換過程是由Velocity進(jìn)行控制的,而且java的調(diào)用代碼也非常簡(jiǎn)單,如我們可以在java代碼中這樣調(diào)用
          /***********************************************************/
          //這個(gè)文件中設(shè)定了Velocity使用的log4j的配置和Velocity的模版文件所在的目錄
          Velocity.init("D:\\Template\\resource\\jt.properties");
          //模版文件名,模版文件所在的路徑在上一條語(yǔ)句中已經(jīng)設(shè)置了
          Template template = Velocity.getTemplate("hello.vm", "gb2312");
          //實(shí)例化一個(gè)Context
          VelocityContext context = new VelocityContext();
          //把模版變量的值設(shè)置到context中
          context.put("CUSTOMERNAME", "My First Template Engine ---- Velocity.");
          //開始模版的替換
          template.merge(context, writer);
          //寫到文件中
          PrintWriter filewriter = new PrintWriter(new FileOutputStream(outpath),true);
          filewriter.println(writer.toString());
          filewriter.close();
          /***********************************************************/

          這就是整個(gè)java的代碼,非常的簡(jiǎn)單。如果我們有多個(gè)模版變量,我們僅需要把這些模版變量的值設(shè)置到context中。
          下面我們簡(jiǎn)單的分析一下,Velocity引擎讀取模板文件時(shí),它直接輸出文件中所有的文本,但以$字符開頭的除外,$符號(hào)標(biāo)識(shí)著一個(gè)模版變量位置,
          context.put("CUSTOMERNAME", "My First Template Engine ---- Velocity.");
          當(dāng) Velocity 模板引擎解析并輸出模板的結(jié)果時(shí),模板中所有出現(xiàn)$CUSTOMERNAME的地方都將插入客戶的名字,即被加入到VelocityContext的對(duì)象的toString()方法返回值將替代Velocity變量(模板中以$開頭的變量)。
          模板引擎中最強(qiáng)大、使用最頻繁的功能之一是它通過內(nèi)建的映像(Reflection)引擎查找對(duì)象信息的能力。這個(gè)映像引擎允許用一種方便的Java“.”類似的操作符,提取任意加入到VelocityContext的對(duì)象的任何公用方法的值,或?qū)ο蟮娜我鈹?shù)據(jù)成員。
          映像引擎還帶來了另外一個(gè)改進(jìn):快速引用JavaBean的屬性。使用JavaBean屬性的時(shí)候,我們可以忽略get方法和括號(hào)。請(qǐng)看下面這個(gè)模板的例子。
          <html>
          <body>
          Name:$Customer.Name()
          Address:$Customer.Address()
          Age:$Customer.Age()
          </body>
          </html>

          java的代碼:
          /***********************************************************/
          //設(shè)置客戶信息
          Customer mycustomer = new Customer();
          mycustomer.setName("Velocity");
          mycustomer.setAddress("jakarta.apache.org/velocity/index.html");
          mycustomer.setAge(2);
          //這個(gè)文件中設(shè)定了 Velocity 使用的 Log4j 的配置和Velocity的模版文件所在的目錄Velocity.init("D:\\Template\\resource\\jt.properties");
          //模版文件名,模版文件所在的路徑在上一條語(yǔ)句中已經(jīng)設(shè)置了
          Template template = Velocity.getTemplate("hello.vm", "gb2312");
          //實(shí)例化一個(gè)Context
          VelocityContext context = new VelocityContext();
          //把模版變量的值設(shè)置到context中
          context.put("Customer", mycustomer);
          //開始模版的替換
          template.merge(context, writer);
          //寫到文件中
          PrintWriter filewriter = new PrintWriter(new FileOutputStream(outpath),true);
          filewriter.println(writer.toString());
          filewriter.close();
          輸出結(jié)果:
          <html>
          <body>
          Name:Velocity
          Address:jakarta.apache.org/velocity/index.html
          Age:2
          </body>
          </html>
          除了替換變量之外,象Velocity高級(jí)引擎還能做其他許多事情,它們有用來比較和迭代的內(nèi)建指令,通過這些指令我們可以完成程序語(yǔ)言中的條件判斷語(yǔ)句和循環(huán)語(yǔ)句等。
          例如,我們想要輸出年齡等于2的所有客戶的信息,我們可以這樣定義我們的模版
          模版:
          <html>
          <body>
          <table>
          <tr>
          <td>名稱</td>
          <td>地址</td>
          <td>年齡</td>
          </tr>
          #foreach ($Customer in $allCustomer)
          #if($Customer.Age()=="2")
          <tr>
          <td>$Customer.Name()</td>
          <td>$Customer.Address()</td>
          <td>$Customer.Age()</td>
          </tr>
          #end
          #end
          </table>
          </body>
          </html>

          java的代碼:
          /******************************************************/
          //設(shè)置客戶信息
          ArrayList allMyCustomer = new ArrayList();
          //客戶1
          Customer mycustomer1 = new Customer();
          mycustomer1.setName("Velocity");
          mycustomer1.setAddress("jakarta.apache.org/velocity/index.html");
          mycustomer1.setAge(2);
          //客戶2
          Customer mycustomer2 = new Customer();
          mycustomer2.setName("Tomcat");
          mycustomer2.setAddress("jakarta.apache.org/tomcat/index.html");
          mycustomer2.setAge(3);
          //客戶3
          Customer mycustomer3 = new Customer();
          mycustomer3.setName("Log4J");
          mycustomer3.setAddress("jakarta.apache.org/log4j/docs/index.html");
          mycustomer3.setAge(2);
          //添加到allMyCustomer(ArrayList)中.
          allMyCustomer.add(mycustomer1);
          allMyCustomer.add(mycustomer2);
          allMyCustomer.add(mycustomer3);
          //這個(gè)文件中設(shè)定了Velocity使用的log4j的配置和Velocity的模版文件所在的目
          Velocity.init("D:\\Template\\resource\\jt.properties");
          //模版文件名,模版文件所在的路徑在上一條語(yǔ)句中已經(jīng)設(shè)置了
          Template template =Velocity.getTemplate("hello.vm", "gb2312");
          //實(shí)例化一個(gè)Context
          VelocityContext context = new VelocityContext();
          /** 注意這里我們僅僅需要給一個(gè)模版變量負(fù)值 */
          context.put("allCustomer", allMyCustomer);
          //開始模版的替換
          template.merge(context, writer);
          //寫到文件中
          PrintWriter filewriter = new PrintWriter(new FileOutputStream(outpath),true);
          filewriter.println(writer.toString());
          filewriter.close();
          /******************************************************/
          結(jié)果:
          <html>
          <body>
          <table>
          <tr>
          <td>名稱</td>
          <td>地址</td>
          <td>年齡</td>
          </tr>
          <tr>
          <td>Velocity</td>
          <td>jakarta.apache.org/velocity/index.html</td>
          <td>2</td>
          </tr>
          <tr>
          <td>Log4J</td>
          <td>jakarta.apache.org/log4j/docs/index.html</td>
          <td>2</td>
          </tr>
          </table>
          </body>
          </html>

          #if 語(yǔ)句完成邏輯判斷,這個(gè)我想不用多說了。
          allCustomer對(duì)象包含零個(gè)或者多個(gè)Customer對(duì)象。由于ArrayList (List, HashMap, HashTable, Iterator, Vector等)屬于Java Collections Framework的一部分,我們可以用#foreach指令迭代其內(nèi)容。我們不用擔(dān)心如何定型對(duì)象的類型——映像引擎會(huì)為我們完成這個(gè)任務(wù)。#foreach指令的一般格式是“#foreach in ”。#foreach指令迭代list,把list中的每個(gè)元素放入item參數(shù),然后解析#foreach塊內(nèi)的內(nèi)容。對(duì)于list內(nèi)的每個(gè)元素,#foreach塊的內(nèi)容都會(huì)重復(fù)解析一次。從效果上看,它相當(dāng)于告訴模板引擎說:“把list中的每一個(gè)元素依次放入item變量,每次放入一個(gè)元素,輸出一次#foreach塊的內(nèi)容”。

          2.MVC設(shè)計(jì)模型

          使用模板引擎最大的好處在于,它分離了代碼(或程序邏輯)和表現(xiàn)(輸出)。由于這種分離,你可以修改程序邏輯而不必?fù)?dān)心郵件消息本身;類似地,你(或公關(guān)部門的職員)可以在不重新編譯程序的情況下,重新編寫客戶列表。實(shí)際上,我們分離了系統(tǒng)的數(shù)據(jù)模式(Data Model,即提供數(shù)據(jù)的類)、控制器(Controller,即客戶列表程序)以及視圖(View,即模板)。這種三層體系稱為Model-View-Controller模型(MVC)。
          如果遵從MVC模型,代碼分成三個(gè)截然不同的層,簡(jiǎn)化了軟件開發(fā)過程中所有相關(guān)人員的工作。
          結(jié)合模板引擎使用的數(shù)據(jù)模式可以是任何Java對(duì)象,最好是使用Java Collection Framework的對(duì)象。控制器只要了解模板的環(huán)境(如VelocityContext),一般這種環(huán)境都很容易使用。
          一些關(guān)系數(shù)據(jù)庫(kù)的“對(duì)象-關(guān)系”映射工具能夠和模板引擎很好地協(xié)同,簡(jiǎn)化JDBC操作;對(duì)于EJB,情形也類似。 模板引擎與MVC中視圖這一部分的關(guān)系更為密切。模板語(yǔ)言的功能很豐富、強(qiáng)大,足以處理所有必需的視圖功能,同時(shí)它往往很簡(jiǎn)單,不熟悉編程的人也可以使用它。模板語(yǔ)言不僅使得設(shè)計(jì)者從過于復(fù)雜的編程環(huán)境中解脫出來,而且它保護(hù)了系統(tǒng),避免了有意或無(wú)意帶來危險(xiǎn)的代碼。例如,模板的編寫者不可能編寫出導(dǎo)致無(wú)限循環(huán)的代碼,或侵占大量?jī)?nèi)存的代碼。不要輕估這些安全機(jī)制的價(jià)值;大多數(shù)模板編寫者不懂得編程,從長(zhǎng)遠(yuǎn)來看,避免他們接觸復(fù)雜的編程環(huán)境相當(dāng)于節(jié)省了你自己的時(shí)間。 許多模板引擎的用戶相信,在采用模板引擎的方案中,控制器部分和視圖部分的明確分離,再加上模板引擎固有的安全機(jī)制,使得模板引擎足以成為其他內(nèi)容發(fā)布系統(tǒng)(比如JSP)的替代方案。因此,Java模板引擎最常見的用途是替代JSP也就不足為奇了。

          3.HTML處理

          由于人們總是看重模板引擎用來替換JSP的作用,有時(shí)他們會(huì)忘記模板還有更廣泛的用途。到目前為止,模板引擎最常見的用途是處理HTML Web內(nèi)容。但我還用模板引擎生成過SQL、email、XML甚至Java源代碼。

          posted @ 2005-12-01 08:36 船夫 閱讀(528) | 評(píng)論 (0)編輯 收藏

          一篇關(guān)于web.xml配置的詳細(xì)說明

          1 定義頭和根元素

          部署描述符文件就像所有XML文件一樣,必須以一個(gè)XML頭開始。這個(gè)頭聲明可以使用的XML版本并給出文件的字符編碼。
          DOCYTPE聲明必須立即出現(xiàn)在此頭之后。這個(gè)聲明告訴服務(wù)器適用的servlet規(guī)范的版本(如2.2或2.3)并指定管理此文件其余部分內(nèi)容的語(yǔ)法的DTD(Document Type Definition,文檔類型定義)。
          所有部署描述符文件的頂層(根)元素為web-app。請(qǐng)注意,XML元素不像HTML,他們是大小寫敏感的。因此,web-App和WEB-APP都是不合法的,web-app必須用小寫。

          2 部署描述符文件內(nèi)的元素次序

          XML 元素不僅是大小寫敏感的,而且它們還對(duì)出現(xiàn)在其他元素中的次序敏感。例如,XML頭必須是文件中的第一項(xiàng),DOCTYPE聲明必須是第二項(xiàng),而web- app元素必須是第三項(xiàng)。在web-app元素內(nèi),元素的次序也很重要。服務(wù)器不一定強(qiáng)制要求這種次序,但它們?cè)试S(實(shí)際上有些服務(wù)器就是這樣做的)完全拒絕執(zhí)行含有次序不正確的元素的Web應(yīng)用。這表示使用非標(biāo)準(zhǔn)元素次序的web.xml文件是不可移植的。
          下面的列表給出了所有可直接出現(xiàn)在web-app元素內(nèi)的合法元素所必需的次序。例如,此列表說明servlet元素必須出現(xiàn)在所有servlet-mapping元素之前。請(qǐng)注意,所有這些元素都是可選的。因此,可以省略掉某一元素,但不能把它放于不正確的位置。
          l icon icon元素指出IDE和GUI工具用來表示W(wǎng)eb應(yīng)用的一個(gè)和兩個(gè)圖像文件的位置。
          l display-name display-name元素提供GUI工具可能會(huì)用來標(biāo)記這個(gè)特定的Web應(yīng)用的一個(gè)名稱。
          l description description元素給出與此有關(guān)的說明性文本。
          l context-param context-param元素聲明應(yīng)用范圍內(nèi)的初始化參數(shù)。
          l filter 過濾器元素將一個(gè)名字與一個(gè)實(shí)現(xiàn)javax.servlet.Filter接口的類相關(guān)聯(lián)。
          l filter-mapping 一旦命名了一個(gè)過濾器,就要利用filter-mapping元素把它與一個(gè)或多個(gè)servlet或JSP頁(yè)面相關(guān)聯(lián)。
          l listener servlet API的版本2.3增加了對(duì)事件監(jiān)聽程序的支持,事件監(jiān)聽程序在建立、修改和刪除會(huì)話或servlet環(huán)境時(shí)得到通知。Listener元素指出事件監(jiān)聽程序類。
          l servlet 在向servlet或JSP頁(yè)面制定初始化參數(shù)或定制URL時(shí),必須首先命名servlet或JSP頁(yè)面。Servlet元素就是用來完成此項(xiàng)任務(wù)的。
          l servlet-mapping 服務(wù)器一般為servlet提供一個(gè)缺省的URL:
          http://host/webAppPrefix/servlet/ServletName。但是,常常會(huì)更改這個(gè)URL,以便servlet可以訪問初始化參數(shù)或更容易地處理相對(duì)URL。在更改缺省URL時(shí),使用servlet-mapping元素。
          l session-config 如果某個(gè)會(huì)話在一定時(shí)間內(nèi)未被訪問,服務(wù)器可以拋棄它以節(jié)省內(nèi)存。可通過使用HttpSession的setMaxInactiveInterval方法明確設(shè)置單個(gè)會(huì)話對(duì)象的超時(shí)值,或者可利用session-config元素制定缺省超時(shí)值。
          l mime-mapping 如果Web應(yīng)用具有想到特殊的文件,希望能保證給他們分配特定的MIME類型,則mime-mapping元素提供這種保證。
          l welcom-file-list welcome-file-list元素指示服務(wù)器在收到引用一個(gè)目錄名而不是文件名的URL時(shí),使用哪個(gè)文件。
          l error-page error-page元素使得在返回特定HTTP狀態(tài)代碼時(shí),或者特定類型的異常被拋出時(shí),能夠制定將要顯示的頁(yè)面。
          l taglib taglib元素對(duì)標(biāo)記庫(kù)描述符文件(Tag Libraryu Descriptor file)指定別名。此功能使你能夠更改TLD文件的位置,而不用編輯使用這些文件的JSP頁(yè)面。
          l resource-env-ref resource-env-ref元素聲明與資源相關(guān)的一個(gè)管理對(duì)象。
          l resource-ref resource-ref元素聲明一個(gè)資源工廠使用的外部資源。
          l security-constraint security-constraint元素制定應(yīng)該保護(hù)的URL。它與login-config元素聯(lián)合使用
          l login-config 用login-config元素來指定服務(wù)器應(yīng)該怎樣給試圖訪問受保護(hù)頁(yè)面的用戶授權(quán)。它與sercurity-constraint元素聯(lián)合使用。
          l security-role security-role元素給出安全角色的一個(gè)列表,這些角色將出現(xiàn)在servlet元素內(nèi)的security-role-ref元素的role-name子元素中。分別地聲明角色可使高級(jí)IDE處理安全信息更為容易。
          l env-entry env-entry元素聲明Web應(yīng)用的環(huán)境項(xiàng)。
          l ejb-ref ejb-ref元素聲明一個(gè)EJB的主目錄的引用。
          l ejb-local-ref ejb-local-ref元素聲明一個(gè)EJB的本地主目錄的應(yīng)用。

          3 分配名稱和定制的UL

          在web.xml中完成的一個(gè)最常見的任務(wù)是對(duì)servlet或JSP頁(yè)面給出名稱和定制的URL。用servlet元素分配名稱,使用servlet-mapping元素將定制的URL與剛分配的名稱相關(guān)聯(lián)。
          3.1 分配名稱
          為了提供初始化參數(shù),對(duì)servlet或JSP頁(yè)面定義一個(gè)定制URL或分配一個(gè)安全角色,必須首先給servlet或JSP頁(yè)面一個(gè)名稱。可通過 servlet元素分配一個(gè)名稱。最常見的格式包括servlet-name和servlet-class子元素(在web-app元素內(nèi)),如下所示:
          <servlet>
          <servlet-name>Test</servlet-name>
          <servlet-class>moreservlets.TestServlet</servlet-class>
          </servlet>
          這表示位于WEB-INF/classes/moreservlets/TestServlet的servlet已經(jīng)得到了注冊(cè)名Test。給 servlet一個(gè)名稱具有兩個(gè)主要的含義。首先,初始化參數(shù)、定制的URL模式以及其他定制通過此注冊(cè)名而不是類名引用此servlet。其次,可在 URL而不是類名中使用此名稱。因此,利用剛才給出的定義,URL
          http://host/webAppPrefix/servlet/Test 可用于 http://host/webAppPrefix/servlet/moreservlets.TestServlet 的場(chǎng)所。
          請(qǐng)記住:XML元素不僅是大小寫敏感的,而且定義它們的次序也很重要。例如,web-app元素內(nèi)所有servlet元素必須位于所有servlet- mapping元素(下一小節(jié)介紹)之前,而且還要位于5.6節(jié)和5.11節(jié)討論的與過濾器或文檔相關(guān)的元素(如果有的話)之前。類似地,servlet 的servlet-name子元素也必須出現(xiàn)在servlet-class之前。5.2節(jié)"部署描述符文件內(nèi)的元素次序"將詳細(xì)介紹這種必需的次序。
          例如,程序清單5-1給出了一個(gè)名為TestServlet的簡(jiǎn)單servlet,它駐留在moreservlets程序包中。因?yàn)榇藄ervlet是扎根在一個(gè)名為deployDemo的目錄中的Web應(yīng)用的組成部分,所以TestServlet.class放在deployDemo/WEB- INF/classes/moreservlets中。程序清單5-2給出將放置在deployDemo/WEB-INF/內(nèi)的web.xml文件的一部分。此web.xml文件使用servlet-name和servlet-class元素將名稱Test與TestServlet.class相關(guān)聯(lián)。圖 5-1和圖5-2分別顯示利用缺省URL和注冊(cè)名調(diào)用TestServlet時(shí)的結(jié)果。

          程序清單5-1 TestServlet.java
          package moreservlets;

          import java.io.*;
          import javax.servlet.*;
          import javax.servlet.http.*;

          /** Simple servlet used to illustrate servlet naming
          * and custom URLs.
          * <P>
          * Taken from More Servlets and JavaServer Pages
          * from Prentice Hall and Sun Microsystems Press,
          *
          http://www.moreservlets.com/.
          * ? 2002 Marty Hall; may be freely used or adapted.
          */

          public class TestServlet extends HttpServlet {
          public void doGet(HttpServletRequest request,
          HttpServletResponse response)
          throws ServletException, IOException {
          response.setContentType("text/html");
          PrintWriter out = response.getWriter();
          String uri = request.getRequestURI();
          out.println(ServletUtilities.headWithTitle("Test Servlet") +
          "<BODY BGCOLOR=\"#FDF5E6\">\n" +
          "<H2>URI: " + uri + "</H2>\n" +
          "</BODY></HTML>");
          }
          }


          程序清單5-2 web.xml(說明servlet名稱的摘錄)
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!DOCTYPE web-app
          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "
          http://java.sun.com/dtd/web-app_2_3.dtd">

          <web-app>
          <!-- … -->
          <servlet>
          <servlet-name>Test</servlet-name>
          <servlet-class>moreservlets.TestServlet</servlet-class>
          </servlet>
          <!-- … -->
          </web-app>

          3.2 定義定制的URL
          大多數(shù)服務(wù)器具有一個(gè)缺省的serlvet URL:
          http://host/webAppPrefix/servlet/packageName.ServletName。雖然在開發(fā)中使用這個(gè)URL很方便,但是我們常常會(huì)希望另一個(gè)URL用于部署。例如,可能會(huì)需要一個(gè)出現(xiàn)在Web應(yīng)用頂層的URL(如,http: //host/webAppPrefix/Anyname),并且在此URL中沒有servlet項(xiàng)。位于頂層的URL簡(jiǎn)化了相對(duì)URL的使用。此外,對(duì)許多開發(fā)人員來說,頂層URL看上去比更長(zhǎng)更麻煩的缺省URL更簡(jiǎn)短。
          事實(shí)上,有時(shí)需要使用定制的URL。比如,你可能想關(guān)閉缺省URL映射,以便更好地強(qiáng)制實(shí)施安全限制或防止用戶意外地訪問無(wú)初始化參數(shù)的servlet。如果你禁止了缺省的URL,那么你怎樣訪問servlet呢?這時(shí)只有使用定制的URL了。
          為了分配一個(gè)定制的URL,可使用servlet-mapping元素及其servlet-name和url-pattern子元素。Servlet- name元素提供了一個(gè)任意名稱,可利用此名稱引用相應(yīng)的servlet;url-pattern描述了相對(duì)于Web應(yīng)用的根目錄的URL。url- pattern元素的值必須以斜杠(/)起始。
          下面給出一個(gè)簡(jiǎn)單的web.xml摘錄,它允許使用URL
          http://host/webAppPrefix/UrlTest而不是http://host/webAppPrefix/servlet/Test
          http: //host/webAppPrefix/servlet/moreservlets.TestServlet。請(qǐng)注意,仍然需要XML頭、 DOCTYPE聲明以及web-app封閉元素。此外,可回憶一下,XML元素出現(xiàn)地次序不是隨意的。特別是,需要把所有servlet元素放在所有 servlet-mapping元素之前。
          <servlet>
          <servlet-name>Test</servlet-name>
          <servlet-class>moreservlets.TestServlet</servlet-class>
          </servlet>
          <!-- ... -->
          <servlet-mapping>
          <servlet-name>Test</servlet-name>
          <url-pattern>/UrlTest</url-pattern>
          </servlet-mapping>
          URL模式還可以包含通配符。例如,下面的小程序指示服務(wù)器發(fā)送所有以Web應(yīng)用的URL前綴開始,以..asp結(jié)束的請(qǐng)求到名為BashMS的servlet。
          <servlet>
          <servlet-name>BashMS</servlet-name>
          <servlet-class>msUtils.ASPTranslator</servlet-class>
          </servlet>
          <!-- ... -->
          <servlet-mapping>
          <servlet-name>BashMS</servlet-name>
          <url-pattern>/*.asp</url-pattern>
          </servlet-mapping>
          3.3 命名JSP頁(yè)面
          因?yàn)镴SP頁(yè)面要轉(zhuǎn)換成sevlet,自然希望就像命名servlet一樣命名JSP頁(yè)面。畢竟,JSP頁(yè)面可能會(huì)從初始化參數(shù)、安全設(shè)置或定制的URL中受益,正如普通的serlvet那樣。雖然JSP頁(yè)面的后臺(tái)實(shí)際上是servlet這句話是正確的,但存在一個(gè)關(guān)鍵的猜疑:即,你不知道JSP頁(yè)面的實(shí)際類名(因?yàn)橄到y(tǒng)自己挑選這個(gè)名字)。因此,為了命名JSP頁(yè)面,可將jsp-file元素替換為servlet-calss元素,如下所示:
          <servlet>
          <servlet-name>Test</servlet-name>
          <jsp-file>/TestPage.jsp</jsp-file>
          </servlet>
          命名JSP頁(yè)面的原因與命名servlet的原因完全相同:即為了提供一個(gè)與定制設(shè)置(如,初始化參數(shù)和安全設(shè)置)一起使用的名稱,并且,以便能更改激活 JSP頁(yè)面的URL(比方說,以便多個(gè)URL通過相同頁(yè)面得以處理,或者從URL中去掉.jsp擴(kuò)展名)。但是,在設(shè)置初始化參數(shù)時(shí),應(yīng)該注意,JSP頁(yè)面是利用jspInit方法,而不是init方法讀取初始化參數(shù)的。
          例如,程序清單5-3給出一個(gè)名為TestPage.jsp的簡(jiǎn)單JSP頁(yè)面,它的工作只是打印出用來激活它的URL的本地部分。TestPage.jsp放置在deployDemo應(yīng)用的頂層。程序清單5-4給出了用來分配一個(gè)注冊(cè)名PageName,然后將此注冊(cè)名與
          http://host/webAppPrefix/UrlTest2/anything 形式的URL相關(guān)聯(lián)的web.xml文件(即,deployDemo/WEB-INF/web.xml)的一部分。

          程序清單5-3 TestPage.jsp
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
          <HTML>
          <HEAD>
          <TITLE>
          JSP Test Page
          </TITLE>
          </HEAD>
          <BODY BGCOLOR="#FDF5E6">
          <H2>URI: <%= request.getRequestURI() %></H2>
          </BODY>
          </HTML>


          程序清單5-4 web.xml(說明JSP頁(yè)命名的摘錄)
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!DOCTYPE web-app
          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "
          http://java.sun.com/dtd/web-app_2_3.dtd">

          <web-app>
          <!-- ... -->
          <servlet>
          <servlet-name>PageName</servlet-name>
          <jsp-file>/TestPage.jsp</jsp-file>
          </servlet>
          <!-- ... -->
          <servlet-mapping>
          <servlet-name> PageName </servlet-name>
          <url-pattern>/UrlTest2/*</url-pattern>
          </servlet-mapping>
          <!-- ... -->
          </web-app>


          4 禁止激活器servlet

          對(duì)servlet或JSP頁(yè)面建立定制URL的一個(gè)原因是,這樣做可以注冊(cè)從 init(servlet)或jspInit(JSP頁(yè)面)方法中讀取得初始化參數(shù)。但是,初始化參數(shù)只在是利用定制URL模式或注冊(cè)名訪問 servlet或JSP頁(yè)面時(shí)可以使用,用缺省URL
          http://host/webAppPrefix/servlet/ServletName 訪問時(shí)不能使用。因此,你可能會(huì)希望關(guān)閉缺省URL,這樣就不會(huì)有人意外地調(diào)用初始化servlet了。這個(gè)過程有時(shí)稱為禁止激活器servlet,因?yàn)槎鄶?shù)服務(wù)器具有一個(gè)用缺省的servlet URL注冊(cè)的標(biāo)準(zhǔn)servlet,并激活缺省的URL應(yīng)用的實(shí)際servlet。
          有兩種禁止此缺省URL的主要方法:
          l 在每個(gè)Web應(yīng)用中重新映射/servlet/模式。
          l 全局關(guān)閉激活器servlet。
          重要的是應(yīng)該注意到,雖然重新映射每個(gè)Web應(yīng)用中的/servlet/模式比徹底禁止激活servlet所做的工作更多,但重新映射可以用一種完全可移植的方式來完成。相反,全局禁止激活器servlet完全是針對(duì)具體機(jī)器的,事實(shí)上有的服務(wù)器(如ServletExec)沒有這樣的選擇。下面的討論對(duì)每個(gè)Web應(yīng)用重新映射/servlet/ URL模式的策略。后面提供在Tomcat中全局禁止激活器servlet的詳細(xì)內(nèi)容。
          4.1 重新映射/servlet/URL模式
          在一個(gè)特定的Web應(yīng)用中禁止以
          http://host/webAppPrefix/servlet/ 開始的URL的處理非常簡(jiǎn)單。所需做的事情就是建立一個(gè)錯(cuò)誤消息servlet,并使用前一節(jié)討論的url-pattern元素將所有匹配請(qǐng)求轉(zhuǎn)向該 servlet。只要簡(jiǎn)單地使用:
          <url-pattern>/servlet/*</url-pattern>
          作為servlet-mapping元素中的模式即可。
          例如,程序清單5-5給出了將SorryServlet servlet(程序清單5-6)與所有以
          http://host/webAppPrefix/servlet/ 開頭的URL相關(guān)聯(lián)的部署描述符文件的一部分。

          程序清單5-5 web.xml(說明JSP頁(yè)命名的摘錄)
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!DOCTYPE web-app
          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "
          http://java.sun.com/dtd/web-app_2_3.dtd">

          <web-app>
          <!-- ... -->
          <servlet>
          <servlet-name>Sorry</servlet-name>
          <servlet-class>moreservlets.SorryServlet</servlet-class>
          </servlet>
          <!-- ... -->
          <servlet-mapping>
          <servlet-name> Sorry </servlet-name>
          <url-pattern>/servlet/*</url-pattern>
          </servlet-mapping>
          <!-- ... -->
          </web-app>


          程序清單5-6 SorryServlet.java
          package moreservlets;

          import java.io.*;
          import javax.servlet.*;
          import javax.servlet.http.*;

          /** Simple servlet used to give error messages to
          * users who try to access default servlet URLs
          * (i.e.,
          http://host/webAppPrefix/servlet/ServletName)
          * in Web applications that have disabled this
          * behavior.
          * <P>
          * Taken from More Servlets and JavaServer Pages
          * from Prentice Hall and Sun Microsystems Press,
          *
          http://www.moreservlets.com/.
          * ? 2002 Marty Hall; may be freely used or adapted.
          */

          public class SorryServlet extends HttpServlet {
          public void doGet(HttpServletRequest request,
          HttpServletResponse response)
          throws ServletException, IOException {
          response.setContentType("text/html");
          PrintWriter out = response.getWriter();
          String title = "Invoker Servlet Disabled.";
          out.println(ServletUtilities.headWithTitle(title) +
          "<BODY BGCOLOR=\"#FDF5E6\">\n" +
          "<H2>" + title + "</H2>\n" +
          "Sorry, access to servlets by means of\n" +
          "URLs that begin with\n" +
          "
          http://host/webAppPrefix/servlet/\n" +
          "has been disabled.\n" +
          "</BODY></HTML>");
          }

          public void doPost(HttpServletRequest request,
          HttpServletResponse response)
          throws ServletException, IOException {
          doGet(request, response);
          }
          }


          4.2 全局禁止激活器:Tomcat
          Tomcat 4中用來關(guān)閉缺省URL的方法與Tomcat 3中所用的很不相同。下面介紹這兩種方法:
          1.禁止激活器: Tomcat 4
          Tomcat 4用與前面相同的方法關(guān)閉激活器servlet,即利用web.xml中的url-mapping元素進(jìn)行關(guān)閉。不同之處在于Tomcat使用了放在 install_dir/conf中的一個(gè)服務(wù)器專用的全局web.xml文件,而前面使用的是存放在每個(gè)Web應(yīng)用的WEB-INF目錄中的標(biāo)準(zhǔn) web.xml文件。
          因此,為了在Tomcat 4中關(guān)閉激活器servlet,只需在install_dir/conf/web.xml中簡(jiǎn)單地注釋出/servlet/* URL映射項(xiàng)即可,如下所示:
          <!--
          <servlet-mapping>
          <servlet-name>invoker</servlet-name>
          <url-pattern>/servlet/*</url-pattern>
          </servlet-mapping>
          -->
          再次提醒,應(yīng)該注意這個(gè)項(xiàng)是位于存放在install_dir/conf的Tomcat專用的web.xml文件中的,此文件不是存放在每個(gè)Web應(yīng)用的WEB-INF目錄中的標(biāo)準(zhǔn)web.xml。
          2.禁止激活器:Tomcat3
          在Apache Tomcat的版本3中,通過在install_dir/conf/server.xml中注釋出InvokerInterceptor項(xiàng)全局禁止缺省 servlet URL。例如,下面是禁止使用缺省servlet URL的server.xml文件的一部分。
          <!--
          <RequsetInterceptor
          className="org.apache.tomcat.request.InvokerInterceptor"
          debug="0" prefix="/servlet/" />
          -->

          5 初始化和預(yù)裝載servlet與JSP頁(yè)面

          這里討論控制servlet和JSP頁(yè)面的啟動(dòng)行為的方法。特別是,說明了怎樣分配初始化參數(shù)以及怎樣更改服務(wù)器生存期中裝載servlet和JSP頁(yè)面的時(shí)刻。
          5.1 分配servlet初始化參數(shù)
          利用init-param元素向servlet提供初始化參數(shù),init-param元素具有param-name和param-value子元素。例如,在下面的例子中,如果initServlet servlet是利用它的注冊(cè)名(InitTest)訪問的,它將能夠從其方法中調(diào)用getServletConfig(). getInitParameter("param1")獲得"Value 1",調(diào)用getServletConfig().getInitParameter("param2")獲得"2"。
          <servlet>
          <servlet-name>InitTest</servlet-name>
          <servlet-class>moreservlets.InitServlet</servlet-class>
          <init-param>
          <param-name>param1</param-name>
          <param-value>value1</param-value>
          </init-param>
          <init-param>
          <param-name>param2</param-name>
          <param-value>2</param-value>
          </init-param>
          </servlet>
          在涉及初始化參數(shù)時(shí),有幾點(diǎn)需要注意:
          l 返回值。GetInitParameter的返回值總是一個(gè)String。因此,在前一個(gè)例子中,可對(duì)param2使用Integer.parseInt獲得一個(gè)int。
          l JSP中的初始化。JSP頁(yè)面使用jspInit而不是init。JSP頁(yè)面還需要使用jsp-file元素代替servlet-class。
          l 缺省URL。初始化參數(shù)只在通過它們的注冊(cè)名或與它們注冊(cè)名相關(guān)的定制URL模式訪問Servlet時(shí)可以使用。因此,在這個(gè)例子中,param1和 param2初始化參數(shù)將能夠在使用URL
          http://host/webAppPrefix/servlet/InitTest 時(shí)可用,但在使用URL http://host/webAppPrefix/servlet/myPackage.InitServlet 時(shí)不能使用。
          例如,程序清單5-7給出一個(gè)名為InitServlet的簡(jiǎn)單servlet,它使用init方法設(shè)置firstName和emailAddress字段。程序清單5-8給出分配名稱InitTest給servlet的web.xml文件。
          程序清單5-7 InitServlet.java
          package moreservlets;

          import java.io.*;
          import javax.servlet.*;
          import javax.servlet.http.*;

          /** Simple servlet used to illustrate servlet
          * initialization parameters.
          * <P>
          * Taken from More Servlets and JavaServer Pages
          * from Prentice Hall and Sun Microsystems Press,
          *
          http://www.moreservlets.com/.
          * ? 2002 Marty Hall; may be freely used or adapted.
          */

          public class InitServlet extends HttpServlet {
          private String firstName, emailAddress;

          public void init() {
          ServletConfig config = getServletConfig();
          firstName = config.getInitParameter("firstName");
          emailAddress = config.getInitParameter("emailAddress");
          }

          public void doGet(HttpServletRequest request,
          HttpServletResponse response)
          throws ServletException, IOException {
          response.setContentType("text/html");
          PrintWriter out = response.getWriter();
          String uri = request.getRequestURI();
          out.println(ServletUtilities.headWithTitle("Init Servlet") +
          "<BODY BGCOLOR=\"#FDF5E6\">\n" +
          "<H2>Init Parameters:</H2>\n" +
          "<UL>\n" +
          "<LI>First name: " + firstName + "\n" +
          "<LI>Email address: " + emailAddress + "\n" +
          "</UL>\n" +
          "</BODY></HTML>");
          }
          }


          程序清單5-8 web.xml(說明初始化參數(shù)的摘錄)
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!DOCTYPE web-app
          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "
          http://java.sun.com/dtd/web-app_2_3.dtd">

          <web-app>
          <!-- ... -->
          <servlet>
          <servlet-name>InitTest</servlet-name>
          <servlet-class>moreservlets.InitServlet</servlet-class>
          <init-param>
          <param-name>firstName</param-name>
          <param-value>Larry</param-value>
          </init-param>
          <init-param>
          <param-name>emailAddress</param-name>
          <param-value>
          Ellison@Microsoft.com</param-value>
          </init-param>
          </servlet>
          <!-- ... -->
          </web-app>

          5.2 分配JSP初始化參數(shù)
          給JSP頁(yè)面提供初始化參數(shù)在三個(gè)方面不同于給servlet提供初始化參數(shù)。
          1)使用jsp-file而不是servlet-class。因此,WEB-INF/web.xml文件的servlet元素如下所示:
          <servlet>
          <servlet-name>PageName</servlet-name>
          <jsp-file>/RealPage.jsp</jsp-file>
          <init-param>
          <param-name>...</param-name>
          <param-value>...</param-value>
          </init-param>
          ...
          </servlet>
          2) 幾乎總是分配一個(gè)明確的URL模式。對(duì)servlet,一般相應(yīng)地使用以
          http://host/webAppPrefix/servlet/ 開始的缺省URL。只需記住,使用注冊(cè)名而不是原名稱即可。這對(duì)于JSP頁(yè)面在技術(shù)上也是合法的。例如,在上面給出的例子中,可用URL http://host/webAppPrefix/servlet/PageName 訪問RealPage.jsp的對(duì)初始化參數(shù)具有訪問權(quán)的版本。但在用于JSP頁(yè)面時(shí),許多用戶似乎不喜歡應(yīng)用常規(guī)的servlet的URL。此外,如果 JSP頁(yè)面位于服務(wù)器為其提供了目錄清單的目錄中(如,一個(gè)既沒有index.html也沒有index.jsp文件的目錄),則用戶可能會(huì)連接到此 JSP頁(yè)面,單擊它,從而意外地激活未初始化的頁(yè)面。因此,好的辦法是使用url-pattern(5.3節(jié))將JSP頁(yè)面的原URL與注冊(cè)的 servlet名相關(guān)聯(lián)。這樣,客戶機(jī)可使用JSP頁(yè)面的普通名稱,但仍然激活定制的版本。例如,給定來自項(xiàng)目1的servlet定義,可使用下面的 servlet-mapping定義:
          <servlet-mapping>
          <servlet-name>PageName</servlet-name>
          <url-pattern>/RealPage.jsp</url-pattern>
          </servlet-mapping>
          3)JSP頁(yè)使用jspInit而不是init。自動(dòng)從JSP頁(yè)面建立的servlet或許已經(jīng)使用了inti方法。因此,使用JSP聲明提供一個(gè)init方法是不合法的,必須制定jspInit方法。
          為了說明初始化JSP頁(yè)面的過程,程序清單5-9給出了一個(gè)名為InitPage.jsp的JSP頁(yè)面,它包含一個(gè)jspInit方法且放置于 deployDemo Web應(yīng)用層次結(jié)構(gòu)的頂層。一般,
          http://host/deployDemo/InitPage.jsp 形式的URL將激活此頁(yè)面的不具有初始化參數(shù)訪問權(quán)的版本,從而將對(duì)firstName和emailAddress變量顯示null。但是, web.xml文件(程序清單5-10)分配了一個(gè)注冊(cè)名,然后將該注冊(cè)名與URL模式/InitPage.jsp相關(guān)聯(lián)。

          程序清單5-9 InitPage.jsp
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
          <HTML>
          <HEAD><TITLE>JSP Init Test</TITLE></HEAD>
          <BODY BGCOLOR="#FDF5E6">
          <H2>Init Parameters:</H2>
          <UL>
          <LI>First name: <%= firstName %>
          <LI>Email address: <%= emailAddress %>
          </UL>
          </BODY></HTML>
          <%!
          private String firstName, emailAddress;

          public void jspInit() {
          ServletConfig config = getServletConfig();
          firstName = config.getInitParameter("firstName");
          emailAddress = config.getInitParameter("emailAddress");
          }
          %>


          程序清單5-10 web.xml(說明JSP頁(yè)面的init參數(shù)的摘錄)
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!DOCTYPE web-app
          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "
          http://java.sun.com/dtd/web-app_2_3.dtd">

          <web-app>
          <!-- ... -->
          <servlet>
          <servlet-name>InitPage</servlet-name>
          <jsp-file>/InitPage.jsp</jsp-file>
          <init-param>
          <param-name>firstName</param-name>
          <param-value>Bill</param-value>
          </init-param>
          <init-param>
          <param-name>emailAddress</param-name>
          <param-value>
          gates@oracle.com</param-value>
          </init-param>
          </servlet>
          <!-- ... -->
          <servlet-mapping>
          <servlet-name> InitPage</servlet-name>
          <url-pattern>/InitPage.jsp</url-pattern>
          </servlet-mapping>
          <!-- ... -->
          </web-app>


          5.3 提供應(yīng)用范圍內(nèi)的初始化參數(shù)
          一般,對(duì)單個(gè)地servlet或JSP頁(yè)面分配初始化參數(shù)。指定的servlet或JSP頁(yè)面利用ServletConfig的getInitParameter方法讀取這些參數(shù)。但是,在某些情形下,希望提供可由任意servlet或JSP頁(yè)面借助ServletContext的getInitParameter方法讀取的系統(tǒng)范圍內(nèi)的初始化參數(shù)。
          可利用context-param元素聲明這些系統(tǒng)范圍內(nèi)的初始化值。context-param元素應(yīng)該包含param-name、param-value以及可選的description子元素,如下所示:
          <context-param>
          <param-name>support-email</param-name>
          <param-value>
          blackhole@mycompany.com</param-value>
          </context-param>
          可回憶一下,為了保證可移植性,web.xml內(nèi)的元素必須以正確的次序聲明。但這里應(yīng)該注意,context-param元素必須出現(xiàn)任意與文檔有關(guān)的元素(icon、display-name或description)之后及filter、filter-mapping、listener或 servlet元素之前。
          5.4 在服務(wù)器啟動(dòng)時(shí)裝載servlet
          假如servlet或JSP頁(yè)面有一個(gè)要花很長(zhǎng)時(shí)間執(zhí)行的init (servlet)或jspInit(JSP)方法。例如,假如init或jspInit方法從某個(gè)數(shù)據(jù)庫(kù)或ResourceBundle查找產(chǎn)量。這種情況下,在第一個(gè)客戶機(jī)請(qǐng)求時(shí)裝載servlet的缺省行為將對(duì)第一個(gè)客戶機(jī)產(chǎn)生較長(zhǎng)時(shí)間的延遲。因此,可利用servlet的load-on- startup元素規(guī)定服務(wù)器在第一次啟動(dòng)時(shí)裝載servlet。下面是一個(gè)例子。
          <servlet>
          <servlet-name> … </servlet-name>
          <servlet-class> … </servlet-class> <!-- Or jsp-file -->
          <load-on-startup/>
          </servlet>
          可以為此元素體提供一個(gè)整數(shù)而不是使用一個(gè)空的load-on-startup。想法是服務(wù)器應(yīng)該在裝載較大數(shù)目的servlet或JSP頁(yè)面之前裝載較少數(shù)目的servlet或JSP頁(yè)面。例如,下面的servlet項(xiàng)(放置在Web應(yīng)用的WEB-INF目錄下的web.xml文件中的web-app元素內(nèi))將指示服務(wù)器首先裝載和初始化SearchServlet,然后裝載和初始化由位于Web應(yīng)用的result目錄中的index.jsp文件產(chǎn)生的 servlet。
          <servlet>
          <servlet-name>Search</servlet-name>
          <servlet-class>myPackage.SearchServlet</servlet-class> <!-- Or jsp-file -->
          <load-on-startup>1</load-on-startup>
          </servlet>
          <servlet>
          <servlet-name>Results</servlet-name>
          <servlet-class>/results/index.jsp</servlet-class> <!-- Or jsp-file -->
          <load-on-startup>2</load-on-startup>
          </servlet>

          6 聲明過濾器

          servlet版本2.3引入了過濾器的概念。雖然所有支持servlet API版本2.3的服務(wù)器都支持過濾器,但為了使用與過濾器有關(guān)的元素,必須在web.xml中使用版本2.3的DTD。
          過濾器可截取和修改進(jìn)入一個(gè)servlet或JSP頁(yè)面的請(qǐng)求或從一個(gè)servlet或JSP頁(yè)面發(fā)出的相應(yīng)。在執(zhí)行一個(gè)servlet或JSP頁(yè)面之前,必須執(zhí)行第一個(gè)相關(guān)的過濾器的doFilter方法。在該過濾器對(duì)其FilterChain對(duì)象調(diào)用doFilter時(shí),執(zhí)行鏈中的下一個(gè)過濾器。如果沒有其他過濾器,servlet或JSP頁(yè)面被執(zhí)行。過濾器具有對(duì)到來的ServletRequest對(duì)象的全部訪問權(quán),因此,它們可以查看客戶機(jī)名、查找到來的cookie等。為了訪問servlet或JSP頁(yè)面的輸出,過濾器可將響應(yīng)對(duì)象包裹在一個(gè)替身對(duì)象(stand-in object)中,比方說把輸出累加到一個(gè)緩沖區(qū)。在調(diào)用FilterChain對(duì)象的doFilter方法之后,過濾器可檢查緩沖區(qū),如有必要,就對(duì)它進(jìn)行修改,然后傳送到客戶機(jī)。
          例如,程序清單5-11帝國(guó)難以了一個(gè)簡(jiǎn)單的過濾器,只要訪問相關(guān)的servlet或JSP頁(yè)面,它就截取請(qǐng)求并在標(biāo)準(zhǔn)輸出上打印一個(gè)報(bào)告(開發(fā)過程中在桌面系統(tǒng)上運(yùn)行時(shí),大多數(shù)服務(wù)器都可以使用這個(gè)過濾器)。

          程序清單5-11 ReportFilter.java
          package moreservlets;

          import java.io.*;
          import javax.servlet.*;
          import javax.servlet.http.*;
          import java.util.*;

          /** Simple filter that prints a report on the standard output
          * whenever the associated servlet or JSP page is accessed.
          * <P>
          * Taken from More Servlets and JavaServer Pages
          * from Prentice Hall and Sun Microsystems Press,
          *
          http://www.moreservlets.com/.
          * ? 2002 Marty Hall; may be freely used or adapted.
          */

          public class ReportFilter implements Filter {
          public void doFilter(ServletRequest request,
          ServletResponse response,
          FilterChain chain)
          throws ServletException, IOException {
          HttpServletRequest req = (HttpServletRequest)request;
          System.out.println(req.getRemoteHost() +
          " tried to access " +
          req.getRequestURL() +
          " on " + new Date() + ".");
          chain.doFilter(request,response);
          }

          public void init(FilterConfig config)
          throws ServletException {
          }

          public void destroy() {}
          }

          一旦建立了一個(gè)過濾器,可以在web.xml中利用filter元素以及filter-name(任意名稱)、file-class(完全限定的類名)和(可選的)init-params子元素聲明它。請(qǐng)注意,元素在web.xml的web-app元素中出現(xiàn)的次序不是任意的;允許服務(wù)器(但不是必需的)強(qiáng)制所需的次序,并且實(shí)際中有些服務(wù)器也是這樣做的。但這里要注意,所有filter元素必須出現(xiàn)在任意filter-mapping元素之前, filter-mapping元素又必須出現(xiàn)在所有servlet或servlet-mapping元素之前。
          例如,給定上述的ReportFilter類,可在web.xml中作出下面的filter聲明。它把名稱Reporter與實(shí)際的類ReportFilter(位于moreservlets程序包中)相關(guān)聯(lián)。
          <filter>
          <filter-name>Reporter</filter-name>
          <filter-class>moresevlets.ReportFilter</filter-class>
          </filter>
          一旦命名了一個(gè)過濾器,可利用filter-mapping元素把它與一個(gè)或多個(gè)servlet或JSP頁(yè)面相關(guān)聯(lián)。關(guān)于此項(xiàng)工作有兩種選擇。
          首先,可使用filter-name和servlet-name子元素把此過濾器與一個(gè)特定的servlet名(此servlet名必須稍后在相同的 web.xml文件中使用servlet元素聲明)關(guān)聯(lián)。例如,下面的程序片斷指示系統(tǒng)只要利用一個(gè)定制的URL訪問名為SomeServletName 的servlet或JSP頁(yè)面,就運(yùn)行名為Reporter的過濾器。
          <filter-mapping>
          <filter-name>Reporter</filter-name>
          <servlet-name>SomeServletName</servlet-name>
          </filter-mapping>
          其次,可利用filter-name和url-pattern子元素將過濾器與一組servlet、JSP頁(yè)面或靜態(tài)內(nèi)容相關(guān)聯(lián)。例如,相面的程序片段指示系統(tǒng)只要訪問Web應(yīng)用中的任意URL,就運(yùn)行名為Reporter的過濾器。
          <filter-mapping>
          <filter-name>Reporter</filter-name>
          <url-pattern>/*</url-pattern>
          </filter-mapping>
          例如,程序清單5-12給出了將ReportFilter過濾器與名為PageName的servlet相關(guān)聯(lián)的web.xml文件的一部分。名字 PageName依次又與一個(gè)名為TestPage.jsp的JSP頁(yè)面以及以模式http: //host/webAppPrefix/UrlTest2/ 開頭的URL相關(guān)聯(lián)。TestPage.jsp的源代碼已經(jīng)JSP頁(yè)面命名的談?wù)撛谇懊娴?節(jié)"分配名稱和定制的URL"中給出。事實(shí)上,程序清單5- 12中的servlet和servlet-name項(xiàng)從該節(jié)原封不動(dòng)地拿過來的。給定這些web.xml項(xiàng),可看到下面的標(biāo)準(zhǔn)輸出形式的調(diào)試報(bào)告(換行是為了容易閱讀)。
          audit.irs.gov tried to access
          http://mycompany.com/deployDemo/UrlTest2/business/tax-plan.html
          on Tue Dec 25 13:12:29 EDT 2001.

          程序清單5-12 Web.xml(說明filter用法的摘錄)
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!DOCTYPE web-app
          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "
          http://java.sun.com/dtd/web-app_2_3.dtd">

          <web-app>
          <filter>
          <filter-name>Reporter</filter-name>
          <filter-class>moresevlets.ReportFilter</filter-class>
          </filter>
          <!-- ... -->
          <filter-mapping>
          <filter-name>Reporter</filter-name>
          <servlet-name>PageName</servlet-name>
          </filter-mapping>
          <!-- ... -->
          <servlet>
          <servlet-name>PageName</servlet-name>
          <jsp-file>/RealPage.jsp</jsp-file>
          </servlet>
          <!-- ... -->
          <servlet-mapping>
          <servlet-name> PageName </servlet-name>
          <url-pattern>/UrlTest2/*</url-pattern>
          </servlet-mapping>
          <!-- ... -->
          </web-app>


          7 指定歡迎頁(yè)

          假如用戶提供了一個(gè)像http: //host/webAppPrefix/directoryName/ 這樣的包含一個(gè)目錄名但沒有包含文件名的URL,會(huì)發(fā)生什么事情呢?用戶能得到一個(gè)目錄表?一個(gè)錯(cuò)誤?還是標(biāo)準(zhǔn)文件的內(nèi)容?如果得到標(biāo)準(zhǔn)文件內(nèi)容,是 index.html、index.jsp、default.html、default.htm或別的什么東西呢?
          Welcome-file-list 元素及其輔助的welcome-file元素解決了這個(gè)模糊的問題。例如,下面的web.xml項(xiàng)指出,如果一個(gè)URL給出一個(gè)目錄名但未給出文件名,服務(wù)器應(yīng)該首先試用index.jsp,然后再試用index.html。如果兩者都沒有找到,則結(jié)果有賴于所用的服務(wù)器(如一個(gè)目錄列表)。
          <welcome-file-list>
          <welcome-file>index.jsp</welcome-file>
          <welcome-file>index.html</welcome-file>
          </welcome-file-list>
          雖然許多服務(wù)器缺省遵循這種行為,但不一定必須這樣。因此,明確地使用welcom-file-list保證可移植性是一種良好的習(xí)慣。

          8 指定處理錯(cuò)誤的頁(yè)面

          現(xiàn)在我了解到,你在開發(fā)servlet和JSP頁(yè)面時(shí)從不會(huì)犯錯(cuò)誤,而且你的所有頁(yè)面是那樣的清晰,一般的程序員都不會(huì)被它們的搞糊涂。但是,是人總會(huì)犯錯(cuò)誤的,用戶可能會(huì)提供不合規(guī)定的參數(shù),使用不正確的URL或者不能提供必需的表單字段值。除此之外,其它開發(fā)人員可能不那么細(xì)心,他們應(yīng)該有些工具來克服自己的不足。
          error-page元素就是用來克服這些問題的。它有兩個(gè)可能的子元素,分別是:error-code和exception- type。第一個(gè)子元素error-code指出在給定的HTTP錯(cuò)誤代碼出現(xiàn)時(shí)使用的URL。第二個(gè)子元素excpetion-type指出在出現(xiàn)某個(gè)給定的Java異常但未捕捉到時(shí)使用的URL。error-code和exception-type都利用location元素指出相應(yīng)的URL。此 URL必須以/開始。location所指出的位置處的頁(yè)面可通過查找HttpServletRequest對(duì)象的兩個(gè)專門的屬性來訪問關(guān)于錯(cuò)誤的信息,這兩個(gè)屬性分別是:javax.servlet.error.status_code和javax.servlet.error.message。
          可回憶一下,在web.xml內(nèi)以正確的次序聲明web-app的子元素很重要。這里只要記住,error-page出現(xiàn)在web.xml文件的末尾附近,servlet、servlet-name和welcome-file-list之后即可。

          8.1 error-code元素
          為了更好地了解error-code元素的值,可考慮一下如果不正確地輸入文件名,大多數(shù)站點(diǎn)會(huì)作出什么反映。這樣做一般會(huì)出現(xiàn)一個(gè)404錯(cuò)誤信息,它表示不能找到該文件,但幾乎沒提供更多有用的信息。另一方面,可以試一下在
          www.microsoft.comwww.ibm.com 處或者特別是在www.bea.com 處輸出未知的文件名。這是會(huì)得出有用的消息,這些消息提供可選擇的位置,以便查找感興趣的頁(yè)面。提供這樣有用的錯(cuò)誤頁(yè)面對(duì)于Web應(yīng)用來說是很有價(jià)值得。事實(shí)上rm-error-page子元素)。由form-login-page給出的HTML表單必須具有一個(gè)j_security_check的 ACTION屬性、一個(gè)名為j_username的用戶名文本字段以及一個(gè)名為j_password的口令字段。
          例如,程序清單5-19指示服務(wù)器使用基于表單的驗(yàn)證。Web應(yīng)用的頂層目錄中的一個(gè)名為login.jsp的頁(yè)面將收集用戶名和口令,并且失敗的登陸將由相同目錄中名為login-error.jsp的頁(yè)面報(bào)告。

          程序清單5-19 web.xml(說明login-config的摘錄)
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!DOCTYPE web-app
          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "
          http://java.sun.com/dtd/web-app_2_3.dtd">

          <web-app>
          <!-- ... -->
          <security-constraint> ... </security-constraint>
          <login-config>
          <auth-method> FORM </auth-method>
          <form-login-config>
          <form-login-page>/login.jsp</form-login-page>
          <form-error-page>/login-error.jsp</form-error-page>
          </form-login-config>
          </login-config>
          <!-- ... -->
          </web-app>


          9.2 限制對(duì)Web資源的訪問
          現(xiàn)在,可以指示服務(wù)器使用何種驗(yàn)證方法了。"了不起,"你說道,"除非我能指定一個(gè)來收到保護(hù)的 URL,否則沒有多大用處。"沒錯(cuò)。指出這些URL并說明他們應(yīng)該得到何種保護(hù)正是security-constriaint元素的用途。此元素在 web.xml中應(yīng)該出現(xiàn)在login-config的緊前面。它包含是個(gè)可能的子元素,分別是:web-resource-collection、 auth-constraint、user-data-constraint和display-name。下面各小節(jié)對(duì)它們進(jìn)行介紹。
          l web-resource-collection
          此元素確定應(yīng)該保護(hù)的資源。所有security-constraint元素都必須包含至少一個(gè)web-resource-collection項(xiàng)。此元素由一個(gè)給出任意標(biāo)識(shí)名稱的web-resource-name元素、一個(gè)確定應(yīng)該保護(hù)的URL的url-pattern元素、一個(gè)指出此保護(hù)所適用的 HTTP命令(GET、POST等,缺省為所有方法)的http-method元素和一個(gè)提供資料的可選description元素組成。例如,下面的 Web-resource-collection項(xiàng)(在security-constratint元素內(nèi))指出Web應(yīng)用的proprietary目錄中所有文檔應(yīng)該受到保護(hù)。
          <security-constraint>
          <web-resource-coolection>
          <web-resource-name>Proprietary</web-resource-name>
          <url-pattern>/propritary/*</url-pattern>
          </web-resource-coolection>
          <!-- ... -->
          </security-constraint>
          重要的是應(yīng)該注意到,url-pattern僅適用于直接訪問這些資源的客戶機(jī)。特別是,它不適合于通過MVC體系結(jié)構(gòu)利用 RequestDispatcher來訪問的頁(yè)面,或者不適合于利用類似jsp:forward的手段來訪問的頁(yè)面。這種不勻稱如果利用得當(dāng)?shù)脑捄苡泻锰帯@纾瑂ervlet可利用MVC體系結(jié)構(gòu)查找數(shù)據(jù),把它放到bean中,發(fā)送請(qǐng)求到從bean中提取數(shù)據(jù)的JSP頁(yè)面并顯示它。我們希望保證決不直接訪問受保護(hù)的JSP頁(yè)面,而只是通過建立該頁(yè)面將使用的bean的servlet來訪問它。url-pattern和auth-contraint元素可通過聲明不允許任何用戶直接訪問JSP頁(yè)面來提供這種保證。但是,這種不勻稱的行為可能讓開發(fā)人員放松警惕,使他們偶然對(duì)應(yīng)受保護(hù)的資源提供不受限制的訪問。
          l auth-constraint
          盡管web-resource-collention元素質(zhì)出了哪些URL應(yīng)該受到保護(hù),但是auth-constraint元素卻指出哪些用戶應(yīng)該具有受保護(hù)資源的訪問權(quán)。此元素應(yīng)該包含一個(gè)或多個(gè)標(biāo)識(shí)具有訪問權(quán)限的用戶類別role- name元素,以及包含(可選)一個(gè)描述角色的description元素。例如,下面web.xml中的security-constraint元素部門規(guī)定只有指定為Administrator或Big Kahuna(或兩者)的用戶具有指定資源的訪問權(quán)。
          <security-constraint>
          <web-resource-coolection> ... </web-resource-coolection>
          <auth-constraint>
          <role-name>administrator</role-name>
          <role-name>kahuna</role-name>
          </auth-constraint>
          </security-constraint>
          重要的是認(rèn)識(shí)到,到此為止,這個(gè)過程的可移植部分結(jié)束了。服務(wù)器怎樣確定哪些用戶處于任何角色以及它怎樣存放用戶的口令,完全有賴于具體的系統(tǒng)。
          例如,Tomcat使用install_dir/conf/tomcat-users.xml將用戶名與角色名和口令相關(guān)聯(lián),正如下面例子中所示,它指出用戶joe(口令bigshot)和jane(口令enaj)屬于administrator和kahuna角色。
          <tomcat-users>
          <user name="joe" password="bigshot" roles="administrator,kahuna" />
          <user name="jane" password="enaj" roles="kahuna" />
          </tomcat-users>
          l user-data-constraint
          這個(gè)可選的元素指出在訪問相關(guān)資源時(shí)使用任何傳輸層保護(hù)。它必須包含一個(gè)transport-guarantee子元素(合法值為NONE、 INTEGRAL或CONFIDENTIAL),并且可選地包含一個(gè)description元素。transport-guarantee為NONE值將對(duì)所用的通訊協(xié)議不加限制。INTEGRAL值表示數(shù)據(jù)必須以一種防止截取它的人閱讀它的方式傳送。雖然原理上(并且在未來的HTTP版本中),在 INTEGRAL和CONFIDENTIAL之間可能會(huì)有差別,但在當(dāng)前實(shí)踐中,他們都只是簡(jiǎn)單地要求用SSL。例如,下面指示服務(wù)器只允許對(duì)相關(guān)資源做 HTTPS連接:
          <security-constraint>
          <!-- ... -->
          <user-data-constraint>
          <transport-guarantee>CONFIDENTIAL</transport-guarantee>
          </user-data-constraint>
          </security-constraint>
          l display-name
          security-constraint的這個(gè)很少使用的子元素給予可能由GUI工具使用的安全約束項(xiàng)一個(gè)名稱。
          9.3 分配角色名
          迄今為止,討論已經(jīng)集中到完全由容器(服務(wù)器)處理的安全問題之上了。但servlet以及JSP頁(yè)面也能夠處理它們自己的安全問題。
          例如,容器可能允許用戶從bigwig或bigcheese角色訪問一個(gè)顯示主管人員額外緊貼的頁(yè)面,但只允許bigwig用戶修改此頁(yè)面的參數(shù)。完成這種更細(xì)致的控制的一種常見方法是調(diào)用HttpServletRequset的isUserInRole方法,并據(jù)此修改訪問。
          Servlet的 security-role-ref子元素提供出現(xiàn)在服務(wù)器專用口令文件中的安全角色名的一個(gè)別名。例如,假如編寫了一個(gè)調(diào)用 request.isUserInRole("boss")的servlet,但后來該servlet被用在了一個(gè)其口令文件調(diào)用角色manager而不是boss的服務(wù)器中。下面的程序段使該servlet能夠使用這兩個(gè)名稱中的任何一個(gè)。
          <servlet>
          <!-- ... -->
          <security-role-ref>
          <role-name>boss</role-name> <!-- New alias -->
          <role-link>manager</role-link> <!-- Real name -->
          </security-role-ref>
          </servlet>
          也可以在web-app內(nèi)利用security-role元素提供將出現(xiàn)在role-name元素中的所有安全角色的一個(gè)全局列表。分別地生命角色使高級(jí)IDE容易處理安全信息。

          10 控制會(huì)話超時(shí)

          如果某個(gè)會(huì)話在一定的時(shí)間內(nèi)未被訪問,服務(wù)器可把它扔掉以節(jié)約內(nèi)存。可利用HttpSession的setMaxInactiveInterval方法直接設(shè)置個(gè)別會(huì)話對(duì)象的超時(shí)值。如果不采用這種方法,則缺省的超時(shí)值由具體的服務(wù)器決定。但可利用session-config和session- timeout元素來給出一個(gè)適用于所有服務(wù)器的明確的超時(shí)值。超時(shí)值的單位為分鐘,因此,下面的例子設(shè)置缺省會(huì)話超時(shí)值為三個(gè)小時(shí)(180分鐘)。
          <session-config>
          <session-timeout>180</session-timeout>
          </session-config>

          11 Web應(yīng)用的文檔化

          越來越多的開發(fā)環(huán)境開始提供servlet和JSP的直接支持。例子有Borland Jbuilder Enterprise Edition、Macromedia UltraDev、Allaire JRun Studio(寫此文時(shí),已被Macromedia收購(gòu))以及IBM VisuaAge for Java等。
          大量的web.xml元素不僅是為服務(wù)器設(shè)計(jì)的,而且還是為可視開發(fā)環(huán)境設(shè)計(jì)的。它們包括icon、display-name和discription等。
          可回憶一下,在web.xml內(nèi)以適當(dāng)?shù)卮涡蚵暶鱳eb-app子元素很重要。不過,這里只要記住icon、display-name和description是web.xml的web-app元素內(nèi)的前三個(gè)合法元素即可。
          l icon
          icon元素指出GUI工具可用來代表Web應(yīng)用的一個(gè)和兩個(gè)圖像文件。可利用small-icon元素指定一幅16 x 16的GIF或JPEG圖像,用large-icon元素指定一幅32 x 32的圖像。下面舉一個(gè)例子:
          <icon>
          <small-icon>/images/small-book.gif</small-icon>
          <large-icon>/images/tome.jpg</large-icon>
          </icon>
          l display-name
          display-name元素提供GUI工具可能會(huì)用來標(biāo)記此Web應(yīng)用的一個(gè)名稱。下面是個(gè)例子。
          <display-name>Rare Books</display-name>
          l description
          description元素提供解釋性文本,如下所示:
          <description>
          This Web application represents the store developed for
          rare-books.com, an online bookstore specializing in rare
          and limited-edition books.
          </description>

          12 關(guān)聯(lián)文件與MIME類型

          服務(wù)器一般都具有一種讓W(xué)eb站點(diǎn)管理員將文件擴(kuò)展名與媒體相關(guān)聯(lián)的方法。例如,將會(huì)自動(dòng)給予名為mom.jpg的文件一個(gè)image/jpeg的MIME 類型。但是,假如你的Web應(yīng)用具有幾個(gè)不尋常的文件,你希望保證它們?cè)诎l(fā)送到客戶機(jī)時(shí)分配為某種MIME類型。mime-mapping元素(具有 extension和mime-type子元素)可提供這種保證。例如,下面的代碼指示服務(wù)器將application/x-fubar的MIME類型分配給所有以.foo結(jié)尾的文件。
          <mime-mapping>
          <extension>foo</extension>
          <mime-type>application/x-fubar</mime-type>
          </mime-mapping>
          或許,你的Web應(yīng)用希望重載(override)標(biāo)準(zhǔn)的映射。例如,下面的代碼將告訴服務(wù)器在發(fā)送到客戶機(jī)時(shí)指定.ps文件作為純文本(text/plain)而不是作為PostScript(application/postscript)。
          <mime-mapping>
          <extension>ps</extension>
          <mime-type>application/postscript</mime-type>
          </mime-mapping>


          13 定位TLD

          JSP taglib元素具有一個(gè)必要的uri屬性,它給出一個(gè)TLD(Tag Library Descriptor)文件相對(duì)于Web應(yīng)用的根的位置。TLD文件的實(shí)際名稱在發(fā)布新的標(biāo)簽庫(kù)版本時(shí)可能會(huì)改變,但我們希望避免更改所有現(xiàn)有JSP頁(yè)面。此外,可能還希望使用保持taglib元素的簡(jiǎn)練性的一個(gè)簡(jiǎn)短的uri。這就是部署描述符文件的taglib元素派用場(chǎng)的所在了。Taglib包含兩個(gè)子元素:taglib-uri和taglib-location。taglib-uri元素應(yīng)該與用于JSP taglib元素的uri屬性的東西相匹配。Taglib-location元素給出TLD文件的實(shí)際位置。例如,假如你將文件chart-tags- 1.3beta.tld放在WebApp/WEB-INF/tlds中。現(xiàn)在,假如web.xml在web-app元素內(nèi)包含下列內(nèi)容。
          <taglib>
          <taglib-uri>/charts.tld</taglib-uri>
          <taglib-location>
          /WEB-INF/tlds/chart-tags-1.3beta.tld
          </taglib-location>
          </taglib>
          給出這個(gè)說明后,JSP頁(yè)面可通過下面的簡(jiǎn)化形式使用標(biāo)簽庫(kù)。
          <%@ taglib uri="/charts.tld" prefix="somePrefix" %>

          14 指定應(yīng)用事件監(jiān)聽程序

          應(yīng)用事件監(jiān)聽器程序是建立或修改servlet環(huán)境或會(huì)話對(duì)象時(shí)通知的類。它們是servlet規(guī)范的版本2.3中的新內(nèi)容。這里只簡(jiǎn)單地說明用來向Web應(yīng)用注冊(cè)一個(gè)監(jiān)聽程序的web.xml的用法。
          注冊(cè)一個(gè)監(jiān)聽程序涉及在web.xml的web-app元素內(nèi)放置一個(gè)listener元素。在listener元素內(nèi),listener-class元素列出監(jiān)聽程序的完整的限定類名,如下所示:
          <listener>
          <listener-class>package.ListenerClass</listener-class>
          </listener>
          雖然listener元素的結(jié)構(gòu)很簡(jiǎn)單,但請(qǐng)不要忘記,必須正確地給出web-app元素內(nèi)的子元素的次序。listener元素位于所有的servlet 元素之前以及所有filter-mapping元素之后。此外,因?yàn)閼?yīng)用生存期監(jiān)聽程序是serlvet規(guī)范的2.3版本中的新內(nèi)容,所以必須使用 web.xml DTD的2.3版本,而不是2.2版本。
          例如,程序清單5-20給出一個(gè)名為ContextReporter的簡(jiǎn)單的監(jiān)聽程序,只要Web應(yīng)用的Servlet-Context建立(如裝載Web應(yīng)用)或消除(如服務(wù)器關(guān)閉)時(shí),它就在標(biāo)準(zhǔn)輸出上顯示一條消息。程序清單5-21給出此監(jiān)聽程序注冊(cè)所需要的web.xml文件的一部分。

          程序清單5-20 ContextReporterjava
          package moreservlets;

          import javax.servlet.*;
          import java.util.*;

          /** Simple listener that prints a report on the standard output
          * when the ServletContext is created or destroyed.
          * <P>
          * Taken from More Servlets and JavaServer Pages
          * from Prentice Hall and Sun Microsystems Press,
          *
          http://www.moreservlets.com/.
          * ? 2002 Marty Hall; may be freely used or adapted.
          */

          public class ContextReporter implements ServletContextListener {
          public void contextInitialized(ServletContextEvent event) {
          System.out.println("Context created on " +
          new Date() + ".");
          }

          public void contextDestroyed(ServletContextEvent event) {
          System.out.println("Context destroyed on " +
          new Date() + ".");
          }
          }


          程序清單5-21 web.xml(聲明一個(gè)監(jiān)聽程序的摘錄)
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!DOCTYPE web-app
          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "
          http://java.sun.com/dtd/web-app_2_3.dtd">

          <web-app>
          <!-- ... -->
          <filter-mapping> … </filter-mapping>
          <listener>
          <listener-class>package.ListenerClass</listener-class>
          </listener>
          <servlet> ... </servlet>
          <!-- ... -->
          </web-app>


          15 J2EE元素

          本節(jié)描述用作J2EE環(huán)境組成部分的Web應(yīng)用的web.xml元素。這里將提供一個(gè)簡(jiǎn)明的介紹,詳細(xì)內(nèi)容可以參閱
          http://java.sun.com/j2ee/j2ee-1_3-fr-spec.pdf的Java 2 Plantform Enterprise Edition版本1.3規(guī)范的第5章。
          l distributable
          distributable 元素指出,Web應(yīng)用是以這樣的方式編程的:即,支持集群的服務(wù)器可安全地在多個(gè)服務(wù)器上分布Web應(yīng)用。例如,一個(gè)可分布的應(yīng)用必須只使用 Serializable對(duì)象作為其HttpSession對(duì)象的屬性,而且必須避免用實(shí)例變量(字段)來實(shí)現(xiàn)持續(xù)性。distributable元素直接出現(xiàn)在discription元素之后,并且不包含子元素或數(shù)據(jù),它只是一個(gè)如下的標(biāo)志。
          <distributable />
          l resource-env-ref
          resource -env-ref元素聲明一個(gè)與某個(gè)資源有關(guān)的管理對(duì)象。此元素由一個(gè)可選的description元素、一個(gè)resource-env-ref- name元素(一個(gè)相對(duì)于java:comp/env環(huán)境的JNDI名)以及一個(gè)resource-env-type元素(指定資源類型的完全限定的類),如下所示:
          <resource-env-ref>
          <resource-env-ref-name>
          jms/StockQueue
          </resource-env-ref-name>
          <resource-env-ref-type>
          javax.jms.Queue
          </resource-env-ref-type>
          </resource-env-ref>
          l env-entry
          env -entry元素聲明Web應(yīng)用的環(huán)境項(xiàng)。它由一個(gè)可選的description元素、一個(gè)env-entry-name元素(一個(gè)相對(duì)于java: comp/env環(huán)境JNDI名)、一個(gè)env-entry-value元素(項(xiàng)值)以及一個(gè)env-entry-type元素(java.lang程序包中一個(gè)類型的完全限定類名,java.lang.Boolean、java.lang.String等)組成。下面是一個(gè)例子:
          <env-entry>
          <env-entry-name>minAmout</env-entry-name>
          <env-entry-value>100.00</env-entry-value>
          <env-entry-type>minAmout</env-entry-type>
          </env-entry>
          l ejb-ref
          ejb -ref元素聲明對(duì)一個(gè)EJB的主目錄的應(yīng)用。它由一個(gè)可選的description元素、一個(gè)ejb-ref-name元素(相對(duì)于java: comp/env的EJB應(yīng)用)、一個(gè)ejb-ref-type元素(bean的類型,Entity或Session)、一個(gè)home元素(bean的主目錄接口的完全限定名)、一個(gè)remote元素(bean的遠(yuǎn)程接口的完全限定名)以及一個(gè)可選的ejb-link元素(當(dāng)前bean鏈接的另一個(gè) bean的名稱)組成。
          l ejb-local-ref
          ejb-local-ref元素聲明一個(gè)EJB的本地主目錄的引用。除了用local-home代替home外,此元素具有與ejb-ref元素相同的屬性并以相同的方式使用。

          posted @ 2005-11-29 17:38 船夫 閱讀(385) | 評(píng)論 (0)編輯 收藏

          ↑→40種網(wǎng)頁(yè)常用小技巧(javascript)←↓------[不時(shí)之需](轉(zhuǎn)自CJSDN)


          1. oncontextmenu="window.event.returnValue=false" 將徹底屏蔽鼠標(biāo)右鍵
          <table border oncontextmenu=return(false)><td>no</table> 可用于Table

          2. <body onselectstart="return false"> 取消選取、防止復(fù)制

          3. onpaste="return false" 不準(zhǔn)粘貼

          4. oncopy="return false;" oncut="return false;" 防止復(fù)制

          5. <link rel="Shortcut Icon" href="favicon.ico"> IE地址欄前換成自己的圖標(biāo)

          6. <link rel="Bookmark" href="favicon.ico"> 可以在收藏夾中顯示出你的圖標(biāo)

          7. <input style="ime-mode:disabled"> 關(guān)閉輸入法

          8. 永遠(yuǎn)都會(huì)帶著框架
          <script language="JavaScript"><!--
          if (window == top)top.location.href = "frames.htm"; //frames.htm為框架網(wǎng)頁(yè)
          // --></script>

          9. 防止被人frame
          <SCRIPT LANGUAGE=JAVASCRIPT><!--
          if (top.location != self.location)top.location=self.location;
          // --></SCRIPT>

          10. 網(wǎng)頁(yè)將不能被另存為
          <noscript><iframe src=*.html></iframe></noscript>

          11. <input type=button value=查看網(wǎng)頁(yè)源代碼
          onclick="window.location = "view-source:"+ "http://www.pconline.com.cn"">

          12.刪除時(shí)確認(rèn)
          <a href="javascript:if(confirm("確實(shí)要?jiǎng)h除嗎?"))location="boos.asp?&areyou=刪除&page=1"">刪除</a>

          13. 取得控件的絕對(duì)位置
          //Javascript
          <script language="Javascript">
          function getIE(e){
          var t=e.offsetTop;
          var l=e.offsetLeft;
          while(e=e.offsetParent){
          t+=e.offsetTop;
          l+=e.offsetLeft;
          }
          alert("top="+t+"/nleft="+l);
          }
          </script>

          //VBScript
          <script language="VBScript"><!--
          function getIE()
          dim t,l,a,b
          set a=document.all.img1
          t=document.all.img1.offsetTop
          l=document.all.img1.offsetLeft
          while a.tagName<>"BODY"
          set a = a.offsetParent
          t=t+a.offsetTop
          l=l+a.offsetLeft
          wend
          msgbox "top="&t&chr(13)&"left="&l,64,"得到控件的位置"
          end function
          --></script>

          14. 光標(biāo)是停在文本框文字的最后
          <script language="javascript">
          function cc()
          {
          var e = event.srcElement;
          var r =e.createTextRange();
          r.moveStart("character",e.value.length);
          r.collapse(true);
          r.select();
          }
          </script>
          <input type=text name=text1 value="123" onfocus="cc()">

          15. 判斷上一頁(yè)的來源
          javascript:
          document.referrer

          16. 最小化、最大化、關(guān)閉窗口
          <object id=hh1 classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11">
          <param name="Command" value="Minimize"></object>
          <object id=hh2 classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11">
          <param name="Command" value="Maximize"></object>
          <OBJECT id=hh3 classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11">
          <PARAM NAME="Command" VALUE="Close"></OBJECT>
          <input type=button value=最小化 onclick=hh1.Click()>
          <input type=button value=最大化 onclick=hh2.Click()>
          <input type=button value=關(guān)閉 onclick=hh3.Click()>
          本例適用于IE

          17.屏蔽功能鍵Shift,Alt,Ctrl
          <script>
          function look(){
          if(event.shiftKey)
          alert("禁止按Shift鍵!"); //可以換成ALT CTRL
          }
          document.onkeydown=look;
          </script>

          18. 網(wǎng)頁(yè)不會(huì)被緩存
          <META HTTP-EQUIV="pragma" CONTENT="no-cache">
          <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate">
          <META HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1997 08:21:57 GMT">
          或者<META HTTP-EQUIV="expires" CONTENT="0">

          19.怎樣讓表單沒有凹凸感?
          <input type=text style="border:1 solid #000000">

          <input type=text style="border-left:none; border-right:none; border-top:none; border-bottom:

          1 solid #000000"></textarea>

          20.<div><span>&<layer>的區(qū)別?
          <div>(division)用來定義大段的頁(yè)面元素,會(huì)產(chǎn)生轉(zhuǎn)行
          <span>用來定義同一行內(nèi)的元素,跟<div>的唯一區(qū)別是不產(chǎn)生轉(zhuǎn)行
          <layer>是ns的標(biāo)記,ie不支持,相當(dāng)于<div>

          21.讓彈出窗口總是在最上面:
          <body onblur="this.focus();">

          22.不要滾動(dòng)條?
          讓豎條沒有:
          <body style="overflow:scroll;overflow-y:hidden">
          </body>
          讓橫條沒有:
          <body style="overflow:scroll;overflow-x:hidden">
          </body>
          兩個(gè)都去掉?更簡(jiǎn)單了
          <body scroll="no">
          </body>

          23.怎樣去掉圖片鏈接點(diǎn)擊后,圖片周圍的虛線?
          <a href="#" onFocus="this.blur()"><img src="logo.jpg" border=0></a>

          24.電子郵件處理提交表單
          <form name="form1" method="post" action="mailto:****@***.com" enctype="text/plain">
          <input type=submit>
          </form>

          25.在打開的子窗口刷新父窗口的代碼里如何寫?
          window.opener.location.reload()

          26.如何設(shè)定打開頁(yè)面的大小
          <body onload="top.resizeTo(300,200);">
          打開頁(yè)面的位置<body onload="top.moveBy(300,200);">

          27.在頁(yè)面中如何加入不是滿鋪的背景圖片,拉動(dòng)頁(yè)面時(shí)背景圖不動(dòng)
          <STYLE>
          body
          {background-image:url(logo.gif); background-repeat:no-repeat;
          background-position:center;background-attachment: fixed}
          </STYLE>

          28. 檢查一段字符串是否全由數(shù)字組成
          <script language="Javascript"><!--
          function checkNum(str){return str.match(//D/)==null}
          alert(checkNum("1232142141"))
          alert(checkNum("123214214a1"))
          // --></script>

          29. 獲得一個(gè)窗口的大小
          document.body.clientWidth; document.body.clientHeight

          30. 怎么判斷是否是字符
          if (/[^/x00-/xff]/g.test(s)) alert("含有漢字");
          else alert("全是字符");

          31.TEXTAREA自適應(yīng)文字行數(shù)的多少
          <textarea rows=1 name=s1 cols=27 onpropertychange="this.style.posHeight=this.scrollHeight">
          </textarea>

          32. 日期減去天數(shù)等于第二個(gè)日期
          <script language=Javascript>
          function cc(dd,dadd)
          {
          //可以加上錯(cuò)誤處理
          var a = new Date(dd)
          a = a.valueOf()
          a = a - dadd * 24 * 60 * 60 * 1000
          a = new Date(a)
          alert(a.getFullYear() + "年" + (a.getMonth() + 1) + "月" + a.getDate() + "日")
          }
          cc("12/23/2002",2)
          </script>

          33. 選擇了哪一個(gè)Radio
          <HTML><script language="vbscript">
          function checkme()
          for each ob in radio1
          if ob.checked then window.alert ob.value
          next
          end function
          </script><BODY>
          <INPUT name="radio1" type="radio" value="style" checked>Style
          <INPUT name="radio1" type="radio" value="barcode">Barcode
          <INPUT type="button" value="check" onclick="checkme()">
          </BODY></HTML>

          34.腳本永不出錯(cuò)
          <SCRIPT LANGUAGE="JavaScript">
          <!-- Hide
          function killErrors() {
          return true;
          }
          window.onerror = killErrors;
          // -->
          </SCRIPT>

          35.ENTER鍵可以讓光標(biāo)移到下一個(gè)輸入框
          <input onkeydown="if(event.keyCode==13)event.keyCode=9">

          36. 檢測(cè)某個(gè)網(wǎng)站的鏈接速度:
          把如下代碼加入<body>區(qū)域中:
          <script language=Javascript>
          tim=1
          setInterval("tim++",100)
          b=1
          var autourl=new Array()
          autourl[1]="www.njcatv.net"
          autourl[2]="javacool.3322.net"
          autourl[3]="www.sina.com.cn"
          autourl[4]="www.nuaa.edu.cn"
          autourl[5]="www.cctv.com"
          function butt(){
          document.write("<form name=autof>")
          for(var i=1;i<autourl.length;i++)
          document.write("<input type=text name=txt"+i+" size=10 value=測(cè)試中……> =》<input type=text
          name=url"+i+" size=40> =》<input type=button value=GO

          onclick=window.open(this.form.url"+i+".value)><br>")
          document.write("<input type=submit value=刷新></form>")
          }
          butt()
          function auto(url){
          document.forms[0]["url"+b].value=url
          if(tim>200)
          {document.forms[0]["txt"+b].value="鏈接超時(shí)"}
          else
          {document.forms[0]["txt"+b].value="時(shí)間"+tim/10+"秒"}
          b++
          }
          function run(){for(var i=1;i<autourl.length;i++)document.write("<img src=http://"+autourl+"/"+Math.random()+"

          width=1 height=1

          onerror=auto("http://"+autourl+"")>")}
          run()</script>

          37. 各種樣式的光標(biāo)
          auto :標(biāo)準(zhǔn)光標(biāo)
          default :標(biāo)準(zhǔn)箭頭
          hand :手形光標(biāo)
          wait :等待光標(biāo)
          text :I形光標(biāo)
          vertical-text :水平I形光標(biāo)
          no-drop :不可拖動(dòng)光標(biāo)
          not-allowed :無(wú)效光標(biāo)
          help :?幫助光標(biāo)
          all-scroll :三角方向標(biāo)
          move :移動(dòng)標(biāo)
          crosshair :十字標(biāo)
          e-resize
          n-resize
          nw-resize
          w-resize
          s-resize
          se-resize
          sw-resize

          38.頁(yè)面進(jìn)入和退出的特效
          進(jìn)入頁(yè)面<meta http-equiv="Page-Enter" content="revealTrans(duration=x, transition=y)">
          推出頁(yè)面<meta http-equiv="Page-Exit" content="revealTrans(duration=x, transition=y)">
          這個(gè)是頁(yè)面被載入和調(diào)出時(shí)的一些特效。duration表示特效的持續(xù)時(shí)間,以秒為單位。transition表示使用哪種特效,取值為

          1-23:
            0 矩形縮小
            1 矩形擴(kuò)大
            2 圓形縮小
            3 圓形擴(kuò)大
            4 下到上刷新
            5 上到下刷新
            6 左到右刷新
            7 右到左刷新
            8 豎百葉窗
            9 橫百葉窗
            10 錯(cuò)位橫百葉窗
            11 錯(cuò)位豎百葉窗
            12 點(diǎn)擴(kuò)散
            13 左右到中間刷新
            14 中間到左右刷新
            15 中間到上下
            16 上下到中間
            17 右下到左上
            18 右上到左下
            19 左上到右下
            20 左下到右上
            21 橫條
            22 豎條
            23 以上22種隨機(jī)選擇一種

          39.在規(guī)定時(shí)間內(nèi)跳轉(zhuǎn)
          <META http-equiv=V="REFRESH" content="5;URL=http://www.51js.com">

          40.網(wǎng)頁(yè)是否被檢索
          <meta name="ROBOTS" content="屬性值">
            其中屬性值有以下一些:
            屬性值為"all": 文件將被檢索,且頁(yè)上鏈接可被查詢;
            屬性值為"none": 文件不被檢索,而且不查詢頁(yè)上的鏈接;
            屬性值為"index": 文件將被檢索;
            屬性值為"follow": 查詢頁(yè)上的鏈接;
            屬性值為"noindex": 文件不檢索,但可被查詢鏈接;
            屬性值為"nofollow": 文件不被檢索,但可查詢頁(yè)上的鏈接。

          posted @ 2005-11-29 09:27 船夫 閱讀(234) | 評(píng)論 (0)編輯 收藏

          無(wú)法刷新include的jsp的問題

                這幾天在寫web表現(xiàn)層的東西,由于對(duì)jsp不是很熟悉,在使用include的時(shí)候就遇到了問題。
                可能是用OOP久了,寫什么都想封裝起來,寫jsp的時(shí)候就想使用include。我在一個(gè)parent.jsp中使用
          <%@include file="sub.jsp"%>
          include了一個(gè)sub.jsp,之后就發(fā)現(xiàn)我在刷新parent.jsp的時(shí)候不能同時(shí)刷新sub.jsp,百思不得其解,聽高手說把IE的Cache禁用了就行了,但使用
          <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
          這個(gè)禁了之后還是不行,最后到論壇上逛了一圈兒才發(fā)現(xiàn)原來是我的標(biāo)簽使用錯(cuò)了,應(yīng)該使用jsp:include標(biāo)簽,@include file主要用于靜態(tài)的內(nèi)容引用,就相當(dāng)于把被引用的文件代碼(sub.jsp)直接copy到主頁(yè)面(parent.jsp)中。而jsp:include可以隨時(shí)更新sub.jsp的內(nèi)容,只要把屬性flush設(shè)為true。
          要詳細(xì)了解的可以看看以下兩篇文章:
          http://www-900.ibm.com/developerWorks/cn/java/j-jsp04153/
          http://www-900.ibm.com/developerWorks/cn/java/j-jsp04293/

          posted @ 2005-11-23 15:26 船夫 閱讀(1627) | 評(píng)論 (1)編輯 收藏

          網(wǎng)頁(yè)中META標(biāo)簽的使用

          Meta 標(biāo)簽放在每個(gè)網(wǎng)頁(yè)的<head>...</head>中,我們大家比較熟悉的如: 

          <meta name="GENERATOR" content="Microsoft FrontPage 3.0">說明編輯工具;
          <meta name="KEYWORDS" content="...">說明關(guān)鍵詞;
          <meta name="DESCRIPTION" content="...">說明主頁(yè)描述;

          <meta http-equiv="Content-Type" content="text/html; charset=gb_2312-80">和
          <meta http-equiv="Content-Language" content="zh-CN">說明所用語(yǔ)言及文字... 

          可見META有兩種,name和http-equiv。 

          name主要用于描述網(wǎng)頁(yè),對(duì)應(yīng)于content,以便于搜索引擎機(jī)器人查找、分類(目 前幾乎所有的搜索引擎都使用網(wǎng)上機(jī)器人自動(dòng)查找META值來給你的網(wǎng)頁(yè)分類)。這其中最重要的是DESCRIPTION(你的站點(diǎn)在引擎上的描述)和KEYWORDS(搜索引 擎籍以分類的關(guān)鍵詞),應(yīng)該給你的“每一頁(yè)”都插入這兩個(gè)META值。當(dāng)然你也可以不要搜索引擎檢索,可用: 
          <meta name="ROBOTS" content="all | none | index | noindex | follow | nofollow"> 來確定:
          設(shè)定為"all"時(shí)文件將被檢索,且頁(yè)上鏈接可被查詢;
          設(shè)定為"none"則表示文件不被檢索,而且不查詢頁(yè)上的鏈接;
          設(shè)定為"index"時(shí)文件將被檢索;
          設(shè)定為"follow"則可查詢頁(yè)上的鏈接;
          設(shè)定為"noindex"時(shí)文件不檢索,但可被查詢鏈接;
          設(shè)定為"nofollow"則表示文件不被檢索,但可查詢頁(yè)上的鏈接.

          http-equiv顧名思義相當(dāng)于http文件頭的作用,可以直接影響網(wǎng)頁(yè)的傳輸。比較 直接的例子如: 

          1、自動(dòng)刷新,并指向新網(wǎng)頁(yè)
          <meta http-equiv="Refresh" content="10; url= http://yourlink"> 10秒后刷新到http://yourlink;

          2、網(wǎng)頁(yè)間轉(zhuǎn)換時(shí)加入效果
          <meta http-equiv="Page-Enter" content="revealTrans(duration=10, transition=50)"> 
          <meta http-equiv="Page-Exit" content="revealTrans(duration=20, transition=6)"> 
          加在一個(gè)網(wǎng)頁(yè)中,進(jìn)出時(shí)有一些特殊效果,這個(gè)功能即FrontPage 98的Format/Page Transition.不過注意所加網(wǎng)頁(yè)不能是一個(gè)Frame頁(yè);

          3、強(qiáng)制網(wǎng)頁(yè)不被存入Cache中
          <meta http-equiv="pragma" content="no-cache"> 
          <meta http-equiv="expires" content="wed, 26 Feb 1997 08:21:57 GMT"> 
          大家可以到http://www.internet.com上看看,它的首頁(yè)當(dāng)你斷線后,就無(wú)法在cache中再調(diào)出。(本身是關(guān)于建站很棒的站點(diǎn))

          4、定義指向窗口
          <meta http-equiv="window-target" content="_top">
          可以防止網(wǎng)頁(yè)被別人作為一個(gè)Frame調(diào)用.(不過,我試了一下,似乎不靈) 

          Meta還有很多功能, 如大家關(guān)心的 "怎樣在搜索引擎中,被放在搜索結(jié)果前面的 位置"( http://vancouver-webpages.com/VWbot/mk-metas.html). 你可以在以下站點(diǎn)進(jìn)一步查詢:http://webdeveloper.com/categories/html/ html_metatag_res.html
          http://vancouver-webpages.com/META/
          http://www.nlc-bnc.ca/ifla/II/metadata.htm

          posted @ 2005-11-17 17:05 船夫 閱讀(338) | 評(píng)論 (0)編輯 收藏

          糾錯(cuò)步驟

          1.仔細(xì)認(rèn)真的檢查以確定是否是真的代碼問題
          2.

          posted @ 2005-11-17 15:57 船夫 閱讀(247) | 評(píng)論 (0)編輯 收藏

          HTML標(biāo)簽詳解

          --  HTML標(biāo)簽詳解
          HTML指令詳解
          結(jié)構(gòu)
          <html>
          <head>
          <title>標(biāo)題<title>
          </head>
          <body>..........文件內(nèi)容..........
          </body>
          </html>
          1.文件標(biāo)題
          <title>..........</title>
          2.文件更新--<meta>
           【1】10秒后自動(dòng)更新一次
            <meta http-equiv="refresh" content=10>
           【2】10秒後自動(dòng)連結(jié)到另一文件
            <meta http-equiv="refresh" content="10;URL=欲連結(jié)文件之URL">
          3.查詢用表單--<isindex>
             若欲設(shè)定查詢欄位前的提示文字:
            <isindex prompt="提示文字">
          4.預(yù)設(shè)的基準(zhǔn)路徑--<base>
             <base href="放置文件的主機(jī)之URL">
          版面
          1.標(biāo)題文字 <h#>..........</h#> #=1~6;h1為最大字,h6為最小字
          2.字體變化 <font>..........</font> 
          【1】字體大小 <font size=#>..........</font> #=1~7;數(shù)字愈大字也愈大 
          【2】指定字型 <font face="字型名稱">..........</font> 
          【3】文字顏色 <font color=#rrggbb>..........</font> rr:表紅色(red)色碼 gg:表綠色(green)色碼 bb:表藍(lán)色(blue)色碼
          3.顯示小字體 <small>..........</small> 
          4.顯示大字體 <big>..........</big>
          5.粗體字 <b>..........</b>
          6.斜體字 <i>..........</i> 
          7.打字機(jī)字體 <tt>..........</tt>
          8.底線 <u>..........</u>
          9.刪除線 <strike>..........</strike>
          10.下標(biāo)字 <sub>..........</sub>
          11.上標(biāo)字 <sup>..........</sup>
          12.文字閃爍效果 <blink>..........</blink>
          13.換行 <br>
          14.分段 <p> 
          15.文字的對(duì)齊方向 <p align="#"> #號(hào)可為 left:表向左對(duì)齊(預(yù)設(shè)值) center:表向中對(duì)齊 right:表向右對(duì)齊 P.S.<p align="#">之後的文字都會(huì)以所設(shè)的對(duì)齊方式顯示, 直到出現(xiàn)另一個(gè)<p align="#">改變其對(duì)齊方向,或遇到 <hr>ⅱ<h#>標(biāo)簽時(shí)會(huì)自動(dòng)設(shè)回預(yù)設(shè)的向左對(duì)齊。
          16.分隔線 <hr> 
          【1】分隔線的粗細(xì) <hr size=點(diǎn)數(shù)> 
          【2】分隔線的寬度 <hr size=點(diǎn)數(shù)或百分比> 
          【3】分隔線對(duì)齊方向 <hr align="#"> #號(hào)可為 left:表向左對(duì)齊(預(yù)設(shè)值) center:表向中對(duì)齊 right:表向右對(duì)齊 
          【4】分隔線的顏色 <hr color=#rrggbb> 
          【5】實(shí)心分隔線 <hr noshade>
          17.向中對(duì)齊 <center>..........</center>
          18.依原始樣式顯示 <pre>..........</pre>
          19.<body>指令的屬性 
          【1】背景顏色 -- bgcolor <body bgcolor=#rrggbb> 
          【2】背景圖案 -- background <body background="圖形文件名"> 
          【3】設(shè)定背景圖案不會(huì)卷動(dòng) -- bgproperties <body bgproperties=fixed> 
          【4】文件內(nèi)容文字的顏色 -- text <body text=#rrggbb> 
          【5】超連結(jié)文字顏色 -- link <body link=#rrggbb> 
          【6】正被選取的超連結(jié)文字顏色 -- vlink <body vlink=#rrggbb> 
          【7】已連結(jié)過的超連結(jié)文字顏色 -- alink <body alink=#rrggbb>
          20.注解 <!--..........-->21.特殊字元表示法 
          符 號(hào)   語(yǔ) 法  
          <     &lt  
          >     &gt  
          &     &amp  
          "     &quot  
          空白    &nbsp  

           

          圖片
          1.插入圖片 <img src="圖形文件名">
          2.設(shè)定圖框 -- border <img src="圖形文件名" border=點(diǎn)數(shù)>
          3.設(shè)定圖形大小 -- widthⅱheight <img src="圖形文件名" width=寬度點(diǎn)數(shù) height=高度點(diǎn)數(shù)>
          4.設(shè)定圖形上下左右留空 -- vspaceⅱhspace <img src="圖形文件名" vspace=上下留空點(diǎn)數(shù) hspace=左右留空點(diǎn)數(shù)>
          5.圖形附注 <img src="圖形文件名" alt="說明文字">
          6.預(yù)載圖片
          <img src="高解析度圖形文件名" lowsrc="低解析度圖形文件名"> P.S.兩個(gè)圖的圖形大小最好一致
          7.影像地圖(Image Map) <img src="圖形文件名" usemap="#圖的名稱"> <map name="圖的名稱">
                 <area shape=形狀 coords=區(qū)域座標(biāo)列表 href="連結(jié)點(diǎn)之URL">
                 <area shape=形狀 coords=區(qū)域座標(biāo)列表 href="連結(jié)點(diǎn)之URL">
                 <area shape=形狀 coords=區(qū)域座標(biāo)列表 href="連結(jié)點(diǎn)之URL">
                 <area shape=形狀 coords=區(qū)域座標(biāo)列表 href="連結(jié)點(diǎn)之URL">    </map>    
          【1】定義形狀 -- shape
                 shape=rect:矩形         shape=circle:圓形         shape=poly:多邊形    
          【2】定義區(qū)域 -- coords
          a.矩形:必須使用四個(gè)數(shù)字,前兩個(gè)數(shù)字為左上角座標(biāo),后兩個(gè)數(shù)字為右下角座標(biāo)
          例:<area shape=rect coords=100,50,200,75 href="URL">
          b.圓形:必須使用三個(gè)數(shù)字,前兩個(gè)數(shù)字為圓心的座標(biāo),最后一個(gè)數(shù)字為半徑長(zhǎng)度
          例:<area shape=circle coords=85,155,30 href="URL">
          c.任意圖形(多邊形):將圖形之每一轉(zhuǎn)折點(diǎn)座標(biāo)依序填入
          例:<area shape=poly coords=232,70,285,70,300,90,250,90,200,78 href="URL">
          表格
          1.定義表格 <table>..........</table> 
          【1】設(shè)定邊框的厚度 -- border
          <table border=點(diǎn)數(shù)> 
          【2】設(shè)定格線的寬度 -- cellspacing
          <table cellspacing=點(diǎn)數(shù)> 
          【3】設(shè)定資料與格線的距離 -- cellpadding
          <table cellpadding=點(diǎn)數(shù)> 
          【4】調(diào)整表格寬度 -- width
          <table width=點(diǎn)數(shù)或百分比> 
          【5】調(diào)整表格高度 -- height
          <table height=點(diǎn)數(shù)或百分比> 
          【6】設(shè)定表格背景色彩 -- bgcolor
          <table bgcolor=#rrggbb> 
          【7】設(shè)定表格邊框色彩 -- bordercolor
          <table bordercolor=#rrggbb>
          2.顯示格線 <table border>
          3.表格標(biāo)題
          <caption>..........</caption> 
          表格標(biāo)題位置 -- align
          <caption align="#"> #號(hào)可為 top:表標(biāo)題置于表格上方(預(yù)設(shè)值)
          bottom:表標(biāo)題置于表格下方
          4.定義列 <tr>
          5.定義欄位 《1》<td>:靠左對(duì)齊
          《2》<th>:靠中對(duì)齊ⅱ粗體 
          【1】水平位置 -- align <th align="#">
          #號(hào)可為 left:向左對(duì)齊
          center:向中對(duì)齊 right:向右對(duì)齊
          【2】垂直位置 -- align <th align="#"> #號(hào)可為
          top:向上對(duì)齊 middle:向中對(duì)齊
          bottom:向下對(duì)齊 
          【3】欄位寬度 -- width
          <th width=點(diǎn)數(shù)或百分比> 
          【4】欄位垂直合并 -- rowspan
          <th rowspan=欲合并欄位數(shù)> 
          【5】欄位橫向合并 -- colspan
          <th colspan=欲合并欄位數(shù)>
          清單
          一、目錄式清單 
          <dir> <li>項(xiàng)目1 <li>項(xiàng)目2 <li>項(xiàng)目3 </dir> P.S.目錄式清單每一個(gè)項(xiàng)目不能超過20個(gè)字元(即10個(gè)中文字)
          二、選項(xiàng)式清單 <menu> <li>項(xiàng)目1 <li>項(xiàng)目2 <li>項(xiàng)目3 </menu>
          三、有序號(hào)的清單 <o(jì)l> <li>項(xiàng)目1 <li>項(xiàng)目2 <li>項(xiàng)目3 </ol> 
          【1】序號(hào)形式 -- type <o(jì)l type=#>或<li type=#> #號(hào)可為 A:表以大寫英文字母AⅱBⅱCⅱD...做為項(xiàng)目編號(hào) a:表以小寫英文字母aⅱbⅱcⅱd...做為項(xiàng)目編號(hào) I:表以大寫羅馬數(shù)字做為項(xiàng)目編號(hào) i:表以小寫羅馬數(shù)字做為項(xiàng)目編號(hào) 1:表以阿拉伯?dāng)?shù)字做為項(xiàng)目編號(hào)(預(yù)設(shè)值) 
          【2】起始數(shù)字 -- start <o(jì)l start=欲開始計(jì)數(shù)的序數(shù)> 
          【3】指定編號(hào) -- value <li value=欲指定的序數(shù)>
          四、無(wú)序號(hào)的清單 <ul> <li>項(xiàng)目1 <li>項(xiàng)目2 <li>項(xiàng)目3 </ul> 
          【1】項(xiàng)目符號(hào)形式 -- type <ul type=#>或<li type=#> #號(hào)可為 disc:實(shí)心圓點(diǎn)(預(yù)設(shè)值) circle:空心圓點(diǎn) square:實(shí)心方塊 
          【2】原始清單 -- plain <ul plain> 
          【3】清單排列方式 -- warp 《1》清單垂直排列 <ul warp = vert> 《2》清單水平排列 <ul warp = horiz>
          五、定義式清單 <dl> <dt>項(xiàng)目1 <dd>項(xiàng)目1說明 <dt>項(xiàng)目2 <dd>項(xiàng)目2說明 <dt>項(xiàng)目3 <dd>項(xiàng)目3說明 </dl> 
          緊密排列 -- compact <dl compact> P.S.如此可使<dt>的內(nèi)容與<dd>的內(nèi)容在同一行,僅 以數(shù)格空白相隔而不換行,但若<dt>的文字超過一 定的長(zhǎng)度后,compact的作用就消失了!
          表單
          一、基本架構(gòu) <form action="處理資料用的CGI程式之URL"或"mailto:電子信箱的URL" method="get或post"> .......... .......... .......... </form> 
          二、輸入文件型表單 <form action="URL" method="post"> <input> <input> .......... .......... </form> 
          【1】欄位類型 -- type <input type=#> #號(hào)可為 text:文字輸入 password:密碼 checkbox:多選鈕 radio:?jiǎn)芜x鈕 submit:接受按鈕 reset:重設(shè)按鈕 image:圖形鈕 hidden:隱藏欄位 
          【2】欄位名稱 -- name <input name="資料欄名"> P.S.若type為submitⅱreset則name不必設(shè)定 
          【3】文件上的預(yù)設(shè)值 -- value <input value="預(yù)設(shè)之字串"> 
          【4】設(shè)定欄位的寬度 -- size <input size=字元數(shù)> 
          【5】限制最大輸入字串的長(zhǎng)度 -- maxlength <input maxlength=字元數(shù)> 
          【6】預(yù)設(shè)checkbox或radio的初值 -- checked <input type=checkbox checked> <input type=radio checked> 
          【7】指定圖形的URL -- src <input type=image src="圖檔名"> 
          【8】圖文對(duì)齊 -- align <input type=image align="#"> #號(hào)可為 top:文字對(duì)齊圖片之頂端 middle:文字對(duì)齊圖片之中間 buttom:文字對(duì)齊圖片之底部
          三、選擇式表單 <form action="URL" method="post"> <select> <o(jì)ption> <o(jì)ption> .......... .......... </select> </form> 
          A、<select>的屬性 
          【1】欄位名稱 -- name <select name="資料欄位名"> 
          【2】設(shè)定顯示的選項(xiàng)數(shù) -- size <select size=個(gè)數(shù)> 
          【3】多重選項(xiàng) -- multiple <select multiple> 
          B、<o(jì)ption>的屬性 
          【1】定義選項(xiàng)的傳回值 -- value <o(jì)ption value="傳回值"> 
          【2】預(yù)先選取的選項(xiàng) -- selected <o(jì)ption selected>
          四、多列輸入文字區(qū)表單 <form action="URL" method="post"> <textarea> .......... .......... </textarea> </form> 
          【1】文字區(qū)的變數(shù)名稱 -- name <textarea name=變數(shù)名稱> 
          【2】設(shè)定文字輸入?yún)^(qū)寬度 -- cols <textarea cols=字元數(shù)> 
          【3】設(shè)定文字輸入?yún)^(qū)高度 -- rows <textarea rows=列數(shù)> 
          【4】輸入?yún)^(qū)設(shè)定預(yù)設(shè)字串 <textarea> 預(yù)設(shè)文字 </textarea> 
          【5】自動(dòng)換行與否 -- wrap <textarea wrap=#> #號(hào)可為 off:表輸入的文字超過欄寬時(shí),不會(huì)自動(dòng)換行(預(yù)設(shè)值) virtual:表輸入的文字在超過欄寬時(shí)會(huì)自動(dòng)換行
          鏈接
          一、連結(jié)至其他文件 <a href="URL">說明文字或圖片</a>
          二、連結(jié)至文件內(nèi)之某一處(外部連結(jié)) 
          《1》起點(diǎn)
          <a href="檔名#名稱">..........</a> 
          《2》終點(diǎn) <a name="名稱">
          三、frame的超連結(jié) 
          【1】開啟新的瀏覽器來顯示連結(jié)文件 -- _blank <a href="URL" target=_blank>
          【2】顯示連結(jié)文件於目前的frame -- _self <a href="URL" target=_self>
          【3】以上一層的分割視窗顯示連結(jié)文件 -- _parent <a href="URL" target=_parent>
          【4】以全視窗顯示連結(jié)文件 -- _top <a href="URL" target=_top> 
          【5】以特定視窗顯示連結(jié)文件 --<a href="URL" target="特定視窗名稱">
          FRAME
          一、分割視窗指令 <frameset>..........</frameset> 
          【1】垂直(上下)分割 -- rows
          <frameset rows=#> #號(hào)可為點(diǎn)數(shù):如欲分割為100,200,300三個(gè)視窗,則
          <frameset rows=100,200,300>;亦可以*號(hào)代表,如<frameset rows=*,500,*>
          百分比:如<frameset rows=30%,70%>,各 項(xiàng)總和最好為100%
          【2】水平(左右)分割 -- cols <frameset cols=點(diǎn)數(shù)或百分比>
          二ⅱ指定視窗內(nèi)容 -- <frame>
          <frameset cols=30%,70%>    <frame>    <frame> </frameset>
          【1】指定視窗的文件名稱 -- src <frame src=HTML檔名> 
          【2】定義視窗的名稱 -- name
          <frame name=視窗名稱> 
          【3】設(shè)定文件與上下邊框的距離 -- marginheight
          <frame marginheight=點(diǎn)數(shù)> 
          【4】設(shè)定文件與左右邊框的距離 -- marginwidth
          <frame marginwidth=點(diǎn)數(shù)> 
          【5】設(shè)定分割視窗卷軸 -- scrolling
          <frame scrolling=#> #號(hào)可為 yes:固定出現(xiàn)卷軸
          no:不出現(xiàn)卷軸 auto:自動(dòng)判斷文件大小需不需要卷軸(預(yù)設(shè)值)
          【6】鎖住分割視窗的大小 -- noresize <frame noresize>

          posted @ 2005-11-17 15:21 船夫 閱讀(376) | 評(píng)論 (1)編輯 收藏

          IBATIS SQLMap詳解

               摘要: Tag: IBATIS    SQL    Maps                           &n...  閱讀全文

          posted @ 2005-11-09 19:17 船夫 閱讀(9926) | 評(píng)論 (6)編輯 收藏

          [數(shù)據(jù)庫(kù)]JDBC連接數(shù)據(jù)庫(kù)經(jīng)驗(yàn)技巧集萃(轉(zhuǎn)載自Blog For Everyone)

          Java數(shù)據(jù)庫(kù)連接(JDBC)由一組用 Java 編程語(yǔ)言編寫的類和接口組成。JDBC 為工具/數(shù)據(jù)庫(kù)開發(fā)人員提供了一個(gè)標(biāo)準(zhǔn)的 API,使他們能夠用純Java API 來編寫數(shù)據(jù)庫(kù)應(yīng)用程序。然而各個(gè)開發(fā)商的接口并不完全相同,所以開發(fā)環(huán)境的變化會(huì)帶來一定的配置變化。本文主要集合了不同數(shù)據(jù)庫(kù)的連接方式。

            一、連接各種數(shù)據(jù)庫(kù)方式速查表

            下面羅列了各種數(shù)據(jù)庫(kù)使用JDBC連接的方式,可以作為一個(gè)手冊(cè)使用。

            1、Oracle8/8i/9i數(shù)據(jù)庫(kù)(thin模式)

          Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
          String url="jdbc:oracle:thin:@localhost:1521:orcl"; //orcl為數(shù)據(jù)庫(kù)的SID
          String user="test";
          String password="test";
          Connection conn= DriverManager.getConnection(url,user,password);

            2、DB2數(shù)據(jù)庫(kù)

          Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance();
          String url="jdbc:db2://localhost:5000/sample"; //sample為你的數(shù)據(jù)庫(kù)名
          String user="admin";
          String password="";
          Connection conn= DriverManager.getConnection(url,user,password);

            3、Sql Server7.0/2000數(shù)據(jù)庫(kù)

          Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
          String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb";
          //mydb為數(shù)據(jù)庫(kù)
          String user="sa";
          String password="";
          Connection conn= DriverManager.getConnection(url,user,password);

            4、Sybase數(shù)據(jù)庫(kù)

          Class.forName("com.sybase.jdbc.SybDriver").newInstance();
          String url =" jdbc:sybase:Tds:localhost:5007/myDB";//myDB為你的數(shù)據(jù)庫(kù)名
          Properties sysProps = System.getProperties();
          SysProps.put("user","userid");
          SysProps.put("password","user_password");
          Connection conn= DriverManager.getConnection(url, SysProps);

            5、Informix數(shù)據(jù)庫(kù)

          Class.forName("com.informix.jdbc.IfxDriver").newInstance();
          String url = "jdbc:informix-sqli://123.45.67.89:1533/myDB:INFORMIXSERVER=myserver;
          user=testuser;password=testpassword"; //myDB為數(shù)據(jù)庫(kù)名
          Connection conn= DriverManager.getConnection(url);

            6、MySQL數(shù)據(jù)庫(kù)

          Class.forName("org.gjt.mm.mysql.Driver").newInstance();
          String url ="jdbc:mysql://localhost/myDB?user=soft&password=soft1234&useUnicode=true&characterEncoding=8859_1"
          //myDB為數(shù)據(jù)庫(kù)名
          Connection conn= DriverManager.getConnection(url);

            7、PostgreSQL數(shù)據(jù)庫(kù)

          Class.forName("org.postgresql.Driver").newInstance();
          String url ="jdbc:postgresql://localhost/myDB" //myDB為數(shù)據(jù)庫(kù)名
          String user="myuser";
          String password="mypassword";
          Connection conn= DriverManager.getConnection(url,user,password);

            8、access數(shù)據(jù)庫(kù)直連用ODBC的

          Class.forName("sun.jdbc.odbc.JdbcOdbcDriver") ;
          String url="jdbc:odbc:Driver={MicroSoft Access Driver (*.mdb)};DBQ="+application.getRealPath("/Data/ReportDemo.mdb");
          Connection conn = DriverManager.getConnection(url,"","");
          Statement stmtNew=conn.createStatement() ;

            二、JDBC連接MySql方式

            下面是使用JDBC連接MySql的一個(gè)小的教程

            1、查找驅(qū)動(dòng)程序

            MySQL目前提供的java驅(qū)動(dòng)程序?yàn)镃onnection/J,可以從MySQL官方網(wǎng)站下載,并找到mysql-connector-java-3.0.15-ga-bin.jar文件,此驅(qū)動(dòng)程序?yàn)榧僯ava驅(qū)動(dòng)程序,不需做其他配置。

            2、動(dòng)態(tài)指定classpath

            如果需要執(zhí)行時(shí)動(dòng)態(tài)指定classpath,就在執(zhí)行時(shí)采用-cp方式。否則將上面的.jar文件加入到classpath環(huán)境變量中。

            3、加載驅(qū)動(dòng)程序

          try{
           Class.forName(com.mysql.jdbc.Driver);
           System.out.println(Success loading Mysql Driver!);
          }catch(Exception e)
          {
           System.out.println(Error loading Mysql Driver!);
           e.printStackTrace();
          }

            4、設(shè)置連接的url

          jdbc:mysql://localhost/databasename[?pa=va][&pa=va]

            三、以下列出了在使用JDBC來連接Oracle數(shù)據(jù)庫(kù)時(shí)可以使用的一些技巧

            1、在客戶端軟件開發(fā)中使用Thin驅(qū)動(dòng)程序

            在開發(fā)Java軟件方面,Oracle的數(shù)據(jù)庫(kù)提供了四種類型的驅(qū)動(dòng)程序,二種用于應(yīng)用軟件、applets、servlets等客戶端軟件,另外二種用于數(shù)據(jù)庫(kù)中的Java存儲(chǔ)過程等服務(wù)器端軟件。在客戶機(jī)端軟件的開發(fā)中,我們可以選擇OCI驅(qū)動(dòng)程序或Thin驅(qū)動(dòng)程序。OCI驅(qū)動(dòng)程序利用Java本地化接口(JNI),通過Oracle客戶端軟件與數(shù)據(jù)庫(kù)進(jìn)行通訊。Thin驅(qū)動(dòng)程序是純Java驅(qū)動(dòng)程序,它直接與數(shù)據(jù)庫(kù)進(jìn)行通訊。為了獲得最高的性能,Oracle建議在客戶端軟件的開發(fā)中使用OCI驅(qū)動(dòng)程序,這似乎是正確的。但我建議使用Thin驅(qū)動(dòng)程序,因?yàn)橥ㄟ^多次測(cè)試發(fā)現(xiàn),在通常情況下,Thin驅(qū)動(dòng)程序的性能都超過了OCI驅(qū)動(dòng)程序。

            2、關(guān)閉自動(dòng)提交功能,提高系統(tǒng)性能

            在第一次建立與數(shù)據(jù)庫(kù)的連接時(shí),在缺省情況下,連接是在自動(dòng)提交模式下的。為了獲得更好的性能,可以通過調(diào)用帶布爾值false參數(shù)的Connection類的setAutoCommit()方法關(guān)閉自動(dòng)提交功能,如下所示:

            conn.setAutoCommit(false);

            值得注意的是,一旦關(guān)閉了自動(dòng)提交功能,我們就需要通過調(diào)用Connection類的commit()和rollback()方法來人工的方式對(duì)事務(wù)進(jìn)行管理。

            3、在動(dòng)態(tài)SQL或有時(shí)間限制的命令中使用Statement對(duì)象

            在執(zhí)行SQL命令時(shí),我們有二種選擇:可以使用PreparedStatement對(duì)象,也可以使用Statement對(duì)象。無(wú)論多少次地使用同一個(gè)SQL命令,PreparedStatement都只對(duì)它解析和編譯一次。當(dāng)使用Statement對(duì)象時(shí),每次執(zhí)行一個(gè)SQL命令時(shí),都會(huì)對(duì)它進(jìn)行解析和編譯。這可能會(huì)使你認(rèn)為,使用PreparedStatement對(duì)象比使用Statement對(duì)象的速度更快。然而,我進(jìn)行的測(cè)試表明,在客戶端軟件中,情況并非如此。因此,在有時(shí)間限制的SQL操作中,除非成批地處理SQL命令,我們應(yīng)當(dāng)考慮使用Statement對(duì)象。

            此外,使用Statement對(duì)象也使得編寫動(dòng)態(tài)SQL命令更加簡(jiǎn)單,因?yàn)槲覀兛梢詫⒆址B接在一起,建立一個(gè)有效的SQL命令。因此,我認(rèn)為,Statement對(duì)象可以使動(dòng)態(tài)SQL命令的創(chuàng)建和執(zhí)行變得更加簡(jiǎn)單。

            4、利用helper函數(shù)對(duì)動(dòng)態(tài)SQL命令進(jìn)行格式化

            在創(chuàng)建使用Statement對(duì)象執(zhí)行的動(dòng)態(tài)SQL命令時(shí),我們需要處理一些格式化方面的問題。例如,如果我們想創(chuàng)建一個(gè)將名字O'Reilly插入表中的SQL命令,則必須使用二個(gè)相連的“''”號(hào)替換O'Reilly中的“'”號(hào)。完成這些工作的最好的方法是創(chuàng)建一個(gè)完成替換操作的helper方法,然后在連接字符串心服用公式表達(dá)一個(gè)SQL命令時(shí),使用創(chuàng)建的helper方法。與此類似的是,我們可以讓helper方法接受一個(gè)Date型的值,然后讓它輸出基于Oracle的to_date()函數(shù)的字符串表達(dá)式。

            5、利用PreparedStatement對(duì)象提高數(shù)據(jù)庫(kù)的總體效率

            在使用PreparedStatement對(duì)象執(zhí)行SQL命令時(shí),命令被數(shù)據(jù)庫(kù)進(jìn)行解析和編譯,然后被放到命令緩沖區(qū)。然后,每當(dāng)執(zhí)行同一個(gè)PreparedStatement對(duì)象時(shí),它就會(huì)被再解析一次,但不會(huì)被再次編譯。在緩沖區(qū)中可以發(fā)現(xiàn)預(yù)編譯的命令,并且可以重新使用。在有大量用戶的企業(yè)級(jí)應(yīng)用軟件中,經(jīng)常會(huì)重復(fù)執(zhí)行相同的SQL命令,使用PreparedStatement對(duì)象帶來的編譯次數(shù)的減少能夠提高數(shù)據(jù)庫(kù)的總體性能。如果不是在客戶端創(chuàng)建、預(yù)備、執(zhí)行PreparedStatement任務(wù)需要的時(shí)間長(zhǎng)于Statement任務(wù),我會(huì)建議在除動(dòng)態(tài)SQL命令之外的所有情況下使用PreparedStatement對(duì)象。

            6、在成批處理重復(fù)的插入或更新操作中使用PreparedStatement對(duì)象

            如果成批地處理插入和更新操作,就能夠顯著地減少它們所需要的時(shí)間。Oracle提供的Statement和 CallableStatement并不真正地支持批處理,只有PreparedStatement對(duì)象才真正地支持批處理。我們可以使用addBatch()和executeBatch()方法選擇標(biāo)準(zhǔn)的JDBC批處理,或者通過利用PreparedStatement對(duì)象的setExecuteBatch()方法和標(biāo)準(zhǔn)的executeUpdate()方法選擇速度更快的Oracle專有的方法。要使用Oracle專有的批處理機(jī)制,可以以如下所示的方式調(diào)用setExecuteBatch():

          PreparedStatement pstmt3D null;
          try {
           ((OraclePreparedStatement)pstmt).setExecuteBatch(30);
           ...
           pstmt.executeUpdate();
          }

            調(diào)用setExecuteBatch()時(shí)指定的值是一個(gè)上限,當(dāng)達(dá)到該值時(shí),就會(huì)自動(dòng)地引發(fā)SQL命令執(zhí)行,標(biāo)準(zhǔn)的executeUpdate()方法就會(huì)被作為批處理送到數(shù)據(jù)庫(kù)中。我們可以通過調(diào)用PreparedStatement類的sendBatch()方法隨時(shí)傳輸批處理任務(wù)。

            7、使用Oracle locator方法插入、更新大對(duì)象(LOB)

            Oracle的PreparedStatement類不完全支持BLOB和CLOB等大對(duì)象的處理,尤其是Thin驅(qū)動(dòng)程序不支持利用PreparedStatement對(duì)象的setObject()和setBinaryStream()方法設(shè)置BLOB的值,也不支持利用setCharacterStream()方法設(shè)置CLOB的值。只有l(wèi)ocator本身中的方法才能夠從數(shù)據(jù)庫(kù)中獲取LOB類型的值。可以使用PreparedStatement對(duì)象插入或更新LOB,但需要使用locator才能獲取LOB的值。由于存在這二個(gè)問題,因此,我建議使用locator的方法來插入、更新或獲取LOB的值。

            8、使用SQL92語(yǔ)法調(diào)用存儲(chǔ)過程

            在調(diào)用存儲(chǔ)過程時(shí),我們可以使用SQL92或Oracle PL/SQL,由于使用Oracle PL/SQL并沒有什么實(shí)際的好處,而且會(huì)給以后維護(hù)你的應(yīng)用程序的開發(fā)人員帶來麻煩,因此,我建議在調(diào)用存儲(chǔ)過程時(shí)使用SQL92。

            9、使用Object SQL將對(duì)象模式轉(zhuǎn)移到數(shù)據(jù)庫(kù)中

            既然可以將Oracle的數(shù)據(jù)庫(kù)作為一種面向?qū)ο蟮臄?shù)據(jù)庫(kù)來使用,就可以考慮將應(yīng)用程序中的面向?qū)ο竽J睫D(zhuǎn)到數(shù)據(jù)庫(kù)中。目前的方法是創(chuàng)建Java bean作為偽裝的數(shù)據(jù)庫(kù)對(duì)象,將它們的屬性映射到關(guān)系表中,然后在這些bean中添加方法。盡管這樣作在Java中沒有什么問題,但由于操作都是在數(shù)據(jù)庫(kù)之外進(jìn)行的,因此其他訪問數(shù)據(jù)庫(kù)的應(yīng)用軟件無(wú)法利用對(duì)象模式。如果利用Oracle的面向?qū)ο蟮募夹g(shù),可以通過創(chuàng)建一個(gè)新的數(shù)據(jù)庫(kù)對(duì)象類型在數(shù)據(jù)庫(kù)中模仿其數(shù)據(jù)和操作,然后使用JPublisher等工具生成自己的Java bean類。如果使用這種方式,不但Java應(yīng)用程序可以使用應(yīng)用軟件的對(duì)象模式,其他需要共享你的應(yīng)用中的數(shù)據(jù)和操作的應(yīng)用軟件也可以使用應(yīng)用軟件中的對(duì)象模式。

            10、利用SQL完成數(shù)據(jù)庫(kù)內(nèi)的操作

            我要向大家介紹的最重要的經(jīng)驗(yàn)是充分利用SQL的面向集合的方法來解決數(shù)據(jù)庫(kù)處理需求,而不是使用Java等過程化的編程語(yǔ)言。

            如果編程人員要在一個(gè)表中查找許多行,結(jié)果中的每個(gè)行都會(huì)查找其他表中的數(shù)據(jù),最后,編程人員創(chuàng)建了獨(dú)立的UPDATE命令來成批地更新第一個(gè)表中的數(shù)據(jù)。與此類似的任務(wù)可以通過在set子句中使用多列子查詢而在一個(gè)UPDATE命令中完成。當(dāng)能夠在單一的SQL命令中完成任務(wù),何必要讓數(shù)據(jù)在網(wǎng)上流來流去的?我建議用戶認(rèn)真學(xué)習(xí)如何最大限度地發(fā)揮SQL的功能。

          posted @ 2005-11-08 11:46 船夫 閱讀(384) | 評(píng)論 (0)編輯 收藏

          通過Jpetstore學(xué)習(xí)WSAD、ROSE、WEBSPHERE的基本用法(摘自Matrix)

          driver=org.gjt.mm.mysql.Driver
          url=jdbc:mysql://localhost/jpetstore
          username=root
          password=root


          第三步:運(yùn)行工程
          右鍵點(diǎn)擊“jpetstoreWeb”工程,選擇“在服務(wù)器上運(yùn)行”
          image

          由于WSAD帶WebSphere測(cè)試環(huán)境,全部默認(rèn)就可以。

          在IE運(yùn)行 http://localhost:9080/jpetstoreWeb/

          控制臺(tái)右下有“服務(wù)器”,可以啟動(dòng)或者停止服務(wù)器。

          第四步:重構(gòu)項(xiàng)目

          1.右鍵com.ibatis.jpetstore.persistence.iface.AccountDao,選擇“重命名”,如為IAccountDao(我個(gè)人的習(xí)慣,接口都以I開頭),所有引用AccountDao的java文件中,AccountDao也全部更改名稱了。其余的幾個(gè)Dao也重命名。

          2.打開com.ibatis.jpetstore.service.AccountService,選擇“重構(gòu)”->“抽取接口”,命名IAccountService,形成接口和實(shí)現(xiàn)兩個(gè)文件,所有對(duì)AccountService的引用也同時(shí)修改。

          第五步:導(dǎo)出EAR文件。
          二、在Websphere5.1中運(yùn)行jpetstore
          進(jìn)入Webshpere的管理控制臺(tái),選擇安裝新的應(yīng)用程序,導(dǎo)入并發(fā)布jpetstore.ear后,就可以在IE中直接運(yùn)行了( http://localhost:9080/jpetstoreWeb/)。

          三、用ROSE為jpetstore建模

          本部分的模型,首先通過ROSE工具的反向工程(Reverse Engineer)、然后進(jìn)行整理生成。

          (一)、UseCase用例

          ?????
          普通用戶(user)可以搜索產(chǎn)品(searchProducts)、查看產(chǎn)品分類(viewCategory)、查看產(chǎn)品(viewProduct)、查看產(chǎn)品項(xiàng)目(viewItem)、注冊(cè)新賬號(hào)(newAccount)、登陸(sign-In)。

          登陸后的用戶(signedUser)可以注銷登陸(sign-Out)、編輯賬號(hào)(editAccount)、將產(chǎn)品項(xiàng)目放入購(gòu)物車(addItemToCart)、從購(gòu)物車刪除產(chǎn)品項(xiàng)目(removeItemFromCart)、修改購(gòu)物數(shù)量(updateCartQuantities)、新訂單(newOrder)、查看訂單(viewOrder)、查看購(gòu)物車(viewCart)、結(jié)算(checkout)。

          (二)、數(shù)據(jù)模型

          ?????
          jpetstore的數(shù)據(jù)模型可以分三大類:

          1.產(chǎn)品相關(guān):
          產(chǎn)品分類(CATEGORY)
          產(chǎn)品(PRODUCT),也可以說是產(chǎn)品的小分類
          單個(gè)產(chǎn)品(ITEM),描述具體產(chǎn)品的詳細(xì)屬性
          供應(yīng)商(SUPPLIER)
          產(chǎn)品庫(kù)存(INVENTORY)

          2.用戶賬號(hào)相關(guān):
          用戶賬號(hào)(ACCOUNT)
          用戶口令(SIGNON),ibatis純粹為了展示表關(guān)聯(lián)的用法。
          用戶配置文件(PROFILE),存放用戶個(gè)性化信息。
          系統(tǒng)BANNER信息(BANNERDATA)

          3.訂單相關(guān):
          用戶訂單(ORDERS)
          訂單狀態(tài)(ORDERSTATUS)
          訂單詳情(LINEITEM)
           

          (三)、WEB模型

          WEB模型一向是各個(gè)建模工具的弱項(xiàng),ROSE的WEB建模能力也不強(qiáng),有時(shí)不能表達(dá)準(zhǔn)確的含義。

          1.新增、修改賬號(hào)
          ?????

          2.瀏覽產(chǎn)品
          image

          3.訂單
          image

          4.購(gòu)物車(略)

          對(duì)于WEB模型,配合struts的導(dǎo)航圖(NitroX生成,部分截圖),會(huì)更清楚些。

          image

          (四)、類圖

          image

          蘭色方框內(nèi)是通過spring+hibernate實(shí)現(xiàn)的。可以看到,表現(xiàn)層的AccountBean是面向接口調(diào)用Service的,當(dāng)改為用hibernate實(shí)現(xiàn)O/R mapping時(shí),只需要修改接口的實(shí)現(xiàn)類(DAO持久層),表現(xiàn)層的程序不需要任何修改。

          資源:
          附件一:ROSE,jpetstore.mdl
          [下載文件]
          附件二:jpetstoreWeb工程(不包括spring.jar、hibernate3.jar,太大了)
          [下載文件]

          posted @ 2005-11-06 17:26 船夫 閱讀(474) | 評(píng)論 (0)編輯 收藏

          開發(fā)線程安全的Spring Web應(yīng)用


          開發(fā)線程安全的Spring Web應(yīng)用

          作者:羅時(shí)飛 譯    來自:open-v.com

            前言

            如果開發(fā)者正開發(fā)或維護(hù)基于Servlet的Web應(yīng)用,則Servlet規(guī)范建議最好能夠看看。因?yàn)樗械膬?nèi)容對(duì)于Web應(yīng)用開發(fā)者理解Servlet容器的工作機(jī)理很有幫助。
            其中,規(guī)范給出了Servlet容器是如何處理客戶請(qǐng)求的。Servlet容器將會(huì)根據(jù)web.xml配置文件中定義的各個(gè)Servet而創(chuàng)建相應(yīng)的單例。因此,多個(gè)客戶請(qǐng)求可能同時(shí)訪問這些單例,即多個(gè)線程同時(shí)訪問它們。在Web應(yīng)用中保證線程安全是很重要的。開發(fā)者應(yīng)該對(duì)這個(gè)問題保持警惕,而且必須確保各自的代碼必須以線程安全的方式運(yùn)行。

            溫故線程安全

            好了,本文將介紹線程安全的基本知識(shí)以及如何實(shí)現(xiàn)線程安全。有關(guān)線程安全,現(xiàn)有的資料有很多,作者很喜歡Wikipedia[譯者注:http://en.wikipedia.org/wiki/Thread-safe ]這篇文章。開發(fā)者基本上可以認(rèn)為,如果代碼是可重入的(reentrant),或者通過某種形式的互斥而實(shí)現(xiàn)對(duì)并發(fā)訪問的保護(hù),則代碼是線程安全的。
            大部分Java開發(fā)者都應(yīng)該聽過synchronized關(guān)鍵字。在不采用任何第三方庫(kù)的前提下,Java本身對(duì)線程提供了原生支持,而且synchronized關(guān)鍵字往往是Java應(yīng)用中實(shí)現(xiàn)線程安全最重要的因素。Java中的同步提供了互斥支持。通過同步一塊代碼或整個(gè)方法能夠保證同時(shí)最多只有單個(gè)線程執(zhí)行它,從而實(shí)現(xiàn)了線程安全。引入同步具有副作用,即阻塞。比如,大公司或律師辦公室的前臺(tái)小姐同時(shí)需要處理電話、郵件、受訪客戶等等。這使得她的工作很繁忙,而且導(dǎo)致一些事情不能夠及時(shí)處理。
            在Web應(yīng)用中需要警惕阻塞。受同步保護(hù)的代碼塊使得其同時(shí)處理客戶請(qǐng)求的吞吐量降低,而且很多客戶處于阻塞狀態(tài),除非某客戶處理完成。而且互斥不僅會(huì)帶來阻塞,還會(huì)帶來死鎖。通常,死鎖是不可恢復(fù)的。如下條件將觸發(fā)死鎖的發(fā)生:線程A鎖住了線程B等待的資源,而且線程B鎖住了線程A等待的資源,即線程B一直在等待線程A釋放鎖,線程A也是如此。因此,對(duì)于多線程的應(yīng)用而言,死鎖的預(yù)防和處理通常都是很頭疼的。
            另外,synchronized關(guān)鍵字還使得大量的同步對(duì)象到處使用,從而引入了死鎖的可能性。比如,java.util.Hashtable和java.util.Vector中提供的方法都是受互斥保護(hù)的,因此除非確實(shí)需要使用它們,否則盡量不用。開發(fā)者只需要使用java.util.HashMap和java.util.ArrayList即可。當(dāng)然,java.util.Collections中的同步方法也使用了synchronized關(guān)鍵字。
            盡管可重入更易于管理,但它引入了其他問題。可重入代碼避免了線程間數(shù)據(jù)的共享。考慮如下代碼(姑且認(rèn)為Java中的方法是線程安全的):

            public Double pi() {
            int a = 22;
            int b = 7;
            return new Double(a / b);
            }

            不管同時(shí)進(jìn)入該方法的線程有多少,它總是線程安全的。各個(gè)線程都維護(hù)了屬于各個(gè)線程的棧,并不同其他線程共享。其中,各個(gè)線程在當(dāng)前方法(包括靜態(tài)方法)中創(chuàng)建的方法變量?jī)H屬于當(dāng)前線程,即存儲(chǔ)在當(dāng)前線程的棧中。因此,當(dāng)線程A和B同時(shí)進(jìn)入上述方法時(shí),它們都將創(chuàng)建a和b。由于上述方法不存在數(shù)據(jù)共享,因此上述方法是線程安全的。請(qǐng)注意:22/7值同PI值較接近,但它們不相等。

            接下來,看看如何優(yōu)化上述代碼吧。

            private Double pi = null;

            public Double pi() {
            if (pi == null) {
             pi = new Double(22 / 7);
            }

            return pi;
            }

            盡管改進(jìn)后的方法能夠提高性能,但并不是線程安全的。比如:如果pi為null,而且線程A和B同時(shí)進(jìn)入第4行。因此,線程A和B會(huì)同時(shí)測(cè)試pi是否為空,它們都將返回true。接下來,如果線程A繼續(xù)執(zhí)行(線程B由于某種原因被暫掛),然后返回對(duì)內(nèi)存地址的引用。其中,該內(nèi)存地址含有22/7的結(jié)果,即pi值。最后,線程A退出方法。當(dāng)線程B再次進(jìn)入第5行時(shí),新的內(nèi)存地址將覆蓋原先的內(nèi)存地址(線程A提供的)。這太危險(xiǎn)了,而且這種問題往往難于調(diào)試。
          如果使用ThreadLocal,則不僅能夠保證pi()方法是線程安全,而且能夠提供性能的改善。

            private static ThreadLocal pi = new ThreadLocal();

            public Double pi() {
            if (pi.get() == null) {
            pi.set(new Double(22 / 7));
            }

            return (Double)pi.get();
            }

            ThreadLocal類能夠包裹任何對(duì)象,而且能夠?qū)?duì)象綁定到當(dāng)前線程,使得它僅僅供當(dāng)前線程使用。當(dāng)線程初次執(zhí)行pi()方法時(shí),由于沒有對(duì)象綁定到ThreadLocal實(shí)例pi上,因此get()方法返回null。借助于set()方法能夠?qū)?duì)象綁定到當(dāng)前線程,而且不供其它線程使用。因此,如果不同線程需要經(jīng)常訪問pi()方法,則借助于ThreadLocal不僅能夠保證線程安全,而且能夠提高性能。
            目前,存在很多關(guān)于如何使用ThreadLocal的資源。在Java 1.4之前,ThreadLocal的性能確實(shí)很差,但是現(xiàn)已解決了這個(gè)問題。另外,由于對(duì)ThreadLocal的錯(cuò)誤理解,使得很多開發(fā)者對(duì)它的誤用。注意,上述實(shí)例使用ThreadLocal的方式是絕對(duì)沒問題的。在引入ThreadLocal后,上述方法的行為并未發(fā)生改變,但是方法已經(jīng)是線程安全的了。
            通過可重入的方式開發(fā)線程安全的代碼要求開發(fā)者謹(jǐn)慎使用實(shí)例變量或靜態(tài)變量,尤其對(duì)于修改那些其他線程需要使用的對(duì)象而言。某些場(chǎng)合,使用同步可能更為合適。然而,為識(shí)別由于同步而引起的應(yīng)用性能瓶頸往往只能借助于專業(yè)的性能評(píng)測(cè)工具或負(fù)載測(cè)試完成。

            Web應(yīng)用中的線程安全

            好了,在溫故線程安全的知識(shí)后,來研究Web應(yīng)用中是如何線程安全的吧!開發(fā)者通過創(chuàng)建Web頁(yè)面來操作數(shù)據(jù)庫(kù)。比如,在Web層和業(yè)務(wù)邏輯層都能夠操作RDBMS。本文使用Hibernate將業(yè)務(wù)模型持久化到數(shù)據(jù)庫(kù)中。在Web層,開發(fā)者可以使用Tapestry、Wicket、Struts、WebWork、JSF、Spring MVC,或者其他運(yùn)行在Web容器中的Web框架。
            至于Web層的具體實(shí)現(xiàn)并不是本文的重點(diǎn)。本文將關(guān)注如何管理數(shù)據(jù)庫(kù)連接,這也是Web應(yīng)用中處理線程安全問題是經(jīng)常要考慮的資源。數(shù)據(jù)庫(kù)連接對(duì)象,比如連接、結(jié)果集、Statement、Hibernate Session,是有狀態(tài)對(duì)象。當(dāng)然,它們不是線程安全的,因此不能夠同時(shí)供多個(gè)線程訪問。在本文前面已經(jīng)提到,開發(fā)者應(yīng)盡量避免使用同步。無(wú)論是synchronized關(guān)鍵字,還是那些同步類(Hashtable或Vector),應(yīng)盡量避免使用。因此,如果使用可重入,則不用處理阻塞或死鎖。
            當(dāng)然,通過可重入實(shí)現(xiàn)線程安全以訪問數(shù)據(jù)庫(kù)并不是件簡(jiǎn)單的工作。比如,有些開發(fā)者可能會(huì)在Servlet容器配置中添加過濾器。因此,在客戶請(qǐng)求到來時(shí),過濾器將創(chuàng)建JDBC連接或Hibernate Session,并借助于ThreadLocal類將它們綁定到當(dāng)前線程中,從而供業(yè)務(wù)邏輯使用。如果直接使用J2EE API,則開發(fā)者除了需要做很多同業(yè)務(wù)邏輯無(wú)關(guān)的操作外,還需要管理事務(wù)、DB錯(cuò)誤等等開發(fā)內(nèi)容。請(qǐng)注意,這些同業(yè)務(wù)邏輯無(wú)關(guān)的操作的維護(hù)工作往往很費(fèi)時(shí)間。

            Spring的闖入

            一些Java開發(fā)者可能聽說過Spring提供的DAO抽象。當(dāng)然,一些開發(fā)者也有可能使用過它。借助于Spring提供的模板,開發(fā)者能夠使用DAO代碼的重用。借助于Spring AOP,開發(fā)者還能夠使用聲明式事務(wù)。因此,本文來研究Spring是如何實(shí)現(xiàn)以線程安全方式訪問RDBMS的。比如,Spring允許以JDBC、Hibernate、JDO、iBATIS、TopLink等方式訪問數(shù)據(jù)庫(kù)。如下給出的實(shí)例是企業(yè)應(yīng)用中很常見的情景。

            首先,定義數(shù)據(jù)源和用于Hibernate SessionFactory。

          id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">


          WEB-INF/jdbc.properties



          ${jdbc.driverClassName}
          ${jdbc.url}
          ${jdbc.username}
          ${jdbc.password}







          classpath:




          net.sf.hibernate.dialect.HSQLDialect
          true


            這是使用Hibernate的典型配置,即通過定義的數(shù)據(jù)源連接到數(shù)據(jù)庫(kù)、通過本地SessionFactory創(chuàng)建Hibernate SessionFactory。接下來,需要定義業(yè)務(wù)對(duì)象(實(shí)現(xiàn)對(duì)DB的訪問)和事務(wù)管理器(通過Hibernate Session管理本地事務(wù))。其中,業(yè)務(wù)對(duì)象暴露的方法能夠在數(shù)據(jù)庫(kù)中添加新的紀(jì)錄,而事務(wù)管理器能夠?qū)⒎椒ò谑聞?wù)中。它們的定義如下。

          public interface CustomerDAO {
          public void createCustomer(Customer customer);
          }

          public class HibernateCustomerDAO implements CustomerDAO {

          private HibernateTemplate hibernateTemplate = null;

          public void setSessionFactory(SessionFactory sessionFactory) {
          this.hibernateTemplate = new HibernateTemplate(sessionFactory, false);
          }

          public void createCustomer(Customer customer) {
          this.hibernateTemplate.save(customer);
          }
          }

            開發(fā)者應(yīng)該已經(jīng)看到,上述類使用了Spring提供的HibernateTemplate。注意,模板的開發(fā)遵循了業(yè)界最佳實(shí)踐,并且將一些同業(yè)務(wù)不相關(guān),但J2EE API規(guī)定要處理的那些代碼處理掉了。與此同時(shí),它通過DAO抽象將受查異常轉(zhuǎn)換為非受查異常。當(dāng)然,Spring不只是為使用Hibernate提供模板,它還為JDBC、iBATIS、SqlMap、JDO、TopLink提供類似模板。由于這些模板類及其實(shí)例變量實(shí)現(xiàn)了可重入,即都是線程安全的,因此允許并發(fā)線程同時(shí)使用模板。使用這些模板不僅能夠?qū)崿F(xiàn)代碼的重用,還提供了最佳實(shí)踐。除了以線程安全方式訪問DB外,模板還提供了其他很多有意義的內(nèi)容。好了,來看看如何定義業(yè)務(wù)對(duì)象和事務(wù)管理器吧!










          PROPAGATION_REQUIRED
          PROPAGATION_REQUIRED


            如果開發(fā)者對(duì)Spring中事務(wù)管理的配置不熟悉,則本文正好滿足你們。首先,上述Spring配置片斷定義了業(yè)務(wù)對(duì)象HibernateCustomerDAO,它包裹了Hibernate SessionFactory。注意,默認(rèn)時(shí),Spring中定義的JavaBean都是單例的,HibernateCustomerDAO也不例外。這意味:多個(gè)線程可能同時(shí)執(zhí)行createCustomer()方法。
            其次,配置了Hibernate事務(wù)管理器,它包裹了同一Hibernate SessionFactory實(shí)例。在事務(wù)管理器每次執(zhí)行時(shí),它都會(huì)完成如下幾件事情。其一,檢查Hibernate Session是否綁定到當(dāng)前線程。如果已綁定,則直接使用它。如果還未綁定,事務(wù)管理器將告知Hibernate SessionFactory創(chuàng)建新的Session,然后將創(chuàng)建的Session綁定到當(dāng)前線程。其二,如果當(dāng)前沒有處于活動(dòng)的事務(wù),則事務(wù)管理器將啟動(dòng)新的事務(wù),并將Session包裹進(jìn)來。否則,直接參與到活動(dòng)事務(wù)中。
            整個(gè)過程是通過使用Spring提供的TransactionProxyFactoryBean實(shí)現(xiàn)的。當(dāng)然,這是一種以聲明方式實(shí)現(xiàn)的事務(wù)管理過程。TransactionProxyFactoryBean能夠?yàn)闃I(yè)務(wù)對(duì)象創(chuàng)建代理對(duì)象,從而通過事務(wù)管理器管理事務(wù)。當(dāng)每次通過代理對(duì)象調(diào)用createCustomer()方法時(shí),事務(wù)管理器將根據(jù)事務(wù)屬性管理事務(wù)。當(dāng)前,Spring除了提供HibernateTransactionManager事務(wù)管理器外,還為JDBC數(shù)據(jù)源、JDO、TopLink提供了相應(yīng)的事務(wù)管理器。
            好了,再來看看業(yè)務(wù)對(duì)象吧!當(dāng)調(diào)用createCustomer()方法時(shí),HibernateTemplate將查找綁定到當(dāng)前線程的Hibernate Session。由于上述配置文件片斷傳入到HibernateTemplate構(gòu)建器的第二個(gè)參數(shù)為false,因此如果沒有綁定Hibernate Session,則將拋出未受查異常。這對(duì)于那些未正確配置事務(wù)管理功能的場(chǎng)和特別有用(注意,事務(wù)管理器很重要)。一旦事務(wù)管理配置好后,Hibernate Session將綁定到當(dāng)前線程,從而啟動(dòng)事務(wù)。請(qǐng)注意,HibernateTemplate不會(huì)去檢查事務(wù)是否激活,也不會(huì)顯示地啟動(dòng)或終止事務(wù)。也請(qǐng)注意,如果在聲明的方法(事務(wù)屬性中給出的)中拋出了未受查異常,則當(dāng)前活動(dòng)事務(wù)將回滾。至于事務(wù)屬性的研究,本文不再給出。

            結(jié)論

            最后,來總結(jié)一下Spring以線程安全方式實(shí)現(xiàn)數(shù)據(jù)訪問吧。通過使用事務(wù)管理和權(quán)衡ThreadLocal提供的功能,Spring將數(shù)據(jù)庫(kù)連接(JDBC連接、Hibernate Session、JDO持久化管理器)綁定到當(dāng)前線程,從而供DAO模板使用。本文在最開始研究了數(shù)據(jù)庫(kù)連接并沒有在線程間共享。Spring不僅提供了聲明式事務(wù)管理、J2EE API抽象、最佳實(shí)踐,而且其提供的模板是線程安全的。當(dāng)使用Spring訪問DB時(shí),通過可重入實(shí)現(xiàn)應(yīng)用的線程安全是最為可靠、常見的做法。

          posted @ 2005-11-04 09:52 船夫 閱讀(242) | 評(píng)論 (0)編輯 收藏

          SQL Server 中易混淆的數(shù)據(jù)類型 (摘自“藍(lán)色理想”)

          近來在做數(shù)據(jù)庫(kù)設(shè)計(jì),有時(shí)候真弄不清SQL2000里的數(shù)據(jù)類型,所以摘了這篇文章。

          (1)char、varchar、text和nchar、nvarchar、ntext
          char和varchar的長(zhǎng)度都在1到8000之間,它們的區(qū)別在于char是定長(zhǎng)字符數(shù)據(jù),而varchar是變長(zhǎng)字符數(shù)據(jù)。所謂定長(zhǎng)就是長(zhǎng)度固定的,當(dāng)輸入的數(shù)據(jù)長(zhǎng)度沒有達(dá)到指定的長(zhǎng)度時(shí)將自動(dòng)以英文空格在其后面填充,使長(zhǎng)度達(dá)到相應(yīng)的長(zhǎng)度;而變長(zhǎng)字符數(shù)據(jù)則不會(huì)以空格填充。text存儲(chǔ)可變長(zhǎng)度的非Unicode數(shù)據(jù),最大長(zhǎng)度為2^31-1(2,147,483,647)個(gè)字符。

          后面三種數(shù)據(jù)類型和前面的相比,從名稱上看只是多了個(gè)字母"n",它表示存儲(chǔ)的是Unicode數(shù)據(jù)類型的字符。寫過程序的朋友對(duì)Unicode應(yīng)該很了解。字符中,英文字符只需要一個(gè)字節(jié)存儲(chǔ)就足夠了,但漢字眾多,需要兩個(gè)字節(jié)存儲(chǔ),英文與漢字同時(shí)存在時(shí)容易造成混亂,Unicode字符集就是為了解決字符集這種不兼容的問題而產(chǎn)生的,它所有的字符都用兩個(gè)字節(jié)表示,即英文字符也是用兩個(gè)字節(jié)表示。nchar、nvarchar的長(zhǎng)度是在1到4000之間。和char、varchar比較:nchar、nvarchar則最多存儲(chǔ)4000個(gè)字符,不論是英文還是漢字;而char、varchar最多能存儲(chǔ)8000個(gè)英文,4000個(gè)漢字。可以看出使用nchar、nvarchar數(shù)據(jù)類型時(shí)不用擔(dān)心輸入的字符是英文還是漢字,較為方便,但在存儲(chǔ)英文時(shí)數(shù)量上有些損失。

          (2)datetime和smalldatetime
          datetime:從1753年1月1日到9999年12月31日的日期和時(shí)間數(shù)據(jù),精確到百分之三秒。
          smalldatetime:從1900年1月1日到2079年6月6日的日期和時(shí)間數(shù)據(jù),精確到分鐘。

          (3)bitint、int、smallint、tinyint和bit
          bigint:從-2^63(-9223372036854775808)到2^63-1(9223372036854775807)的整型數(shù)據(jù)。
          int:從-2^31(-2,147,483,648)到2^31-1(2,147,483,647)的整型數(shù)據(jù)。
          smallint:從-2^15(-32,768)到2^15-1(32,767)的整數(shù)數(shù)據(jù)。
          tinyint:從0到255的整數(shù)數(shù)據(jù)。
          bit:1或0的整數(shù)數(shù)據(jù)。

          (4)decimal和numeric
          這兩種數(shù)據(jù)類型是等效的。都有兩個(gè)參數(shù):p(精度)和s(小數(shù)位數(shù))。p指定小數(shù)點(diǎn)左邊和右邊可以存儲(chǔ)的十進(jìn)制數(shù)字的最大個(gè)數(shù),p必須是從 1到38之間的值。s指定小數(shù)點(diǎn)右邊可以存儲(chǔ)的十進(jìn)制數(shù)字的最大個(gè)數(shù),s必須是從0到p之間的值,默認(rèn)小數(shù)位數(shù)是0。

          (5)float和real
          float:從-1.79^308到1.79^308之間的浮點(diǎn)數(shù)字?jǐn)?shù)據(jù)。
          real:從-3.40^38到3.40^38之間的浮點(diǎn)數(shù)字?jǐn)?shù)據(jù)。在SQL Server中,real的同義詞為float(24)。

          轉(zhuǎn)自:動(dòng)態(tài)網(wǎng)制作指南 www.knowsky.com

          posted @ 2005-11-02 10:50 船夫 閱讀(159) | 評(píng)論 (0)編輯 收藏

          bigint數(shù)據(jù)類型與int數(shù)據(jù)類型(摘自ZDNet)

          盡管int依然是SQL Server 2000中最主要的整數(shù)數(shù)據(jù)類型,但是SQL Server 2000還是新增加了整數(shù)數(shù)據(jù)類型bigint,它應(yīng)用于整數(shù)超過int數(shù)據(jù)范圍的場(chǎng)合。

          int數(shù)據(jù)類型所表示的數(shù)值范圍從-2^31到2^31-1,也就是說,你可以用int數(shù)據(jù)類型來表達(dá)-2,147,483,648到2,147,483,647(即大約正負(fù)二十億)之間的整數(shù)。一個(gè)int型占用四個(gè)字節(jié)的存儲(chǔ)空間。

          而bigint可以精確的表示從-2^63到2^63-1(即從-9,223,372,036,854,775,808到 9,223,372,036,854,775,807)之間的整數(shù),它占用了八個(gè)字節(jié)的存儲(chǔ)空間。

          當(dāng)你使用bigint時(shí),需要留意下面幾點(diǎn):

          • 在數(shù)據(jù)類型優(yōu)先表中,bigint數(shù)據(jù)類型位于int之上、smallmoney之下。
          • SQL Server不能自動(dòng)的把int型數(shù)據(jù)轉(zhuǎn)換成bigint型。
          • 如果函數(shù)的參數(shù)表達(dá)式是一個(gè)bigint類型時(shí),函數(shù)只能返回bigint類型的數(shù)據(jù)。使用bigint數(shù)據(jù)類型的函數(shù)有AVG、CEILING、FLOOR、MAX、MIN、ROUND以及SUM等等。
          • 可以在指定了整型數(shù)據(jù)的所有語(yǔ)法位置使用bigint數(shù)據(jù)類型:ALTER PROCEDURE、ALTER TABLE、CREATE PROCEDURE、CREATE TABLE以及 DECLARE變量。
          • 你可以在SQL Server目錄組件(catalog components)得到bigint欄的信息。

          你可能會(huì)對(duì)為什么任何人都有可能需要使用bigint數(shù)據(jù)類型這一問題感到疑惑。實(shí)際上,這個(gè)問題并不難以回答,例如當(dāng)你的數(shù)據(jù)庫(kù)需要進(jìn)行大數(shù)據(jù)運(yùn)算時(shí)(如信用卡公司常常會(huì)碰到這種情況),你就需要使用bigint數(shù)據(jù)類型

          posted @ 2005-11-02 10:44 船夫 閱讀(1808) | 評(píng)論 (0)編輯 收藏

          主站蜘蛛池模板: 乌审旗| 五指山市| 巴里| 南京市| 曲阳县| 马鞍山市| 南澳县| 大英县| 炉霍县| 龙泉市| 滨海县| 额济纳旗| 大兴区| 沅陵县| 东阿县| 海淀区| 白河县| 文登市| 通渭县| 广德县| 青龙| 九江县| 乐亭县| 来安县| 会宁县| 海安县| 长葛市| 连平县| 桑日县| 温泉县| 吐鲁番市| 寿阳县| 内丘县| 广宗县| 太原市| 咸阳市| 蓬安县| 永康市| 邯郸市| 拉萨市| 桐乡市|