2010年6月29日

          1、Log4j是什么?
            Log4j可以幫助調試(有時候debug是發揮不了作 用的)和分析,要下載和了解更詳細的內容,還是訪問其官方網站吧: http://jakarta.apache.org/log4j .

            2、Log4j的概念
            Log4j中有三個主要的組件,它們分別是 Logger、Appender和Layout,Log4j 允許開發人員定義多個Logger,每個Logger擁有自己的名字,Logger之間通過名字來表明隸屬關系。有一個Logger稱為Root,它永遠存在,且不能通過名字檢索或引用,可以通過Logger.getRootLogger()方法獲得,其它Logger通過 Logger.getLogger(String name)方法。
            Appender則是用來指明將所有的log信息存放到什么地方,Log4j中支持多種appender,如 console、files、GUI components、NT Event Loggers等,一個Logger可以擁有多個Appender,也就是你既可以將Log信息輸出到屏幕,同時存儲到一個文件中。
            Layout的作用是控制Log信息的輸出方式,也就是格式化輸出的信息。
            Log4j中將要輸出的Log信息定義了5種級別,依次為DEBUG、INFO、WARN、ERROR和FATAL,當輸出時,只有級別高過配置中規定的 級別的信息才能真正的輸出,這樣就很方便的來配置不同情況下要輸出的內容,而不需要更改代碼,這點實在是方便啊。

            3、Log4j的配置文件
            雖然可以不用配置文件,而在程序中實現配置,但這種方法在如今的系統開發中顯然是不可取的,能采用配置文件的地方一定一定要用配置文件。Log4j支持兩 種格式的配置文件:XML格式和Java的property格式,本人更喜歡后者,首先看一個簡單的例子吧,如下:
             log4j.rootLogger=debug, stdout, R
             log4j.appender.stdout=org.apache.log4j.ConsoleAppender
             log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

             # Pattern to output the caller's file name and line number.
             log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

             log4j.appender.R=org.apache.log4j.RollingFileAppender
             log4j.appender.R.File=example.log
             log4j.appender.R.MaxFileSize= 100KB

             # Keep one backup file
             log4j.appender.R.MaxBackupIndex=1

             log4j.appender.R.layout=org.apache.log4j.PatternLayout
             log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n

            首先,是設置root,格式為 log4j.rootLogger=[level],appenderName, ……,其中level就是設置需要輸出信息的級別,后面是appender的輸出的目的地,appenderName就是指定日志信息輸出到哪個地方。您可以同時指定多個輸出目的地。 配置日志信息輸出目的地Appender,其語法為
          log4j.appender.appenderName = fully.qualified.name.of.appender.class
             log4j.appender.appenderName.option1 = value1
             ...
             log4j.appender.appenderName.option = valueN


            Log4j提供的appender有以下幾種:
            org.apache.log4j.ConsoleAppender(控制臺)
            org.apache.log4j.FileAppender(文件)
            org.apache.log4j.DailyRollingFileAppender(每天產生一個日志文件)
            org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的時候產生新文件)
            org.apache.log4j.WriterAppender(將日志信息以流格式發送到任意指定的地方)

            配置日志信息的格式(布局),其語法為:
          log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
             log4j.appender.appenderName.layout.option1 = value1
             ....
             log4j.appender.appenderName.layout.option = valueN

            Log4j提供的layout有以下幾種:
            org.apache.log4j.HTMLLayout(以HTML表格形式布局),
            org.apache.log4j.PatternLayout(可以靈活地指定布局模式),
            org.apache.log4j.SimpleLayout(包含日志信息的級別和信息字符串),
            org.apache.log4j.TTCCLayout(包含日志產生的時間、線程、類別等等信息)
               www.jhaccp.com.cn
            Log4J采用類似C語言中的printf函數的打印格式格式化日志信息,打印參數如下: %m 輸出代碼中指定的消息
            %p 輸出優先級,即DEBUG,INFO,WARN,ERROR,FATAL
            %r 輸出自應用啟動到輸出該log信息耗費的毫秒數
            %c 輸出所屬的類目,通常就是所在類的全名
            %t 輸出產生該日志事件的線程名
            %n 輸出一個回車換行符,Windows平臺為“rn”,Unix平臺為“n”
            %d 輸出日志時間點的日期或時間,默認格式為ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},輸出類似: 2002年10月18日 22:10:28,921
            %l 輸出日志事件的發生位置,包括類目名、發生的線程,以及在代碼中的行數。舉例:Testlog4.main(TestLog4.java:10)

            4、Log4j在程序中的使用
            要在自己的程序中使用Log4j,首先需要將commons- logging.jar和logging-log4j-1.2.9.jar導入到構建路徑中。然后再將log4j.properties放到src根目錄下。這樣就可以在程序中使用log4j了。在類中使用log4j,首先聲明一個靜態變量 Logger logger=Logger.getLog("classname");現在就可以使用了,用法如下:logger.debug("debug message")或者logger.info("info message"),看下面一個小例子:

          import com.foo.Bar;
             import org.apache.log4j.Logger;
             import org.apache.log4j.PropertyConfigurator;
             public class MyApp {
               static Logger logger = Logger.getLogger(MyApp.class.getName());
               public static void main(String[] args) {
                 // BasicConfigurator replaced with PropertyConfigurator.
                 PropertyConfigurator.configure(args[0]);
                 logger.info("Entering application.");
                 Bar bar = new Bar();
                 bar.doIt();
                 logger.info("Exiting application.");
               }
             }

          posted @ 2010-06-29 11:27 FaithChen 閱讀(167) | 評論 (0)編輯 收藏


          2010年6月28日

          java1.5方法參數不確定

          Java中"Test(Object...args){}"方法聲明的理解——J2SE5的“Varargs”機制收藏

          轉自:

          孫海濤 (sun.haitao@126.com) http://blog.csdn.net/avius

          2004年8月5日最初發表,2004年8月19日最后修訂

          J2SE 1.5提供了“Varargs”機制。借助這一機制,可以定義能和多個實參相匹配的形參。從而,可以用一種更簡單的方式,來傳遞個數可變的實參。本文介紹這一機制的使用方法,以及這一機制與數組、泛型、重載之間的相互作用時的若干問題。


          J2SE 1.5提供了“Varargs”機制。借助這一機制,可以定義能和多個實參相匹配的形參。從而,可以用一種更簡單的方式,來傳遞個數可變的實參。本文介紹這一機制的使用方法,以及這一機制與數組、泛型、重載之間的相互作用時的若干問題。

           

          到J2SE 1.4為止,一直無法在Java程序里定義實參個數可變的方法——因為Java要求實參(Arguments)和形參(Parameters)的數量和類型都必須逐一匹配,而形參的數目是在定義方法時就已經固定下來了。盡管可以通過重載機制,為同一個方法提供帶有不同數量的形參的版本,但是這仍然不能達到讓實參數量任意變化的目的。

          然而,有些方法的語義要求它們必須能接受個數可變的實參——例如著名的main方法,就需要能接受所有的命令行參數為實參,而命令行參數的數目,事先根本無法確定下來。

          對于這個問題,傳統上一般是采用“利用一個數組來包裹要傳遞的實參”的做法來應付。

          1. 用數組包裹實參

          “用數組包裹實參”的做法可以分成三步:首先,為這個方法定義一個數組型的參數;然后在調用時,生成一個包含了所有要傳遞的實參的數組;最后,把這個數組作為一個實參傳遞過去。

          這種做法可以有效的達到“讓方法可以接受個數可變的參數”的目的,只是調用時的形式不夠簡單。

          J2SE 1.5中提供了Varargs機制,允許直接定義能和多個實參相匹配的形參。從而,可以用一種更簡單的方式,來傳遞個數可變的實參。

          Varargs的含義

          大體說來,“Varargs”是“variable number of arguments”的意思。有時候也被簡單的稱為“variable arguments”,不過因為這一種叫法沒有說明是什么東西可變,所以意義稍微有點模糊。

          2. 定義實參個數可變的方法

          只要在一個形參的“類型”與“參數名”之間加上三個連續的“.”(即“...”,英文里的句中省略號),就可以讓它和不確定個實參相匹配。而一個帶有這樣的形參的方法,就是一個實參個數可變的方法。

          清單1:一個實參個數可變的方法

          private static int sumUp(int... values) { }

          注意,只有最后一個形參才能被定義成“能和不確定個實參相匹配”的。因此,一個方法里只能有一個這樣的形參。另外,如果這個方法還有其它的形參,要把它們放到前面的位置上。

          編譯器會在背地里把這最后一個形參轉化為一個數組形參,并在編譯出的class文件里作上一個記號,表明這是個實參個數可變的方法。

          清單2:實參個數可變的方法的秘密形態

          private static int sumUp(int[] values) { }

          由于存在著這樣的轉化,所以不能再為這個類定義一個和轉化后的方法簽名一致的方法。

          清單3:會導致編譯錯誤的組合

          private static int sumUp(int... values) { } private static int sumUp(int[] values) { }

          空白的存亡問題

          根據J2SE 1.5的語法,在“...”前面的空白字符是可有可無的。這樣就有在“...”前面添加空白字符(形如“Object ... args”)和在“...”前面不加空白字符(形如“Object... args”)的兩種寫法。因為目前和J2SE 1.5相配合的Java Code Conventions還沒有正式發布,所以無法知道究竟哪一種寫法比較正統。不過,考慮到數組參數也有“Object [] args”和“Object[] args”兩種書寫方式,而正統的寫法是不在“[]”前添加空白字符,似乎采取不加空白的“Object... args”的寫法在整體上更協調一些。

          3. 調用實參個數可變的方法

          只要把要傳遞的實參逐一寫到相應的位置上,就可以調用一個實參個數可變的方法。不需要其它的步驟。

          清單4:可以傳遞若干個實參

          sumUp(1, 3, 5, 7);

          在背地里,編譯器會把這種調用過程轉化為用“數組包裹實參”的形式:

          清單5:偷偷出現的數組創建

          sumUp(new int[]{1, 2, 3, 4});

          另外,這里說的“不確定個”也包括零個,所以這樣的調用也是合乎情理的:

          清單6:也可以傳遞零個實參

          sumUp();

          這種調用方法被編譯器秘密轉化之后的效果,則等同于這樣:

          清單7:零實參對應空數組

          sumUp(new int[]{});

          注意這時傳遞過去的是一個空數組,而不是null。這樣就可以采取統一的形式來處理,而不必檢測到底屬于哪種情況。

          4. 處理個數可變的實參

          處理個數可變的實參的辦法,和處理數組實參的辦法基本相同。所有的實參,都被保存到一個和形參同名的數組里。根據實際的需要,把這個數組里的元素讀出之后,要蒸要煮,就可以隨意了。

          清單8:處理收到的實參們

          private static int sumUp(int... values) {      int sum = 0;      for (int i = 0; i < values.length; i++) {          sum += values[i];      }      return sum; }

          5. 轉發個數可變的實參

          有時候,在接受了一組個數可變的實參之后,還要把它們傳遞給另一個實參個數可變的方法。因為編碼時無法知道接受來的這一組實參的數目,所以“把它們逐一寫到該出現的位置上去”的做法并不可行。不過,這并不意味著這是個不可完成的任務,因為還有另外一種辦法,可以用來調用實參個數可變的方法。

          在J2SE 1.5的編譯器的眼中,實參個數可變的方法是最后帶了一個數組形參的方法的特例。因此,事先把整組要傳遞的實參放到一個數組里,然后把這個數組作為最后一個實參,傳遞給一個實參個數可變的方法,不會造成任何錯誤。借助這一特性,就可以順利的完成轉發了。

          清單9:轉發收到的實參們

          public class PrintfSample {      public static void main(String[] args) {          //打印出“Pi:3.141593 E:2.718282”          printOut("Pi:%f E:%f\n", Math.PI, Math.E);      }      private static void printOut(String format, Object... args) {          //J2SE 1.5里PrintStream新增的printf(String format, Object... args)方法          System.out.printf(format, args);      } }

          Java里的“printf”和“sprintf”

          C語言里的printf(按一定的格式輸出字符串)和sprintf(按一定的格式組合字符串)是十分經典的使用Varargs機制的例子。在 J2SE 1.5中,也分別在java.io.PrintStream類和java.lang.String類中提供了類似的功能。

          按一定的格式輸出字符串的功能,可以通過調用PrintStream對象的printf(String format, Object... args)方法來實現。

          按一定的格式組合字符串的工作,則可以通過調用String類的String format(String format, Object... args)靜態方法來進行。

          6. 是數組?不是數組?

          盡管在背地里,編譯器會把能匹配不確定個實參的形參,轉化為數組形參;而且也可以用數組包了實參,再傳遞給實參個數可變的方法;但是,這并不表示“能匹配不確定個實參的形參”和“數組形參”完全沒有差異。

          一個明顯的差異是,如果按照調用實參個數可變的方法的形式,來調用一個最后一個形參是數組形參的方法,只會導致一個“cannot be applied to”的編譯錯誤。

          清單10:一個“cannot be applied to”的編譯錯誤

          private static void testOverloading(int[] i) {      System.out.println("A"); } public static void main(String[] args) {      testOverloading(1, 2, 3);//編譯出錯 }

          由于這一原因,不能在調用只支持用數組包裹實參的方法的時候(例如在不是專門為J2SE 1.5設計第三方類庫中遺留的那些),直接采用這種簡明的調用方式。

          如果不能修改原來的類,為要調用的方法增加參數個數可變的版本,而又想采用這種簡明的調用方式,那么可以借助“引入外加函數(Introduce Foreign Method)”和“引入本地擴展(Intoduce Local Extension)”的重構手法來近似的達到目的。

          7. 當個數可變的實參遇到泛型

          J2SE 1.5中新增了“泛型”的機制,可以在一定條件下把一個類型參數化。例如,可以在編寫一個類的時候,把一個方法的形參的類型用一個標識符(如T)來代表,至于這個標識符到底表示什么類型,則在生成這個類的實例的時候再行指定。這一機制可以用來提供更充分的代碼重用和更嚴格的編譯時類型檢查。

          不過泛型機制卻不能和個數可變的形參配合使用。如果把一個能和不確定個實參相匹配的形參的類型,用一個標識符來代表,那么編譯器會給出一個“generic array creation”的錯誤。

          清單11:當Varargs遇上泛型

          private static <T> void testVarargs(T... args) {//編譯出錯 }

          造成這個現象的原因在于J2SE 1.5中的泛型機制的一個內在約束——不能拿用標識符來代表的類型來創建這一類型的實例。在出現支持沒有了這個約束的Java版本之前,對于這個問題,基本沒有太好的解決辦法。

          不過,傳統的“用數組包裹”的做法,并不受這個約束的限制。

          清單12:可以編譯的變通做法

          private static <T> void testVarargs(T[] args) {      for (int i = 0; i < args.length; i++) {          System.out.println(args[i]);      } }

          8. 重載中的選擇問題

          Java支持“重載”的機制,允許在同一個類擁有許多只有形參列表不同的方法。然后,由編譯器根據調用時的實參來選擇到底要執行哪一個方法。

          傳統上的選擇,基本是依照“特殊者優先”的原則來進行。一個方法的特殊程度,取決于為了讓它順利運行而需要滿足的條件的數目,需要條件越多的越特殊。

          在引入Varargs機制之后,這一原則仍然適用,只是要考慮的問題豐富了一些——傳統上,一個重載方法的各個版本之中,只有形參數量與實參數量正好一致的那些有被進一步考慮的資格。但是Varargs機制引入之后,完全可以出現兩個版本都能匹配,在其它方面也別無二致,只是一個實參個數固定,而一個實參個數可變的情況。

          遇到這種情況時,所用的判定規則是“實參個數固定的版本優先于實參個數可變的版本”。

          清單13:實參個數固定的版本優先

          public class OverloadingSampleA {      public static void main(String[] args) {          testOverloading(1);//打印出A          testOverloading(1, 2);//打印出B          testOverloading(1, 2, 3);//打印出C      }      private static void testOverloading(int i) {          System.out.println("A");      }      private static void testOverloading(int i, int j) {          System.out.println("B");      }      private static void testOverloading(int i, int... more) {          System.out.println("C");      } }

          如果在編譯器看來,同時有多個方法具有相同的優先權,它就會陷入無法就到底調用哪個方法作出一個選擇的狀態。在這樣的時候,它就會產生一個 “reference to 被調用的方法名 is ambiguous”的編譯錯誤,并耐心的等候作了一些修改,足以免除它的迷惑的新源代碼的到來。

          在引入了Varargs機制之后,這種可能導致迷惑的情況,又增加了一些。例如現在可能會有兩個版本都能匹配,在其它方面也如出一轍,而且都是實參個數可變的沖突發生。

          清單14:左右都不是,為難了編譯器

          public class OverloadingSampleB {      public static void main(String[] args) {          testOverloading(1, 2, 3);//編譯出錯      }      private static void testOverloading(Object... args) {      }      private static void testOverloading(Object o, Object... args) {      } }

          另外,因為J2SE 1.5中有“Autoboxing/Auto-Unboxing”機制的存在,所以還可能發生兩個版本都能匹配,而且都是實參個數可變,其它方面也一模一樣,只是一個能接受的實參是基本類型,而另一個能接受的實參是包裹類的沖突發生。

          清單15:Autoboxing/Auto-Unboxing帶來的新問題

          public class OverloadingSampleC {      public static void main(String[] args) {          /* 編譯出錯 */          testOverloading(1, 2);          /* 還是編譯出錯 */          testOverloading(new Integer(1), new Integer(2));      }      private static void testOverloading(int... args) {      }      private static void testOverloading(Integer... args) {      } }

          9. 歸納總結

          和“用數組包裹”的做法相比,真正的實參個數可變的方法,在調用時傳遞參數的操作更為簡單,含義也更為清楚。不過,這一機制也有它自身的局限,并不是一個完美無缺的解決方案。

          posted @ 2010-06-28 17:55 FaithChen 閱讀(1067) | 評論 (0)編輯 收藏


          2010年6月25日

               摘要:   1.讓@Autowired工作起來的準備工作 要使@Autowired能夠工作,首先需要在配置文件中加入以下代碼 <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />  說...  閱讀全文

          posted @ 2010-06-25 17:05 FaithChen 閱讀(1885) | 評論 (0)編輯 收藏


          2008年6月16日

          DWR是一個框架,簡單的說就是能夠在javascript直接調用java方法,而不必去寫一大堆的javascript代碼。它的實現是基于ajax的,可以實現無刷新效果。
              網上有不少DWR的例子,但大都只是某種方法的調用,本文只在使用層面上介紹DWR,并不涉更多的技術與設計,其目的是讓初學者能夠很快的學會各種java方法在javascript中是如何調用的。

              本文以DWR 1.1 為基礎,對于DWR 2.0,因為還沒有正式發布版,故不做介紹。

          一、 dwr配置篇之web.xml
             1 、最小配置
          <servlet>
            <servlet-name>dwr-invoker</servlet-name>
            <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
          </servlet>
          <servlet-mapping>
            <servlet-name>dwr-invoker</servlet-name>
            <url-pattern>/dwr/*</url-pattern>
          </servlet-mapping>
          2、當我們想看DWR自動生成的測試頁(Using debug/test mode)時,可在servlet配置中加上
          <init-param>
            <param-name>debug</param-name>
            <param-value>true</param-value>
          </init-param>
          這個參數DWR默認是false。如果選擇true,我們可以通過 http://localhost:port/app/dwr看到你部署的每個DWR class。并且可以測試java代碼的每個方法是否運行正常。為了安全考慮,在正式環境下你一定把這個參數設為false。
          3、多個dwr.xml文件的配置
          可能有幾種情況,我們一一列舉。一個servlet,多個dwr.xml配置文件;多個servlet,每個servlet對應一個或多個dwr.xml配置文件。
          3.1、一個servlet,多個dwr.xml配置文件
          <servlet>
              <servlet-name>dwr-invoker</servlet-name>
              <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
              <init-param>
                <param-name>config-1</param-name>
                <param-value>WEB-INF/dwr1.xml</param-value>
              </init-param>
              <init-param>
                <param-name>config-2</param-name>
                <param-value>WEB-INF/dwr2.xml</param-value>
              </init-param>
          </servlet>
          在 這種配置下,param-name的值必須以config開頭。param-name可以有>=0個。如果沒有param-name,那么將會讀取 WEB-INF/dwr.xml。如果有大于零個param-name,那么WEB-INF/dwr.xml文件將不會被讀取。
          3.2 、多個 servlet ,每個 servlet 對應一個或多個 dwr.xml
          <servlet>
             <servlet-name>dwr-invoker</servlet-name>
              <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
          </servlet>
          <servlet>
             <servlet-name>dwr-invoker1</servlet-name>
             <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
             <init-param>
               <param-name>config-admin</param-name>
               <param-value>WEB-INF/dwr1.xml</param-value>
             </init-param>
             <init-param>
               <param-name>debug</param-name>
               <param-value>true</param-value>
             </init-param>
          </servlet>
          <servlet-mapping>
          <servlet-name>dwr-invoker</servlet-name>
             <url-pattern>/dwr/*</url-pattern>
          </servlet-mapping>
          <servlet-mapping>
             <servlet-name>dwr-invoker1</servlet-name>
             <url-pattern>/dwr1/*</url-pattern>
          </servlet-mapping>
          在這種情況下,我們可以根據 J2EE security 來控制權限,針對不同 url, 加不同的角色。


          二、 dwr使用篇
          1、調用沒有返回值和參數的JAVA方法
          1.1、dwr.xml的配置
          <dwr>
          <allow>
          <create creator="new" javascript="testClass" >
          <param name="class" value= "com.dwr.TestClass" />
          <include method="testMethod1"/>
          </create>
          </allow>
          </dwr>
          <allow> 標簽中包括可以暴露給 javascript 訪問的東西。
          <create> 標簽中指定 javascript 中可以訪問的 java 類,并定義 DWR 應當如何獲得要進行遠程的類的實例。 creator="new" 屬性指定 java 類實例的生成方式, new 意味著 DWR 應當調用類的默認構造函數來獲得實例,其他的還有 spring 方式,通過與 IOC 容器 Spring 進行集成來獲得實例等等。 javascript=" testClass " 屬性指定 javascript代碼訪問對象時使用的名稱。
          <param> 標簽指定要公開給 javascript 的 java 類名。
          <include> 標簽指定要公開給 javascript 的方法。不指定的話就公開所有方法。
          <exclude> 標簽指定要防止被訪問的方法。
          1.2、javascript中調用
          首先,引入 javascript 腳本
          <script src='dwr/interface/ testClass.js'></script>
          <script src='dwr/engine.js'></script>
          <script src='dwr/util.js'></script>
          其中 TestClass.js 是 dwr 根據配置文件自動生成的, engine.js 和 util.js 是 dwr 自帶的腳本文件。
          其次,編寫調用 java 方法的 javascript 函數
          Function callTestMethod1(){
                testClass.testMethod1();
          }
          2、調用有簡單返回值的java方法
          2.1、dwr.xml的配置
          配置同1.1
          <dwr>
          <allow>
          <create creator="new" javascript="testClass" >
          <param name="class" value= "com.dwr.TestClass" />
          <include method="testMethod2"/>
          </create>
          </allow>
          </dwr>
          2.2、javascript中調用
          首先,引入 javascript 腳本
          其次,編寫調用 java 方法的 javascript 函數和接收返回值的回調函數
          Function callTestMethod2(){
                testClass.testMethod2(callBackFortestMethod2);
          }
          Function callBackFortestMethod2(data){
               // 其中 date 接收方法的返回值
               // 可以在這里對返回值進行處理和顯示等等
          alert("the return value is " + data);
          }
          其中 callBackFortestMethod2 是接收返回值的回調函數
          3、調用有簡單參數的java方法
          3.1、dwr.xml的配置
          配置同1.1
          <dwr>
          <allow>
          <create creator="new" javascript="testClass" >
          <param name="class" value= "com.dwr.TestClass" />
          <include method="testMethod3"/>
          </create>
          </allow>
          </dwr>
          3.2、javascript中調用
          首先,引入 javascript 腳本
          其次,編寫調用 java 方法的 javascript 函數
          Function callTestMethod3(){
                           // 定義要傳到 java 方法中的參數
                var data;
                // 構造參數
                data = “test String”;
                testClass.testMethod3(data);
          }
          4、調用返回JavaBean的java方法
          4.1、dwr.xml的配置
          <dwr>
          <allow>
          <create creator="new" javascript="testClass" >
          <param name="class" value= "com.dwr.TestClass" />
          <include method="testMethod4"/>
          </create>
          <convert converter="bean" match=" "com.dwr.TestBean">
                            <param name="include" value="username,password" />
          </convert>
          </allow>
          </dwr>
          <creator> 標簽負責公開用于 Web 遠程的類和類的方法, <convertor> 標簽則負責這些方法的參數和返回類型。 convert 元素的作用是告訴 DWR 在服務器Java 對象表示和序列化的 JavaScript 之間如何轉換數據類型。 DWR 自動地在 Java 和 JavaScript 表示之間調整簡單數據類型。這些類型包括 Java 原生類型和它們各自的封裝類表示,還有 String 、 Date 、數組和集合類型。 DWR 也能把 JavaBean 轉換成 JavaScript 表示,但是出于安全性的原因,要求顯式的配置, <convertor> 標簽就是完成此功能的。 converter="bean" 屬性指定轉換的方式采用 JavaBean 命名規范, match=""com.dwr.TestBean" 屬性指定要轉換的 javabean 名稱, <param> 標簽指定要轉換的 JavaBean 屬性。
          4.2 、javascript中調用
          首先,引入 javascript 腳本
          其次,編寫調用 java 方法的 javascript 函數和接收返回值的回調函數
          Function callTestMethod4(){
                testClass.testMethod4(callBackFortestMethod4);
          }
          Function callBackFortestMethod4(data){
               // 其中 date 接收方法的返回值
          // 對于 JavaBean 返回值,有兩種方式處理
                       // 不知道屬性名稱時,使用如下方法
                     for(var property in data){
                        alert("property:"+property);
                        alert(property+":"+data[property]);
                     }
          // 知道屬性名稱時,使用如下方法
                     alert(data.username);
                     alert(data.password);
          }
          其中 callBackFortestMethod4 是接收返回值的回調函數
          5、調用有JavaBean參數的java方法
          5.1、dwr.xml的配置
          配置同4.1
          <dwr>
          <allow>
          <create creator="new" javascript="testClass" >
          <param name="class" value= "com.dwr.TestClass" />
          <include method="testMethod5"/>
          </create>
          <convert converter="bean" match=" com.dwr.TestBean">
                            <param name="include" value="username,password" />
          </convert>
          </allow>
          </dwr>
          5.2 、javascript中調用
          首先,引入 javascript 腳本
          其次,編寫調用 java 方法的 javascript 函數
          Function callTestMethod5(){
                           // 定義要傳到 java 方法中的參數
                var data;
                // 構造參數, date 實際上是一個 object
                data = { username:"user", password:"password"  }
                testClass.testMethod5(data);
          }
          6、調用返回List、Set或者Map的java方法
          6.1、dwr.xml的配置
          配置同4.1
          <dwr>
          <allow>
          <create creator="new" javascript="testClass" >
          <param name="class" value= "com.dwr.TestClass" />
          <include method="testMethod6"/>
          </create>
          <convert converter="bean" match= "com.dwr.TestBean ">
          <param name="include" value="username,password" />
          </convert>
          </allow>
          </dwr>
          注意:如果 List 、 Set 或者 Map 中的元素均為簡單類型(包括其封裝類)或 String 、 Date 、數組和集合類型,則不需要<convert>標簽。
          6.2 、javascript中調用(以返回List為例,List的元素為TestBean)
          首先,引入 javascript 腳本
          其次,編寫調用 java 方法的 javascript 函數和接收返回值的回調函數
          Function callTestMethod6(){
                testClass.testMethod6(callBackFortestMethod6);
          }
          Function callBackFortestMethod6(data){
               // 其中 date 接收方法的返回值
          // 對于 JavaBean 返回值,有兩種方式處理
                       // 不知道屬性名稱時,使用如下方法
                     for(var i=0;i<data.length;i++){
          for(var property in data){
                            alert("property:"+property);
                            alert(property+":"+data[property]);
                         }
          }
          // 知道屬性名稱時,使用如下方法
          for(var i=0;i<data.length;i++){
                         alert(data.username);
                         alert(data.password);
          }
          }
          7、調用有List、Set或者Map參數的java方法
          7.1、dwr.xml的配置
          <dwr>
          <allow>
          <create creator="new" javascript="testClass" >
          <param name="class" value= "com.dwr.TestClass" />
          <include method="testMethod7"/>
          </create>
          <convert converter="bean" match= "com.dwr.TestBean ">
          <param name="include" value="username,password" />
          </convert>
          </allow>
          <signatures>
          <![CDATA[
          import java.util.List;
          import com.dwr.TestClass;
          import com.dwr.TestBean;
          TestClass.testMethod7(List<TestBean>);
          ]]>
          </signatures>
          </dwr>
          <signatures> 標簽是用來聲明 java 方法中 List 、 Set 或者 Map 參數所包含的確切類,以便 java 代碼作出判斷。
          7.2 、javascript中調用(以返回List為例,List的元素為TestBean)
          首先,引入 javascript 腳本
          其次,編寫調用 java 方法的 javascript 函數
          Function callTestMethod7(){
          // 定義要傳到 java 方法中的參數
                var data;
                // 構造參數, date 實際上是一個 object 數組,即數組的每個元素均為 object
          data = [
                                {
                                   username:"user1",
                                   password:"password2"
                                },
                                {
                                   username:"user2",
                                   password:" password2"
                                }
                            ];
                testClass.testMethod7(data);
          }
          注意:
          1、 對于第 6 種情況,如果 java 方法的返回值為 Map ,則在接收該返回值的 javascript 回調函數中如下處理:
          function callBackFortestMethod(data){
                     // 其中 date 接收方法的返回值
                     for(var property in data){
                            var bean = data[property];
                            alert(bean.username);
                            alert(bean.password);
                        }
          }
          2、 對于第 7 種情況,如果 java 的方法的參數為 Map (假設其 key 為 String , value 為 TestBean ),則在調用該方法的 javascript 函數中用如下方法構造要傳遞的參數:
          function callTestMethod (){
                        // 定義要傳到 java 方法中的參數
                        var data;
                        // 構造參數, date 實際上是一個 object ,其屬性名為 Map 的 key ,屬性值為 Map 的 value
                        data = {
                                   "key1":{
                                       username:"user1",
                                      password:"password2"
                                   },
                                   "key2":{
                                      username:"user2",
                                      password:" password2"
                                   }
                               };
                        testClass.testMethod(data);
          }
          并且在 dwr.xml 中增加如下的配置段
          <signatures>
          <![CDATA[
          import java.util.List;
          import com.dwr.TestClass;
          import com.dwr.TestBean;
          TestClass.testMethod7(Map<String,TestBean>);
          ]]>
          </signatures>
          3、 由以上可以發現,對于 java 方法的返回值為 List(Set) 的情況, DWR 將其轉化為 Object 數組,傳遞個 javascript ;對于 java 方法的返回值為 Map 的情況, DWR 將其轉化為一個 Object ,其中 Object 的屬性為原 Map 的 key 值,屬性值為原 Map 相應的 value 值。
          4、 如果 java 方法的參數為 List(Set) 和 Map 的情況, javascript 中也要根據 3 種所說,構造相應的 javascript 數據來傳遞到 java 中。

          posted @ 2008-06-16 15:55 FaithChen 閱讀(269) | 評論 (0)編輯 收藏


          2008年3月6日

           (1)使用 ? 指定參數
          ...
          Query query = session.createQuery("from Student s where
                        s.age > ? and s.name like ? ");
          query.setInteger(0,18);
          query.setString(1,"%abc%");
          ...
          (2)使用 : 后跟變量的方法設置參數
          ...
          Query query = session.createQuery("from Student s where
                        s.age > :minAge and s.name like :likeName ");
          query.setInteger("minAge",18);
          query.setString("likeName","%ABC%");
          ...
          (3)setEntity()方法

          setEntity()方法把參數與一個持久類的實例綁定,例如下面的示例
          ...
          Team team = (Team)session.get(Team.class,"5f45saf45sdf456f");
          Query query = session.createQuery("from Student s where s.team = :team");
          query.setEntity("team",team);  //設置參數為team實例
          ...
          注:上述的team對象可以是持久對象也可以是脫管對象

          (4)setParameter()方法

          setParameter()方法的全稱是setParameter(String paraName,實例,實例類型),這個方法
          可以綁定任何類型的參數.其中第三個參數可以省略,hibernate要以根據實例推斷出絕大部分
          對應的映射類型.
          下面將(3)中的代碼做一下改動
          query.setParameter("team",team,Hibernate.entity(Team.class)).
          或者query.setparameter("team",team).

          (5)setPorperties()方法

          該方法的全稱是setProperties(類實例).它將類實例的屬性名與參數值相對應
          ...
          Student student = new Student();
          student.setAge("18");
          Query query = sesion.createQuery("from Student s where s.age = :age");
          query.setProperties(student);  //設置參數為student對象
          ...
          注意:HQL語句中的變量age必須和student的屬性age同名,否則會出錯.

          posted @ 2008-03-06 16:18 FaithChen 閱讀(681) | 評論 (0)編輯 收藏

          四種xml操作方式的基本使用方法

          xml文件:

          <?xml version="1.0" encoding="GB2312"?>
          <RESULT>
              <VALUE>
                  <NO>A1234</NO>
                 <ADDR>四川省XX縣XX鎮XX路X段XX號</ADDR>
              </VALUE>
              <VALUE>
                  <NO>B1234</NO>
                 <ADDR>四川省XX市XX鄉XX村XX組</ADDR>
              </VALUE>
          </RESULT>

          1)DOM

          import java.io.*;
          import java.util.*;
          import org.w3c.dom.*;
          import javax.xml.parsers.*;

          public class MyXMLReader{
           public static void main(String arge[]){

            long lasting =System.currentTimeMillis();
            try{ 
             File f=new File("data_10k.xml");
             DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
             DocumentBuilder builder=factory.newDocumentBuilder();
             Document doc = builder.parse(f);
             NodeList nl = doc.getElementsByTagName("VALUE");
             for (int i=0;i<nl.getLength();i++){
              System.out.print("車牌號碼:" + doc.getElementsByTagName("NO").item(i).getFirstChild().getNodeValue());
              System.out.println("車主地址:" + doc.getElementsByTagName("ADDR").item(i).getFirstChild().getNodeValue());
             }
            }catch(Exception e){
             e.printStackTrace();
          }

          2)SAX

          import org.xml.sax.*;
          import org.xml.sax.helpers.*;
          import javax.xml.parsers.*;

          public class MyXMLReader extends DefaultHandler {

           java.util.Stack tags = new java.util.Stack();
           public MyXMLReader() {
            super();
             }

           public static void main(String args[]) {
            long lasting = System.currentTimeMillis();
            try {
             SAXParserFactory sf = SAXParserFactory.newInstance();
             SAXParser sp = sf.newSAXParser();
             MyXMLReader reader = new MyXMLReader();
             sp.parse(new InputSource("data_10k.xml"), reader);
            } catch (Exception e) {
             e.printStackTrace();
            }

            System.out.println("運行時間:" + (System.currentTimeMillis() - lasting) + "毫秒");}
            public void characters(char ch[], int start, int length) throws SAXException {
            String tag = (String) tags.peek();
            if (tag.equals("NO")) { 
             System.out.print("車牌號碼:" + new String(ch, start, length));
              }
              if (tag.equals("ADDR")) {
            System.out.println("地址:" + new String(ch, start, length));
              }
             }

            public void startElement(String uri,String localName,String qName,Attributes attrs) {
            tags.push(qName);}

          3) JDOM

          import java.io.*;
          import java.util.*;
          import org.jdom.*;
          import org.jdom.input.*;

          public class MyXMLReader {

           public static void main(String arge[]) {
            long lasting = System.currentTimeMillis();
            try {
             SAXBuilder builder = new SAXBuilder(); 
             Document doc = builder.build(new File("data_10k.xml")); 
             Element foo = doc.getRootElement(); 
             List allChildren = foo.getChildren(); 
             for(int i=0;i<allChildren.size();i++) { 
              System.out.print("車牌號碼:" + ((Element)allChildren.get(i)).getChild("NO").getText());
              System.out.println("車主地址:" + ((Element)allChildren.get(i)).getChild("ADDR").getText());
             }
            } catch (Exception e) {
             e.printStackTrace();
          }

          }

          4)DOM4J

          import java.io.*;
          import java.util.*;
          import org.dom4j.*;
          import org.dom4j.io.*;

          public class MyXMLReader {

           public static void main(String arge[]) {
            long lasting = System.currentTimeMillis();
            try {
             File f = new File("data_10k.xml");
             SAXReader reader = new SAXReader();
             Document doc = reader.read(f);
             Element root = doc.getRootElement();
             Element foo;
             for (Iterator i = root.elementIterator("VALUE"); i.hasNext();) {
              foo = (Element) i.next();
              System.out.print("車牌號碼:" + foo.elementText("NO"));
              System.out.println("車主地址:" + foo.elementText("ADDR"));
             }
            } catch (Exception e) {
             e.printStackTrace();
              }
          }

          posted @ 2008-03-06 11:09 FaithChen 閱讀(255) | 評論 (0)編輯 收藏


          2008年3月5日

          簡介:
          DWR可以幫助開發人員完成應用AJAX技術的web程序,它可以讓瀏覽器上的javascript方法調用運行在web服務器上java方法。
          DWR主要由兩部門組成。javascript與web服務器通信并更新web頁;運行在web服務器的Servlet處理請求并把響應發回瀏覽器。
          DWR采用新穎的方法實現了AJAX(本來也沒有確切的定義),在java代碼基礎上動態的生成javascript代碼。web開發者可以直接調用這些javascript代碼,然而真正的代碼是運行在web服務器上的java code。出與安全考慮,開發者必須配置哪些java class暴露給DWR.(dwr.xml)
          DWR不認為瀏覽器和web服務器之間協議重要,把系統界面放在首位。最大挑戰是java method call的同步特征與ajax異步特性之間的矛盾。在異步模型里,結果只有在方法結束后才有效。DWR解決了這個問題,把回調函數當成參數傳給方法,處理完成后,自動調用回調方法。
          配置:

          1. web.xml: <servlet>
                <servlet-name>dwr-invoker</servlet-name>
                <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
                <init-param>
                           <param-name>debug</param-name>
                    <param-value>false</param-value>
                </init-param>
                <init-param>  
                           <param-name>crossDomainSessionSecurity</param-name>   
                           <param-value>false</param-value>  
                    </init-param>
               </servlet>

               <servlet-mapping>
                 <servlet-name>dwr-invoker</servlet-name>
                 <url-pattern>/dwr/*</url-pattern>
               </servlet-mapping>

          2. dwr.xml:<?xml version="1.0" encoding="UTF-8"?>
            <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://www.getahead.ltd.uk/dwr/dwr20.dtd">
            <dwr>
             <allow>
              <create creator="spring" javascript="main_MenuCatalogDWR" scope="page">
               <param name="beanName" value="/main/MenuCatalogDWR"/>
              </create>
              <create creator="spring" javascript="main_TreeDWR" scope="page">
               <param name="beanName" value="/main/TreeDWR"/>
              </create>
              <create creator="spring" javascript="main_OperateFilterDWR" scope="page">
               <param name="beanName" value="/main/OperateFilterDWR"/>
              </create>
              <create creator="spring" javascript="main_RightTreeDWR" scope="page">
               <param name="beanName" value="/main/RightTreeDWR"/>
              </create>
              <convert converter="dom4j" match="org.directwebremoting.convert.DOM4JConverter">
              </convert>
              <convert converter="dom" match="org.directwebremoting.convert.DOMConverter">
              </convert>
             </allow>
            </dwr>

             3.jsp頁面設置:
                  //以下兩行是dwr所必需的
                  <script type='text/javascript' src="<c:url value='/dwr/engine.js'/>"></script>
                                        <script type='text/javascript' src="<c:url value='/dwr/util.js'/>"></script> 
                  <script type='text/javascript' src="<c:url value='/dwr/interface/main_MenuCatalogDWR.js'/>"></script>
          說明:<script type='text/javascript' src="<c:url value='/dwr/engine.js'/>"></script>
                      <script type='text/javascript' src="<c:url value='/dwr/util.js'/>"></script> 是dwr所必需的
             <script type='text/javascript' src="<c:url value='/dwr/interface/main_MenuCatalogDWR.js'/>"></script>主要作用是:
                      dwr/interface/這種請求到來,(如上面的<script type='text/javascript' src="<c:url  value='/dwr/interface/main_MenuCatalogDWR.js'/>"></script>)DWR做一件偉大的事。把我們在WEB-INF/dwr.xml中的
                     <create creator="spring" javascript="main_MenuCatalogDWR" scope="page">
                            <param name="beanName" value="/main/MenuCatalogDWR"/>
                     </create>轉化為javascript函數。 

          4.beanName配置(本項目spring配置文件為action-servlet.xml)
           <bean name="/main/MenuCatalogDWR" class="com.icsshs.webapp.main.MenuCatalogDWR" singleton="false">
                  <property name="hsRoleRightManager">
                      <ref bean="hsRoleRightManager"/>
                  </property>
              </bean>
          5.jsp頁面調用:
          function menucatalog(){
               main_MenuCatalogDWR.execute("",callbackok);
              }
              function callbackok(data){
                  var root0=data.documentElement;
                  if (root0.childNodes.length>0){
                      if (root0.childNodes(0).childNodes.length==0) return;
                      $("mainmenu").innerHTML=root0.childNodes(0).childNodes(0).text;
                      key=root0.childNodes(1).childNodes(0).text;
                      if (parent.frames.leftFrame.document.readyState == "complete"){
                          setmenuclick(key);
                      }else{
                          setTimeout("setmenuclick('"+key+"')",500);
                      }
                  }
              }

          說明:callbackok為回調函數,data為dwr返回的結果集

          posted @ 2008-03-05 17:40 FaithChen 閱讀(324) | 評論 (0)編輯 收藏


          僅列出標題  

          posts - 4, comments - 0, trackbacks - 0, articles - 4

          Copyright © FaithChen

          主站蜘蛛池模板: 旬邑县| 富源县| 乌拉特中旗| 繁昌县| 乌海市| 澄城县| 南昌市| 会理县| 青海省| 通城县| 夏河县| 综艺| 汤原县| 安丘市| 宝兴县| 荥经县| 邵东县| 荥阳市| 含山县| 海宁市| 兴和县| 大同县| 土默特右旗| 五寨县| 桃园市| 乐昌市| 尤溪县| 陇川县| 秭归县| 石景山区| 收藏| 金溪县| 八宿县| 乌拉特中旗| 赤水市| 昌吉市| 科技| 平和县| 安徽省| 应城市| 惠州市|