<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆:93 文章:11 評論:22 引用:0
    首頁 發(fā)新隨筆
    發(fā)新文章 聯(lián)系 聚合管理

    摘自http://blog.csdn.net/dl88250/archive/2007/10/25/1843813.aspx
    Java Logging API是sun公司于2002年5月正式發(fā)布的。它是自J2SE 1.4版本開始提供的一個新的應(yīng)用程序接口。它能夠很方便地控制和輸出日志信息到文件,控制臺或其它用戶定義的地方,如數(shù)據(jù)庫,電子郵件等。所以它是為最 終用戶,系統(tǒng)管理員,軟件服務(wù)工程師和開發(fā)人員提供的一種捕捉安全漏洞,檢查配置正確性,跟蹤調(diào)查系統(tǒng)運行瓶頸和調(diào)查系統(tǒng)運行錯誤的工具。
    Java Logging API的設(shè)計目標是要:
    1. 能夠在運行時啟動或關(guān)閉日志功能;
    2. 能夠非常精密地控制日志,即能夠啟動或關(guān)閉日志的某個個別功能;
    3. 能夠在運行時注冊日志服務(wù),當然也可以注冊新的第三方日志服務(wù);
    4. 能夠提供連接服務(wù),使Java Logging API能與現(xiàn)存的日志系統(tǒng)(如操作系統(tǒng)的日志功能)連接;
    5. 能夠支持顯示高優(yōu)先度的信息給最終用戶。

    輸出日志
    由于Java Logging API提供了非常方便的接口,你可以在下面的例子里看到它的使用有多方便。
    例1:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package jdk14logger;
    import java.util.logging.Logger; // <= (1)
    public class HelloLogWorld
    {

    private static String name = HelloLogWorld.class.getName();
    private static Logger log = Logger.getLogger(name);// <= (2)

    public void sub()
    {
    log.info("Hello Logging World");// <= (3)
    }

    public static void main(String[] args)
    {
    HelloLogWorld logWorld = new HelloLogWorld();
    logWorld.sub();
    }
    }

    說明:
    1. Logger是Java Logging API中的一個類。在此之前,你必須確認你所使用的J2SE是1.4或更高版本。
    2. Logger.getLogger方法創(chuàng)建了一個Logger實例。每一個Logger實例都必須有個名稱,通常的做法是使用類名稱定義Logger實例。后面還會講到這樣做的原因。
    3. log.info方法用來輸出日志信息。
    執(zhí)行例1你可以看到控制臺上輸出了日期時間,類名,方法名和Hello Logging World的信息。

    輸出的種類
    Java Logging API提供了七個級別用來控制輸出。這七個級別分別是:
    SEVERE (最高級別)
    WARNING
    INFO
    CONFIG
    FINE
    FINER
    FINEST (最低級別)
    與之對應(yīng),在Logger類中也為你預備好了這七個級別的輸出方法。下面是使用這幾種方法輸出日志信息的例子。
    例2:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    package jdk14logger;
    import java.util.logging.Logger;

    public class LevelTest
    {

    private static String name = HelloLogWorld.class.getName();
    private static Logger log = Logger.getLogger(name);

    public void sub()
    {
    log.severe("severe level");// <= (1)
    log.warning("warning level");// <= (2)
    log.info("info level");// <= (3)
    log.config("config level");// <= (4)
    log.fine("fine level");// <= (5)
    log.finer("finer level");// <= (6)
    log.finest("finest level");// <= (7)
    }

    public static void main(String[] args)
    {
    LevelTest test = new LevelTest();
    test.sub();
    }
    }


    執(zhí)行例2你可能看到控制臺上只輸出了(1)-(3)的信息,(4)-(7)的信息并沒有如想象的那樣被輸出。這不要緊,繼續(xù)看下面的內(nèi)容你就知道原因了。

    控制輸出
    上面例2中info以下的級別信息沒有被輸出是因為缺省日志輸出級別的設(shè)置是info,也就是說只有info或它以上的級別被輸出,它以下的級別不被輸 出。通過變更設(shè)置可以使輸出級別改變。變更輸出級別的方法有兩種,一是使用外部配置文件,二是使用程序編碼。通常都是使用第一種方法。缺省的外部配置文件 是JRE中l(wèi)ib/logging.properties文件。你可以打開這個文件,修改以下兩行為:
    .level= ALL
    java.util.logging.ConsoleHandler.level = ALL
    修改完后,再運行一次例2,這次(1)-(7)的內(nèi)容就都輸出出來了。你可以修改輸出級別為以下任何值,試一試輸出有什么變化。
    OFF
    SEVERE
    WARNING
    INFO
    CONFIG
    FINE
    FINER
    FINEST
    ALL

    自定義的配置文件
    如果你不想使用系統(tǒng)提供的缺省配置文件lib/logging.properties,那么也可以使用自己定義的配置文件。使用自定義配置文件的方法有很 多種,比較方便的方法是通過定義系統(tǒng)屬性值java.util.logging.config.file來設(shè)置自定義配置文件。例如在執(zhí)行例2時,使用下 面的命令:
    java -Djava.util.logging.config.file=mylogging.properties LevelTest
    其中mylogging.properties是你自定義的配置文件。如果需要,你還可以加上文件的路徑名。

    更多的輸出控制
    除了前面講到的七個輸出級別外,Logger類中還提供了以下三個便于程序員調(diào)試時使用的輸出信息方法:
    entering
    exiting
    throwing
    它們是與FINER相同級別的輸出,分別用于程序入口,出口和例外時的輸出。除此之外Logger類中還準備了一些輸出信息的方法,這些留待以后詳細介紹。

    輸出內(nèi)容的本地化
    Java Logging API已經(jīng)考慮到了國際化對應(yīng)問題。在輸出信息上你可以使用ResourceBundle提供本地化的輸出信息。下面舉個例子說明。
    例3:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package jdk14logger;
    import java.util.logging.Logger;
    public class LocalTest {
    private static String name = HelloLogWorld.class.getName();
    private static Logger log = Logger.getLogger (name, "jdk14logger/LocalTest");<= (1)
    public void sub() {
    log.severe("level.severe");<= (2)
    log.warning("level.warning");<= (3)
    log.info("level.info");<= (4)
    log.config("level.config");<= (5)
    log.fine("level.fine");<= (6)
    log.finer("level.finer");<= (7)
    log.finest("level.finest");<= (8)
    }
    public static void main(String[] args) {
    LocalTest test = new LocalTest();
    test.sub();
    }
    }

    你可以比較一下例2和例3。可以看到例3的Logger.getLogger 方法調(diào)用中增加了一個傳參,并且(2)-(8)中的輸出內(nèi)容也改變了。(1)中增加的字符串傳參就是使用ResourceBundle配置時的屬性文件 名。下面就需要建立這個屬性文件jdk14logger/LocalTest.properties,內(nèi)容如下:
    level.severe=severe level
    level.warning=warning level
    level.info=info level
    level.config=config level
    level.fine=fine level
    level.finer=finer level
    level.finest=finest level
    現(xiàn)在運行例3可以看到輸出結(jié)果并不是(2)-(8)中定義的內(nèi)容。或許你已經(jīng)想到了,(2)-(8)中定義的實際上是local.properties文 件中的屬性鍵名,而輸出是這些屬性鍵名所對應(yīng)的鍵值。那么或許你要問如果屬性鍵名在屬性文件中不存在怎么辦,答案很簡單,如果它不是屬性鍵名就一定是要輸 出的內(nèi)容,所以就照原樣輸出了事。 
    posted @ 2009-02-19 23:00 redcoatjk 閱讀(1823) | 評論 (0)編輯 收藏
     
    載自http://kuangbaoxu.javaeye.com/blog/192804
    1. 代理模式主要有兩種:靜態(tài)代理和動態(tài)代理

    2. 靜態(tài)代理:

    比如要在輸出“HelloWorld”前打印一個字符串“Welcome”

    A:先定義一個接口類
    1package ttitfly.proxy;    
    2   
    3public interface HelloWorld {    
    4    public void print();    
    5//  public void say();    
    6}
     
    B: 定義一個該接口的實現(xiàn)類

    java 代碼
     1package ttitfly.proxy;    
     2   
     3public class HelloWorldImpl implements HelloWorld{    
     4   
     5    public void print(){    
     6        System.out.println("HelloWorld");    
     7    }
        
     8//  public void say(){    
     9//      System.out.println("Say Hello!");    
    10//  }    
    11}
        
    C:定義一個靜態(tài)代理類
     1package ttitfly.proxy;    
     2   
     3public class StaticProxy implements HelloWorld{    
     4   
     5    public HelloWorld helloWorld ;    
     6    public StaticProxy(HelloWorld helloWorld){    
     7        this.helloWorld = helloWorld;    
     8    }
        
     9        
    10    public void print(){    
    11        System.out.println("Welcome");    
    12        //相當于回調(diào)    
    13        helloWorld.print();    
    14    }
        
    15        
    16//  public void say(){    
    17//      //相當于回調(diào)    
    18//      helloWorld.say();    
    19//  }    
    20}
        
    D: 一個測試類:
     1package ttitfly.proxy;    
     2   
     3public class TestStaticProxy {    
     4   
     5    public static void main(String[] args){    
     6        HelloWorld helloWorld = new HelloWorldImpl();    
     7        StaticProxy staticProxy = new StaticProxy(helloWorld);    
     8        staticProxy.print();    
     9            
    10//      staticProxy.say();    
    11    }
        
    12}
        
    可以看出靜態(tài)代理類有一個很不爽的缺點:當如果接口加一個方法(把上面所有的代碼的注釋給去掉),所有的實現(xiàn)類和代理類里都需要做個實現(xiàn)。這就增加了代碼的復雜度。動態(tài)代理就可以避免這個缺點。 
    3 。動態(tài)代理

    動態(tài)代理與普通的代理相比較,最大的好處是接口中聲明的所有方法都被轉(zhuǎn)移到一個集中的方法中處理(invoke),這樣,在接口方法數(shù)量比較多的時候,我們可以進行靈活處理,而不需要像靜態(tài)代理那樣每一個方法進行中轉(zhuǎn)。

    動態(tài)代理類只能代理接口,代理類都需要實現(xiàn)InvocationHandler類,實現(xiàn)invoke方法。該invoke方法就是調(diào)用被代理接口的所有方法時需要調(diào)用的,該invoke方法返回的值是被代理接口的一個實現(xiàn)類

    代理類: 
     1package ttitfly.proxy;        
     2       
     3import java.lang.reflect.InvocationHandler;        
     4import java.lang.reflect.Method;        
     5import java.lang.reflect.Proxy;        
     6//動態(tài)代理類只能代理接口,代理類都需要實現(xiàn)InvocationHandler類,實現(xiàn)invoke方法。該invoke方法就是調(diào)用被代理接口的所有方法時需要調(diào)用的,該invoke方法返回的值是被代理接口的一個實現(xiàn)類        
     7public class DynamicProxy implements InvocationHandler{        
     8            
     9    private Object object;         
    10    //綁定關(guān)系,也就是關(guān)聯(lián)到哪個接口(與具體的實現(xiàn)類綁定)的哪些方法將被調(diào)用時,執(zhí)行invoke方法。    
    11    //Proxy.newProxyInstance的第三個參數(shù)是表明這些被攔截的方法執(zhí)行時需要執(zhí)行哪個InvocationHandler的invoke方法    
    12    public Object bindRelation(Object object){         
    13        this.object = object;        
    14        return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),this);         
    15    }
             
    16    //攔截關(guān)聯(lián)的這個實現(xiàn)類的方法被調(diào)用時將被執(zhí)行        
    17    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {         
    18        System.out.println("Welcome");        
    19        Object result = method.invoke(object, args);         
    20        return result;        
    21    }
            
    22       
    23}
            

    測試類:
     1package ttitfly.proxy;        
     2       
     3public class TestDynamicProxy {        
     4    public static void main(String[] args){        
     5        HelloWorld helloWorld = new HelloWorldImpl();        
     6        DynamicProxy dp = new DynamicProxy();        
     7        //在這里綁定的是HelloWorld,也就是HelloWorld是被代理接口。所以綁定關(guān)系時,需要傳遞一個HelloWorld的實現(xiàn)類的實例化對象。        
     8        HelloWorld helloWorld1 = (HelloWorld)dp.bindRelation(helloWorld);         
     9        helloWorld1.print();         
    10        helloWorld1.say();        
    11            
    12        //helloWorld2將不被攔截    
    13        HelloWorld helloWorld2 = new HelloWorldImpl();    
    14        helloWorld2.print();         
    15        helloWorld2.say();    
    16            
    17    }
            
    18}
            
    在測試類里調(diào)用實現(xiàn)類的print和say方法,因為代理類里代理了HelloWorld的所有方法。所以就不需要像靜態(tài)代理類那樣一一實現(xiàn)了。
    [本來想自己寫個類似的東西,不過發(fā)現(xiàn)javaeye的這篇寫的已經(jīng)很好了.轉(zhuǎn)載過來學習一下.
     javaeye的代碼copy功能真好用!.]





    posted @ 2009-02-17 18:40 redcoatjk 閱讀(372) | 評論 (1)編輯 收藏
     
    載自http://blog.csdn.net/icecityman/archive/2008/11/08/3256281.aspx

    Java程序在定義類時,除了使用class關(guān)鍵字標識之外,還可以在class之前增加若干類的修飾符來修飾限定所定義的類的特性。類的修飾符分為訪問控制符和非訪問控制符兩大類。修飾符之間的先后排列次序?qū)︻惖男再|(zhì)沒有任何影響。

    一. 非訪問修飾符。
     1. 抽象類:
        凡是用abstract修飾符修飾的類被稱為抽象類。抽象類就是沒有具體對象的概念類。
        抽象類是一種經(jīng)過優(yōu)化的概念組織方式:把共同特點抽象出來;其后在描述和處理某一種具體對象時,就只需描述不同的特殊之處。這種組織方式使得所有的概念層次分明,簡潔洗練,非常符合人們?nèi)粘5乃季S習慣。
        由于抽象類是它的所有子類的公共屬性的集合,所以使用抽象類的一個優(yōu)點就是可以充分利用這些公共屬性來提高開發(fā)和維護程序的效率。
        值得一提的是,面向?qū)ο蠹夹g(shù)是要用更接近于人類思維方式的方法來處理實際問題,抽象類的設(shè)立就是這種思想的具體體現(xiàn)之一,它是模仿人類的思維模式的產(chǎn)物。

     2. 最終類:
        如果一個類被final修飾符所修飾和限定,說明這個類不可能有子類。
        被定義為final的類通常是一些有固定作用、用來完成某種標準功能的類。如Java系統(tǒng)定義好的用來實現(xiàn)網(wǎng)絡(luò)功能的InterAddress、Socket等類都是final類。
           abstract和final修飾符不能同時修飾一個類,因為abstract類自身沒有具體對象,需要派生出子類后在創(chuàng)建子類的對象;而final類不可能有子類。這樣放在一起修飾就沒有意義了。

     3. 有些類的修飾符也可以用來修飾類中的成員變量或方法:
     (1)成員變量:是類和對象的靜態(tài)屬性,定義成員變量的操作就是說明變量或創(chuàng)建對象的操作。
       <1> 靜態(tài)成員變量:用static修飾符修飾的成員變量是僅屬于類的靜態(tài)成員變量。靜態(tài)成員變量是類中每個對象共享的成員變量。他們是類的成員變量,不屬于任何一個類的具體對象。是一個公共的存儲單元,任何一個類的對象訪問它時,取到的都是相同的數(shù)值。
       <2> 靜態(tài)初始化器:靜態(tài)初始化器是由關(guān)鍵字static引導的一對大括號括起的語句組。作用是:在加載時,初始化類的靜態(tài)成員變量。
          與構(gòu)造函數(shù)相同,他們都是用來完成初始化的工作,但是靜態(tài)初始化器與構(gòu)造函數(shù)有三點不同:
           ①構(gòu)造函數(shù)是對每個新創(chuàng)建的對象初始化,而靜態(tài)初始化器是對類自身進行初始化。
           ②構(gòu)造函數(shù)是在用new運算符產(chǎn)生新對象時由系統(tǒng)自動執(zhí)行,而靜態(tài)初始化器則是在它所屬的類加載到內(nèi)存時由系統(tǒng)調(diào)用執(zhí)行。
           ③不同于構(gòu)造函數(shù),靜態(tài)初始化器不是方法,沒有方法名、返回值和參數(shù)列表。
       <3> 最終成員變量:用final修飾的成員變量,實際上就是Java中的常量。
          用final修飾符說明常量時,需要注意以下幾點:
          ①需要說明常量的數(shù)據(jù)類型。
          ②需要同時指出常量的具體取值。
          ③因為所有類對象的常量成員,其數(shù)值都固定一致,為了節(jié)省空間,常量通常聲明為static。
       <4> 易失成員變量:如果一個成員變量被volatile修飾符所修飾,說明這個成員變量可能同時被幾個線程所控制和修改,即這個成員變量不僅僅被當前程序所掌握,在運行過程中可能在其他未知的程序操作影響和改變該成員變量的取值。在使用當中應(yīng)該特別注意。
        通常,volatile用來修飾接受外部輸入的成員變量。如表示當前時間的變量將系統(tǒng)的后臺線程隨時修改,以保證程序中取到的總是最新的當前系統(tǒng)時間,所以可以把它定義為易失成員變量。

     (2)方法:是類的動態(tài)屬性,標志了類所具有的功能和操作。小括號是方法的標志。
       <1> 抽象方法:修飾符abstract修飾的抽象方法是一種僅有方法頭,而沒有具體的方法體和操作實現(xiàn)的方法。使用抽象方法的目的是使所有的子類,對外都呈現(xiàn)一個相同名字的方法,是一個統(tǒng)一的接口。所有的抽象方法,都必須存在于抽象類之中。
       <2> 靜態(tài)方法:用static修飾符修飾的方法,是屬于整個類的類方法,不用的是對象或?qū)嵗姆椒āU{(diào)用這種方法時,應(yīng)該使用類名作前綴;這種方法在內(nèi)存中的代碼段將隨著類的定義而分配和裝載,不被任何一個對象專有;只能處理屬于整個類的成員變量。
       <3> 最終方法:用final修飾符修飾的類方法。功能和內(nèi)部語句不能再更改的方法,不能再被繼承。
        注意:所有已被private修飾符限定為私有的方法,以及所有包含在final類中的方法,都被缺省地認為是final的。
       <4> 本地方法:用native修飾符聲明其他語言書寫方法體并具體實現(xiàn)方法功能的特殊的方法。這里的其他語言包括C/C++/FROTRAN/匯編等。由于native的方法的方法體使用其他語言在程序外部寫成,所以所有的native方法都沒有方法體,而用一個分號代替。
       <5> 同步方法:如果synchronized修飾的方法是一個類的方法(即static的方法),那么在被調(diào)用執(zhí)行前,將把系統(tǒng)類Class中對應(yīng)當前類的對象加鎖。如果synchronized修飾的是一個對象的方法(未用static修飾的方法),則這個方法在被調(diào)用執(zhí)行前,將把當前對象加鎖。Synchronized修飾符主要用于多線程共存的程序中的協(xié)調(diào)和同步。


    二. 訪問控制符。
        訪問控制符是一組限定類、成員變量或方法是否可以被程序里的其他部分訪問和調(diào)用的修飾符。類的訪問控制符只有一個public,成員變量和方法的訪問控制符有四個,分別是public、private、protected、private protected,另外還有一種沒有定義專門的訪問控制符的缺省情況。
     1. 公有訪問控制符public:
          Java的類是通過包的概念來組織的,包氏類的一個松散的集合。處于同一個包中的類可以不需要任何說明而方便的互相訪問和引用,而對于不同包中的類,則不行。但當一個類被聲明為public時,他就具有了被其他包中的類訪問的可能性,只要這些其他包中的類在程序中使用import語句引入public類,就可以訪問和引用這個類。
        類中被設(shè)定為public的方法是這個類對外的接口部分,避免了程序的其他部分直接去操作類內(nèi)的數(shù)據(jù),這實際就是數(shù)據(jù)封裝思想的體現(xiàn)。
        每個Java程序的主類都必須是public類,也是基于相同的原因。
        用public修飾的類的成員變量稱為公共成員變量。如果公共成員變量屬于公共類,則它能被所有的其他類所引用。public修飾符會造成安全性的數(shù)據(jù)封裝性下降,所以一般應(yīng)減少public成員變量的使用。

     2. 缺省訪問控制符:
        缺省訪問控制權(quán)規(guī)定,該類只能被同一個包中的類訪問和引用,而不可以被其他包中的類使用,這種訪問特性又稱為包訪問性。
        同樣道理,類內(nèi)的成員變量或方法如果美育訪問控制符來限定,也就具有包訪問性。
        簡單說,定義在同一個程序中的所有類屬于一個包。

     3. 私有訪問控制符private:
        用private修飾得成員變量或方法只能被該類自身所訪問和修改,而且不能被任何其他類(包括該類的子類)來獲取和引用。private修飾符用來聲明那些類的私有成員,它提供了最高的保護級別。

     4. 保護訪問控制符protected:
        用protected修飾的成員變量可以被三種類所引用:該類自身、與它在同一個包中的其它類、在其他包中的該類的子類。使用protected修飾符的主要作用是允許其他包中該類的子類來訪問父類的特定屬性。

     5. 私有保護訪問控制符 private protected :
        用private protected修飾的成員變量可以被兩種類訪問和引用,一種是該類本身,一種是該類的所有子類。把同一個包內(nèi)的非子類排除在可訪問的范圍之外,使得成員變量更專于具有明確繼承關(guān)系的類,而不是松散地組合在一起的包。

    posted @ 2009-02-10 12:50 redcoatjk 閱讀(519) | 評論 (0)編輯 收藏
     

    一、攔截器的實現(xiàn)

         實現(xiàn)一個攔截器非常簡單。實際上,一個攔截器就是一個普通的類,只是這個類必須實現(xiàn)com.opensymphony.xwork2.interceptor.Interceptor接口。Interceptor接口有如下三個方法:


    public interface Interceptor extends Serializable 
    {
        
    void destroy();
        
    void init();
        String intercept(ActionInvocation invocation
    throws Exception;
    }


     

    其中initdestroy方法只在攔截器加載和釋放(都由Struts2自身處理)時執(zhí)行一次。而intercept方法在每次訪問動作時都會被調(diào)用。Struts2在調(diào)用攔截器時,每個攔截器類只有一個對象實例,而所有引用這個攔截器的動作都共享這一個攔截器類的對象實例,因此,在實現(xiàn)Interceptor接口的類中如果使用類變量,要注意同步問題。

    下面我們來實現(xiàn)一個簡單的攔截器,這個攔截器通過請求參數(shù)action指定一個攔截器類中的方法,并調(diào)用這個方法(我們可以使用這個攔截器對某一特定的動作進行預處理)。如果方法不存在,或是action參數(shù)不存在,則繼續(xù)執(zhí)行下面的代碼。如下面的URL

    http://localhost:8080/struts2/test/interceptor.action?action=test

    訪問上面的url后,攔截器會就會調(diào)用攔截器中的test方法,如果這個方法不存在,則調(diào)用invocation.invoke方法,invoke方法和Servlet過濾器中調(diào)用FilterChain.doFilter方法類似,如果在當前攔截器后面還有其他的攔截器,則invoke方法就是調(diào)用后面攔截器的intercept方法,否則,invoke會調(diào)用Action類的execute方法(或其他的執(zhí)行方法)。

    下面我們先來實現(xiàn)一個攔截器的父類ActionInterceptor。這個類主要實現(xiàn)了根據(jù)action參數(shù)值來調(diào)用方法的功能,代碼如下:


     

    package interceptor;

    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.Interceptor;
    import javax.servlet.http.*;
    import org.apache.struts2.*;

    public class ActionInterceptor implements Interceptor
    {
        
    protected final String INVOKE = "##invoke";
       
        
    public void destroy()
        {
            System.out.println(
    "destroy");
        }

        
    public void init()
        {
            System.out.println(
    "init");
        }

        
    public String intercept(ActionInvocation invocationthrows Exception
        {    
            HttpServletRequest request 
    = ServletActionContext.getRequest();
            String action 
    = request.getParameter("action");
            System.out.println(
    this.hashCode());
            
    if (action != null)
            {
                
    try
                {
                    java.lang.reflect.Method method 
    = this.getClass().getMethod(action);
                    String result 
    = (String)method.invoke(this);
                    
    if(result != null)
                    {
                        
    if(!result.equals(INVOKE))
                            
    return result;
                    }
                    
    else
                        
    return null;
                }
                
    catch (Exception e)
                {
                }
            }
            
    return invocation.invoke();
        }
    }


     

    從上面代碼中的intercept方法可以看出,在調(diào)用action所指定的方法后,來判斷返回值。可能發(fā)生的情況有三種:

    1.        返回值為null,執(zhí)行return null

    2.        返回值為INVOKE,執(zhí)行return invockation.invoke()

    3.        其他情況,執(zhí)行return result result表示指定方法的返回值,如上面代碼所示。

        在實現(xiàn)完上面的攔截器父類后,任何繼承于ActionInterceptor類的攔截器都可以自動根據(jù)action的參數(shù)值調(diào)用自身的相應(yīng)方法。下面我們來實現(xiàn)一個擁有兩個動作方法testprint的攔截器類。代碼如下:


    package interceptor;

    import javax.servlet.http.HttpServletResponse;
    import org.apache.struts2.ServletActionContext;

    public class MultiMethodInterceptor extends ActionInterceptor
    {
        
    public String test() throws Exception
        {
            HttpServletResponse response 
    = ServletActionContext.getResponse();
            response.getWriter().println(
    "invoke test");
            
    return this.INVOKE;
        }

        
    public String print() throws Exception
        {
            HttpServletResponse response 
    = ServletActionContext.getResponse();
            response.getWriter().println(
    "invoke print");

            
    return null;
        }
    }


     

    test方法返回了INVOKE,因此,在執(zhí)行完這個方法后,Struts2會接著調(diào)用其他攔截器的intercept方法或Action類的execute方法。而print方法在執(zhí)行完后,只是返回了null,而不再調(diào)用其他的方法了,也就是訪問如下的url時,動作的execute方法將不會執(zhí)行:

        http://localhost:8080/struts2/test/ddd.action?action=print

        下面我們來實現(xiàn)一個Action類,代碼如下:

    package action;

    import org.apache.struts2.*;
    import com.opensymphony.xwork2.ActionSupport;

    public class InterceptorAction extends ActionSupport
    {
        
    public String abcd() throws Exception
        {
            ServletActionContext.getResponse().getWriter()
                    .println(
    "invoke abcd");
            
    return null;
        }
    }


     

    在這個Action類中,只有一個abcd方法,實際上,這個方法相當于execute方法,在下面會設(shè)置動作的method屬性為abcd。下面我們來在struts.xml中定義攔截器類和動作,代碼如下:


     

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd"
    >
    <struts>
        
    <package name="demo" extends="struts-default" namespace="/test">
            
    <interceptors>
                
    <interceptor name="method" class="interceptor.MultiMethodInterceptor" />
                    
    <interceptor-stack name="methodStack">
                        
    <interceptor-ref name="method" />
                        
    <interceptor-ref name="defaultStack" />
                    
    </interceptor-stack>
            
    </interceptors>

            
    <action name="interceptor" class="action.InterceptorAction" method="abcd">
                
    <interceptor-ref name="methodStack" />
            
    </action>
        
    </package>
    </struts>


     

    在配置上面的methodStack攔截器時要注意,最好在后面引用defaultStack,否則很多通過攔截器提供的功能將失去。

    OK,現(xiàn)在訪問如下的URL

        http://localhost:8080/struts2/test/ddd.action?action=test

    在瀏覽器中將會出現(xiàn)如下的字符串:

        invoke test

    invoke abcd

    而如果訪問http://localhost:8080/struts2/test/ddd.action?action=print,將會只出現(xiàn)如下的字符串:

        invoke print

    大家可以看出,訪問這個url時并沒有調(diào)用abcd方法。如果隨便指定的action值的話,則只調(diào)用abcd方法,如訪問http://localhost:8080/struts2/test/ddd.action?action=aaa,就只會輸出invoke abcd


    二、攔截器的參數(shù)

       
    我們在使用很多Struts2內(nèi)置的攔截器時會發(fā)現(xiàn)有很多攔截器都帶參數(shù),當然。我們自己做的攔截器也可以加上同樣的參數(shù)。有兩個參數(shù)比較常用,這兩個參數(shù)是includeMethodsexcludeMethods,其中includeMethods指定了攔截器要調(diào)用的Action類的執(zhí)行方法(默認是execute),也就是說,只有在includeMethods中指定的方法才會被Struts2調(diào)用,而excludeMethods恰恰相反,在這個參數(shù)中指定的執(zhí)行方法不會被Struts2調(diào)用。如果有多個方法,中間用逗號(,)分隔。在Struts2中提供了一個抽象類來處理這兩個參數(shù)。這個類如下:

    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor

       
    如有繼承于這個類的攔截器類都會自動處理includeMethodsexcludeMethods參數(shù),如下面的攔截器類所示:

    package interceptor;

    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.*;

    public class MyFilterInterceptor extends MethodFilterInterceptor
    {
        
    private String name;
        
    public String getName()
        {
            
    return name;
        }
        
    public void setName(String name)
        {
            
    this.name = name;
        }
        @Override
        
    protected String doIntercept(ActionInvocation invocationthrows Exception
        {
            System.out.println(
    "doIntercept");
            System.out.println(name);
            
    return invocation.invoke();
        }
    }


        MethodFilterInterceptor的子類需要實現(xiàn)doIntercept方法(相當于Interceptorintercept方法),如上面代碼所示。在上面的代碼中還有一個name屬性,是為了讀取攔截器的name屬性而設(shè)置的,如下面的配置代碼所示:


    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd"
    >
    <struts>
        
    <package name="demo" extends="struts-default" namespace="/test">
            
    <interceptors>
                
    <interceptor name="method" class="interceptor.MultiMethodInterceptor" />
                    
    <interceptor name="filter"
                        class
    ="interceptor.MyFilterInterceptor">
                        
    <param name="includeMethods">abcd</param>
                        
    <param name="name">中國</param>
                    
    </interceptor>
                    
    <interceptor-stack name="methodStack">
                        
    <interceptor-ref name="method" />
                        
    <interceptor-ref name="filter" />
                        
    <interceptor-ref name="defaultStack" />
                    
    </interceptor-stack>
            
    </interceptors>

            
    <action name="interceptor" class="action.InterceptorAction" method="abcd">
                
    <interceptor-ref name="methodStack" />
            
    </action>
        
    </package>
    </struts>


        再次訪問http://localhost:8080/struts2/test/ddd.action?action=test, Struts2就會調(diào)用MyFilterInterceptordoIntercept方法來輸出name屬性值。如果將上面的includeMethods參數(shù)值中的abcd去掉,則Action類的abcd方法不會被執(zhí)行。

    posted @ 2008-12-28 22:37 redcoatjk 閱讀(350) | 評論 (0)編輯 收藏
     
     WebWork截獲Action請求,在Action執(zhí)行之前或之后調(diào)用攔截器方法。這樣,可以用插拔的方式將功能注入Action中。WebWork框架的很多功能都是以攔截器的形式提供出來。例如:參數(shù)組裝,驗證,國際化,文件上傳等等。

    1. 一個攔截器就是在xwork.xml文件中定義的一個無狀態(tài)Java類,它至少要實現(xiàn)XWork的com.opensymphony.xwork.interceptor.Interceptor接口。代碼如下:

    public interface Interceptor extends Serializable {

    void destroy();

    void init();

    String intercept(ActionInvocation invocation) throws Exception;

    }

    2. 實現(xiàn)Interceptor接口的攔截器,代碼部分在intercept方法中實現(xiàn)。在intercept方法中,可以直接返回一個Result字符串,這樣整個執(zhí)行直接“短路”,這時Action的execute方法也不會執(zhí)行(一般很少會這么用)。所以,一般都會在這個方法里調(diào)用參數(shù)對象invocation的invoke方法,并返回這個方法執(zhí)行的結(jié)果。這樣會持續(xù)執(zhí)行后面的攔截器方法以及Action的execute方法等。

    3. 大部分的時候,攔截器直接繼承WebWork的抽象類 com.opensymphony.xwork.interceptor.AroundInterceptor就可以了。這時,需要實現(xiàn)它的before 和after方法。Before方法會在Action執(zhí)行之前調(diào)用,after方法在Action執(zhí)行之后調(diào)用。

    4. 攔截器的執(zhí)行順序。我們可將多個攔截器放一起組裝成一個攔截器棧。這樣攔截器會按照棧的順序由上而下執(zhí)行before方法,所有before方法執(zhí)行結(jié)束,再執(zhí)行Action的方法,執(zhí)行Result的方法,再返回執(zhí)行結(jié)果,最后再從下而上執(zhí)行攔截器的after方法


    5. 攔截器的過濾功能。我們通常會在應(yīng)用中使用一個通用的定義多個攔截器的攔截器棧。但有些Action方法在調(diào)用的時候,不需要要其中的部分攔截器。這時,我們就可以使用攔截器過濾功能。如果攔截器要擁有過濾功能,必須實現(xiàn)抽象類 com.opensymphony.xwork.interceptor.MethodFilterInterceptor。這樣,攔截器在定義的時候或者在Action引用攔截器棧的時候,我們就可以指定哪些Action方法是需要過濾的,哪些Action是不需要過濾的。
      攔截器可以將任意代碼包含在調(diào)用棧中活動執(zhí)行前或之后, 它可以極大的簡化代碼同時提供增強代碼復用能力. XWork和WebWork的許多特性多作為攔截器實現(xiàn), 可以和你自己的攔截器一起通過外部配置任意指定順序并配置在任意活動上.
      換言之, 當你訪問一個*.action的地址, WebWork的 class="monospaced">ServletDispatcher執(zhí)行一個活動調(diào)用. 在活動執(zhí)行前, 這一調(diào)用可以被另一個對象截取, 這個對象就稱為攔截器. 要想在一個活動執(zhí)行之前(或之后)設(shè)置一個攔截器, 只需正確配置xwork.xml, 如下例所示:

    攔截器配置:
    <action name="formProcessing" class="lesson04_01_01.FormProcessingAction">
    <result name="input" type="dispatcher">ex01-index.jsp</result>
    <result name="success" type="dispatcher">ex01-success.jsp</result>
    <interceptor-ref name="validationWorkflowStack" />
    </action>
      名為formProcessing的Action使用了validationWorkflowStack. 它是一個截取器棧, 棧中按照截取器的執(zhí)行順序進行組織. 這個截取器棧定義在webwork-default.xml, 這樣我們需要做的就是在活動配置的<interceptor-ref />或包配置中的<default-interceptor-ref />中聲明, 就像:

    攔截器配置:
    <!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN"
    "http://www.opensymphony.com/xwork/xwork-1.0.dtd">


    <xwork>
    <!-- Include webwork defaults (from WebWork JAR). -->
    <include file="webwork-default.xml" />

    <!-- Configuration for the default package. -->
    <package name="default" extends="webwork-default">
    <!-- Default interceptor stack. -->
    <default-interceptor-ref name="defaultStack" />

    <!-- Action: HelloWebWorldAction. -->
    <action name="helloWebWorld" class="lesson03.HelloWebWorldAction">
    <result name="success" type="dispatcher">ex01-success.jsp</result>
    </action>
    </package>
    </xwork>

    -------------------------------------------------------
    寫個示例,實現(xiàn)在interceptor中判斷當前時間,返回問候語句,比如“Good afternoon”
    1.xwork_interceptor.xml
    <!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.1.1//EN" "http://www.opensymphony.com/xwork/xwork-1.1.1.dtd">

    <xwork>

    <package name="hello1" extends="webwork-default">
    <!-- 在action和result code之間建立了聯(lián)系-->
    <interceptors>
    <interceptor name="greetingInterceptor" class="com.vstsoft.action.GreetingInterceptor" />
    </interceptors>
    <action name="greeting" class="com.vstsoft.action.GreetingAction">
    <interceptor-ref name="greetingInterceptor" />
    <result name="success">/success.jsp</result>
    <result name="input">/error.jsp</result>
    </action>
    </package>
    </xwork>
    2.GreetingAction
    package com.vstsoft.action;

    import com.opensymphony.xwork.Action;

    public class GreetingAction implements Action {

    public String execute(){
    // TODO Auto-generated method stub
    for(int i=0;i<10;i++){
    System.out.println(i);
    }
    return SUCCESS;//INPUT對應(yīng)于xwork.xml中的resultcode='success'
    }

    }
    3.GreetingInterceptor
    package com.vstsoft.action;

    import java.util.Calendar;
    import com.opensymphony.xwork.interceptor.Interceptor;
    import com.opensymphony.xwork.ActionInvocation;

    public class GreetingInterceptor implements Interceptor {
    public void init() { }
    public void destroy() { }
    public String intercept(ActionInvocation invocation) throws Exception {
    Calendar calendar = Calendar.getInstance();
    int hour = calendar.get(Calendar.HOUR_OF_DAY);
    String greeting = (hour < 6) ? "Good evening" :
    ((hour < 12) ? "Good morning":
    ((hour < 18) ? "Good afternoon": "Good evening"));

    invocation.getInvocationContext().getSession().put("greeting", greeting);

    String result = invocation.invoke();

    return result;
    }
    }
    4.success.jsp
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%@ taglib prefix="ww" uri="/webwork"%>
    <%String path = request.getContextPath();
    String basePath = request.getScheme() + "://"
    + request.getServerName() + ":" + request.getServerPort()
    + path + "/";
    %>


    <html>
    <head>
    <title>Say Hello</title>
    </head>
    <body>
    <font color="red"><%=session.getAttribute("greeting")%></red>
    </body>
    </html>
    posted @ 2008-12-28 22:16 redcoatjk 閱讀(714) | 評論 (0)編輯 收藏
     

    摘自http://dev.rdxx.com/NET/NETOther/2005-7/27/120335366.shtml
    WML教程1:從第一個實際應(yīng)用全面了解WML

    學習自然語言的最好方法就是溶入相應(yīng)的語言環(huán)境在交流中學習,學習一種編程語言的最好方法就是看例程。為了幫助大家建立WML應(yīng)用的第一印象,所以請大家先看第一個例子:

    <?xml version="1.0"?>
    <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
    "http://www.wapforum.org/DTD/wml_1.1.xml">
    <wml>
     <template>
       <do type="prev" label="back">
         <prev/>
         <!--provide a button you can clink to back a step-->
       </do>
     </template>
    <card id="friends" title="Hot link">
     <p>
       <a href="Sina'>http://wap.sian.com.cn/">Sina WAP</a><br/>
       <a href="#nextcard">Next Card</a>
     </p>
    </card>
    <card id="nextcard">
     <p>
      this is the second card.
     </p>
    </card>
    </wml>

    通過以上示例大家應(yīng)該了解到以下內(nèi)容:

    1、語法:WML的語法與HTML相似,仍然是一種標記語言,而且延續(xù)了xML語法規(guī)則

    2、元素:在XML和WML 語言中,語言的基本元素稱之為"標簽"
      標簽必須被 < 和 > 括起來。
      大多數(shù)標簽都包括"起""止"兩部分,例如:<p>…</p>
      某些特殊標簽可以只有一個標簽,但是必須有結(jié)束標記,例如:<prev/>

    3、屬性:XML語言的標簽可以包含很多屬性,給標簽提供必要的附加信息
      屬性內(nèi)容通常在起始標簽內(nèi)使用
      屬性只作為參數(shù)為標簽提供必要的信息,不會被瀏覽器顯示
      屬性的值需要被引號括起來,可以是單引號或者雙引號,引號可以成對嵌套使用
      例如:<card id="friends" title="Hot link">

    4、注釋
      注釋內(nèi)容是方便制作者閱讀源代碼,不會被瀏覽器顯示
      WML不支持注釋嵌套
      例如:<!-- This is a comment. -->

    5、文檔結(jié)構(gòu)
      WML文檔是由Card和Deck構(gòu)成的,一個Deck是一個或多個Card的集合。在得到客戶終端的請求之后,WML從網(wǎng)絡(luò)上把Deck發(fā)送到客戶的瀏覽器,訪問者可以瀏覽Deck內(nèi)包含的所有Card,而不必從網(wǎng)上單獨下載每一個Card。

    其他一些示例中沒有涉及到的基本內(nèi)容:

    6、大小寫敏感
      無論是標簽元素還是屬性內(nèi)容都是大小寫敏感的,這一點繼承了XML的嚴格特性,任何大小寫錯誤都可能導致訪問錯誤,這是WML制作者必須注意的問題。


    7、躲避語法檢查的方法-CDATA
      CDATA內(nèi)的數(shù)據(jù)內(nèi)容都會被當作文本來處理,從而避開語法檢查,直接作為文本顯示。
      示例:
      < ! [ CDATA [ this ia <b> a test ] ] >
      顯示結(jié)果為
      this ia <b> a test

    8、定義變量
      WML可以使用變量供瀏覽器和Script使用,通過在Deck中的一個Card上設(shè)置變量,其他Card不必重新設(shè)置就可以直接調(diào)用。

      變量的語法如下:
      $identifier
      $(identifier)
      $(identifier:conversion)

      如果變量內(nèi)容包含空格就需要用圓括號括起來。由于變量在語法中有最高的優(yōu)先級,包含變量聲明字符的字符串會被當作變量對待,所以如果要顯示$,就一定要連續(xù)使用兩個$。

      示例:
      <p> Your account has $$15.00 in it.</p>
      顯示結(jié)果為:Your account has $15.00 in it

      XML是一種語法非常嚴格的語言,WML也繼承了這種規(guī)則,任何地不規(guī)范語法都會導致錯誤。

    posted @ 2008-12-16 17:29 redcoatjk 閱讀(243) | 評論 (0)編輯 收藏
     
        這個筆記做的不錯.摘自javaeye:  http://chineseoa.javaeye.com/blog/127282 作者chineseoa
    ---------------------------------------------------------------
    第4章: 實現(xiàn)WebWork action

    action是WebWork編程的核心部分,負責:
    . 封裝和傳遞數(shù)據(jù);
    . 邏輯處理

    一.  Action接口

         要求action實現(xiàn)com.opensymphony.xwork.Action接口,該接口有一唯一方法需要實現(xiàn):

         String execute() throws Exception;

         該接口內(nèi)置很多靜態(tài)屬性,可作為execute()方法的返回值;

    二.  ActionSupport基類

         該類包含了action能夠提供的許多可選服務(wù)的默認實現(xiàn)(實現(xiàn)了很多可選的接口),讓你更容易地開發(fā)自己的action類:

         1. action驗證:(com.opensymphony.xwork.Validateable接口)

            該接口有一個唯一的方法,在該方法中可放入驗證代碼:

            void validate()

            該方法會被合適的intereceptor調(diào)用。調(diào)用過程如下:
            . 執(zhí)行validate()方法;
      . 如校驗action出錯(有錯誤消息增加至action),返回INPUT,否則執(zhí)行這個action;

            示例:

        @Override
        public void validate() {
            if(name==null||name.trim().length()<1) {
                addFieldError("name","Invalid name, please input again!");
            }
            if(password==null||password.trim().length()<1) {
                addFieldError("password","Invalid password, please input again!");
            }       
        }

         2. 顯示錯誤信息:(com.opensymphony.xwork.ValidationAware接口)

            收集錯誤信息并將這些信息顯示給用戶。錯誤信息能夠依據(jù)class(action->actionErrors屬性)級別
            (放入一個Collection->fieldErrors屬性)和字段級別(放入一個Map)進行收集。

            一些常見方法:

            void     addActionError(String anErrorMessage)
                    Add an Action-level error message to this Action.
            void     addActionMessage(String aMessage)
                    Add an Action-level message to this Action.
            void     addFieldError(String fieldName, String errorMessage)        

         3. 獲取用戶的locale: (public interface LocaleProvider接口)

            該接口中擁有唯一的一個方法:

    Locale getLocale();

            通過該方法獲得客戶端的語言和地區(qū);

         4. 顯示本地化文本:(com.opensymphony.xwork.TextProvider接口)

            該接口基本上由多個不同參數(shù)的getText()方法組成,getText()方法用于查找本地化信息文本。
            默認情況下, 本地化信息存于和action同一個包下,同名的.properties結(jié)尾的文本。

            示例:

            cho4.LoginAction.java
            ---------------------------------------------------------------------------
        @Override
        public void validate() {
            if(name==null||name.trim().length()<1) {
                addFieldError("name",getText("invalid.name"));     //通過getText獲取本地化信息
            }
            if(password==null||password.trim().length()<1) {
                addFieldError("password",getText("invalid.password"));
            }       
        }

            ch04/LoginAction.properties
            ---------------------------------------------------------------------------
            invalid.name=Invalid name, please input again\!
            invalid.password=Invalid password, please input again\!

    三.  使用ModelDriven action

         1. ???????????????????????/

     
    四.  通過ActionContext訪問數(shù)據(jù)

         1. 獲得HttpSession;

            方法一:
            Map session = ActionContext.getContext().getSession();
            session.put("user",user);



            方法二:(推薦使用)
            public class Login extends ActionSupport implements SessionAware {
                   Map session;
        
                   public void setSession(Map session) {
                          this.session = session;
                   }
                   ...
            }

            實現(xiàn)SessionAware接口,該接口告知WebWork在action執(zhí)行之前需要設(shè)置session Map。

         2. 訪問request和response

            方法一:
            ActionContext ctx = ActionContext.getContext();
            HttpServletRequest req = ctx.get(ServletActionContext.HTTP_REQUEST);
            HttpSession sessio = req.getSession();

            方法二:
            HttpServletRequest req = ServletActionContext.getRequest(); 
            HttpSession sessio = req.getSession();

            方法三:(推薦使用)
            public class Login extends ActionSupport implements ServletRequestAware {
                   HttpServletRequest req;
        
                   public void setServletRequest(HttpServletRequest req) {
                          this.req = req;
                   }
                   ...
            }     

    五.  處理文件上傳

         1. 使用request封裝類訪問上傳文件

            使用MultiPartRequestWrapper對象,該對象會從request的余下部分中把文件正確地解析出來。

            a. JSP頁面

          
           
             
          

            b. action

            public class FileUpload extends ActionSupport implements ServletRequestAware {
                private HttpServletRequest req;
               
                @Override
                public String execute() {
                    MultiPartRequestWrapper wrapper = (MultiPartRequestWrapper)req;
                    File doc = null;
                    try {
                                            //獲得File對象
                        doc = wrapper.getFiles("doc")[0];
    //獲得內(nèi)容類型
                        System.out.println("content type: "+ wrapper.getContentTypes("doc")[0]);
                                            //獲得初始文件名
                        System.out.println("name: "+wrapper.getFileSystemNames("doc")[0]);
                    }catch(Exception e) {
                        e.printStackTrace();
                    }finally {
                        doc.delete();
                    }
                    return SUCCESS;
                }

                public HttpServletRequest getReq() {
                    return req;
                }

                public void setServletRequest(HttpServletRequest req) {
                    this.req = req;
                }   
               
            }

         2. 自動文件上傳

            WebWork提供了一個interceptor: FileUploadInterceptor, 它封裝了上傳文件的獲取和清理工作:
            . 自動獲得request對象;
            . 自動獲得request封裝對象;
            . 自動清除File對象;

            FileUploadInterceptor在webwork-default.xml中自動設(shè)好。通過使用FileUploadInterceptor, 可以把
            上傳的文件(以及內(nèi)容類型和文件名)看做是一般的表單參數(shù)。

            html表單的input元素命名為doc, File字段也必須命名為doc,如多個文件則類型是 File[];
            內(nèi)容類型命名為[element]ContentType, 如多個文件則類型是 String[];
            文件名命名為[element]FileName, 如多個文件則類型是 String[];

        import java.io.File;
        import com.opensymphony.xwork.ActionSupport;

        public class FileUpload extends ActionSupport {
            private File doc;
            private String docContentType;
            private String docFileName;
           
            @Override
            public String execute() {
                System.out.println("doc: "+doc.getName());
                System.out.println("docContentType: "+docContentType);
                System.out.println("docFileName: "+docFileName);
                return SUCCESS;
            }

            public void setDoc(File doc) {
                this.doc = doc;
            }

            public void setDocContentType(String docContentType) {
                this.docContentType = docContentType;
            }

            public void setDocFileName(String docFileName) {
                this.docFileName = docFileName;
            }   
        }     


         3. 配置設(shè)定

            webwork.properties中有三個屬性可以對上傳文件的選項進行設(shè)定:

            . webwork.multipart.parser: 定義底層的多部分 request 的解析器,可選值為 pell, cos和jakarta.
                                        默認值為pell, 建議選用jakarta。
            . webwork.multipart.saveDir: 上傳文件WebWork臨時保存目錄。如沒設(shè)定,則存于javax.servlet.context.tempdir
                                        系統(tǒng)屬性指定的目錄中;
            . webwork.multipart.maxSize: 上傳文件的大小上限,以字節(jié)為單位。默認值為2097152.
    posted @ 2008-12-16 11:39 redcoatjk 閱讀(251) | 評論 (0)編輯 收藏
     
    OGNL使用小結(jié)(一)
    最近一直使用struts2,表現(xiàn)層采用JSP,用的struts2標簽,支持OGNLOGNL中的# $ %使用場景:
    1、“#”主要有三種用途:
    • 訪問OGNL上下文和Action上下文,#相當于ActionContext.getContext();下表有幾個ActionContext中有用的屬性:
      名稱 作用 例子
      parameters 包含當前HTTP請求參數(shù)的Map #parameters.id[0]作用相當于request.getParameter("id")
      request 包含當前HttpServletRequest的屬性(attribute)的Map #request.userName相當于request.getAttribute("userName")
      session 包含當前HttpSession的屬性(attribute)的Map #session.userName相當于session.getAttribute("userName")
      application 包含當前應(yīng)用的ServletContext的屬性(attribute)的Map #application.userName相當于application.getAttribute("userName")
      attr 用于按request > session > application順序訪問其屬性(attribute) #attr.userName相當于按順序在以上三個范圍(scope)內(nèi)讀取userName屬性,直到找到為止
    • 用于過濾和投影(projecting)集合,如books.{?#this.price<100};
    • 構(gòu)造Map,如#{'foo1':'bar1', 'foo2':'bar2'}。
    2、“%”符號的用途
    在標志的屬性為字符串類型時,計算OGNL表達式的值。例如在Ognl.jsp中加入以下代碼:
    [size=13px]<hr />
    <h3>%的用途</h3>
    <p><s:url value="#foobar['foo1']"
    /></p>
    <p><s:url value="%{#foobar['foo1']}"
    /></p>
    清單6 演示%用途的代碼片段
    3、“$”有兩個主要的用途
    • 用于在國際化資源文件中,引用OGNL表達式,例子請參考《在Struts 2.0中國際化(i18n)您的應(yīng)用程序
    • 在Struts 2配置文件中,引用OGNL表達式,如 <action name="AddPhoto" class="addPhoto">
                  <interceptor-ref name="fileUploadStack" />
                  <result type="redirect">ListPhotos.action?albumId=${albumId}</result>
       </action>

    OGNL使用小結(jié)(二)

    1、OGNL除了支持所有的Java操作符外,還支持以下幾種:
       1、逗號,
         與C語言中的逗號操作符類似。
       2、花括號{}
         用于創(chuàng)建列表,元素之間用逗號分隔。
       3、in和not in
         用于判斷一個值是否在集合中。
    2、訪問靜態(tài)方法和靜態(tài)字段
      @class@method(args)     //調(diào)用靜態(tài)方法
      @class@field         //調(diào)用靜態(tài)字段
      其中class必須給出完整的類名(包括包名),如果省略class,那么默認使用的類是java.util.Math,如:
      @@min(5,3)
      @@max(5,3)
      @@PI
    3、索引訪問
      OGNL支持多種索引方式的訪問。
       1、數(shù)組和列表索引
         在OGNL中,數(shù)組和列表可以大致看成是一樣的。
         如:array[0]、list[0]。表達式:{’zhangsan’,'lisi’,'wangwu’}[1]等。
       2、JavaBean的索引屬性
         要使用索引屬性,需要提供兩對setter和getter方法,一對用于數(shù)組,一對用于數(shù)組中的元素。
         如:有一個索引屬性interest,它的getter和setter如下
         public String[] interest;
         public String[] getInterest(){ return interest;}
         public void setInterest(String[] interest){ this.interest=interest;}
         public String getInterest(int i){ return interest[i]}
         public void setInterest(int i, String newInterest){ interest[i]=newInterest;}
         對于表達式interest[2],OGNL可以正確解釋這個表達式,調(diào)用getInterest(2)方法。如果是設(shè)置的情況下,會調(diào)用setInterest(2,value)方法。
       3、OGNL對象的索引屬性
         JavaBean的索引屬性只能使用整型作為索引,OGNL擴展了索引屬性的概念,可以使用任意的對象來作為索引。
    4、對集合進行操作
      1、創(chuàng)建集合:
         創(chuàng)建列表
           使用花括號將元素包含起來,元素之間使用逗號分隔。如{’zhangsan’,'lisi’,'wangwu’}
         創(chuàng)建數(shù)組
           OGNL中創(chuàng)建數(shù)組與Java語言中創(chuàng)建數(shù)組類似。
         創(chuàng)建Map
           Map使用特殊的語法來創(chuàng)建 #{”key”:value, ……}
           如果想指定創(chuàng)建的Map類型,可以在左花括號前指定Map實現(xiàn)類的類名。如:
           #@java.util.LinkedHashMap@{”key”:”value”,….}
           Map通過key來訪問,如map["key"]或map.key。
      2、投影
         OGNL提供了一種簡單的方式在一個集合中對每一個元素聞?wù){(diào)用相同的方法,或者抽取相同的屬性,并將結(jié)果保存為一個新的集合,稱之為投影。
         假如employees是一個包含了employee對象的列表,那么
           #employees.{name}將返回所有雇員的名字的列表。
         在投影期間,使用#this變量來引用迭代中的當前元素。
           如:objects.{#this instanceof String? #this: #this.toString()}
      3、選擇
         OGNL提供了一種簡單的方式來使用表達式從集合中選擇某些元素,并將結(jié)果保存到新的集合中,稱為選擇。
          如#employees.{?#this.salary>3000}
          將返回薪水大于3000的所有雇員的列表。
           #employees.{^#this.salary>3000}
          將返回第一個薪水大于3000的雇員的列表。
           #employees.{$#this.salary>3000}
          將返回最后一個薪水大于3000的雇員的列表。
    5、lambda表達式
      lambda表達式的語法是:   :[...]。OGNL中的lambda表達式只能使用一個參數(shù),這個參數(shù)通過#this引用。
      如:
       #fact= :[ #this<=1 ? 1 : #this* #fact ( #this-1) ], #fact(30)
       #fib= :[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2)+#fib(#this-1)], #fib(11)
    posted @ 2008-12-15 16:39 redcoatjk 閱讀(3521) | 評論 (0)編輯 收藏
     

    摘自http://blog.csdn.net/liuyf8688/archive/2008/02/17/2100759.aspx
    1、Act.java 

    //接口類
    public interface Act {
        
    public void go();
    }

     2、Chinese.java

    //實體類
    public class Chinese {

        
    public void getAge() {
            System.out.println(
    "entity class.");
        }


    }

    3、Person.java

    //抽象類可以實現(xiàn)接口,并且可以繼承實體類。
    public abstract class Person extends Chinese implements Act {

        
    public void run() {
            System.out.println(
    "run");
        }


        
    public abstract void jump();

    }


    4、Test.java
    public class Test extends Person {

        
    // Act中的方法
        public void go() {
            System.out.println(
    "go");
        }


        
    // Person中的方法
        public void jump() {
            System.out.println(
    "jump");
        }


        
    public static void main(String[] args) {
            Test t 
    = new Test();
            t.go();
            t.run();
            t.jump();
            t.getAge(); 
    // Chinese中的方法
        }

    }
    posted @ 2008-12-15 15:52 redcoatjk 閱讀(423) | 評論 (0)編輯 收藏
     
    JSTL中的EL語言是個災(zāi)難,很難想象一個EL表達式不能去取復雜的屬性還不支持顯示的方法調(diào)用,類似list.get(20).getName(locale)。而且這個災(zāi)難還非常流行,唉。

    幸好OGNL很好的解決了這個問題,而且在Tapestry,Webwork等框架下均已經(jīng)內(nèi)嵌了支持。

    表達式分類:
    1. 訪問屬性:如,user.name
    2. 訪問接口/方法:如,user.verify()
    3. 數(shù)組游標,如:users[2]

    常量:
    字符串、字符:一般使用單引號,也可以使用雙引號,支持所有的轉(zhuǎn)義字符
    數(shù)值:可以使用B表示BigDecimal,H表示BigInteger(不是十六進制)
    布爾:true或者false關(guān)鍵字
    空指針:null關(guān)鍵字

    訪問屬性:
    user.name

    索引位置:
    OGNL提供了一個很有趣的例子:array["length"],其中array作為根對象,調(diào)用其length方法是采用字符串的形式來進行的,等同于array["len" + "gth"],當然等價array.length。

    帶索引的屬性:
    someProperty[2] 可以用來getSomeProperty(2) or setSomeProperty(2, value),查找順序先找關(guān)聯(lián)數(shù)組的方法,再找?guī)饕齾?shù)的方法如下:
    public PropertyType[] getPropertyName()
    public void setPropertyName(PropertyType[] anArray)
    public PropertyType getPropertyName(int index)
    public void setPropertyName(int index, PropertyType value)

    OGNl擴展的帶索引的屬性:
    public PropertyType getPropertyName(IndexType index)
    public void setPropertyName(IndexType index, PropertyType value)
    比如:session.attribute("bar")

    調(diào)用方法:
    method( ensureLoaded(), name ),用逗號分隔參數(shù),由于逗號在OGNL語言中有別的用處,所以在語法上需要小心。

    變量引用:
    使用#標注:#var = 99
    this是OGNL語言中內(nèi)置的對象,用來表示當前表達式的變量。listeners.size().(#this > 100? 2*#this : 20+#this)

    括號:
    method( (ensureLoaded(), name) )這個表達式是調(diào)用一個參數(shù)的method方法。

    鏈接表達式:
    再看一次method( (ensureLoaded(), name) )
    其中ensureLoaded(), name的意思是:調(diào)用ensureLoaded方法,再調(diào)用#this.name,method方法的參數(shù)是name。

    集合構(gòu)建
    { null,"Untitled" }——說明:最好看成數(shù)組,因為集合一般不會支持空元素。

    集合投射
    listeners.{delegate}返回所有l(wèi)istener對象的delegate對象。
    objects.{ #this instanceof String ? #this : #this.toString()}轉(zhuǎn)變?yōu)樽址畬ο?br />

    集合選擇:
    listeners.{? #this instanceof ActionListener}——注意?的位置
    返回單個對象,首個:objects.{^ #this instanceof String },最后一個:objects.{$ #this instanceof String }

    創(chuàng)建對象:
    需要顯式的指定java package,如:new java.util.ArrayList()

    靜態(tài)方法、成員:
    @class@method(args),@class@field,同樣要指定class的全路徑

    表達式賦值:
    如果是AST,OGNL直接解析,如果是其他對象,則將其轉(zhuǎn)化對字符串交給AST解析。

    簡單的功能表達式:
    如遞歸表達式:#fact = :[#this<=1? 1 : #this*#fact(#this-1)], #fact(30H)

    集合的特殊屬性
    Collection:size, isEmpty
    List:iterator
    Map:keys, values
    注意:someMap["size"]可能得到someMap中對應(yīng)key為"size"的對象, 而someMap.size得到someMap的大小.
    Set:iterator
    Iterator:next,hasNext
    Enumeration:next,hasNext,nextElement,hasMoreElements

    與JAVA的不同之處
    逗號:類似C的語法,逗號用于分割兩個不同的表達式
    花括號:用于創(chuàng)建list,元素可以為空
    in和not in:用于集合的contains測試
    posted @ 2008-12-15 15:10 redcoatjk 閱讀(324) | 評論 (0)編輯 收藏
    僅列出標題
    共8頁: 上一頁 1 2 3 4 5 6 7 8 下一頁 
    CALENDER
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(3)

    隨筆分類(22)

    隨筆檔案(76)

    文章分類(12)

    文章檔案(17)

    搜索

    •  

    積分與排名

    • 積分 - 250519
    • 排名 - 227

    最新評論

    評論排行榜


    Powered By: 博客園
    模板提供滬江博客

    主站蜘蛛池模板: 99久久婷婷免费国产综合精品| 亚洲国产成人精品无码区花野真一| 亚洲电影中文字幕| 亚洲自偷自拍另类12p| 97久久国产亚洲精品超碰热| 欧美亚洲国产SUV| 91国内免费在线视频| 99精品视频在线免费观看| 亚洲免费综合色在线视频| 免费人妻av无码专区| 亚洲av福利无码无一区二区| 2020天堂在线亚洲精品专区| 美景之屋4在线未删减免费| A片在线免费观看| 91免费精品国自产拍在线不卡| 免费一级一片一毛片| 国产aⅴ无码专区亚洲av| 色偷偷亚洲女人天堂观看欧| 亚洲av色香蕉一区二区三区蜜桃| h在线看免费视频网站男男| 91精品免费高清在线| 免费国产综合视频在线看| 久久精品国产亚洲av四虎| 亚洲午夜无码久久久久软件| 国产va免费观看| 一本无码人妻在中文字幕免费| 亚洲无码高清在线观看| 亚洲精品在线网站| 羞羞视频免费网站含羞草| 51视频精品全部免费最新| 国产又大又黑又粗免费视频| 亚洲网址在线观看你懂的| 无码天堂亚洲国产AV| 3d动漫精品啪啪一区二区免费| 国产jizzjizz视频全部免费| 中文字幕在线观看亚洲| 男女男精品网站免费观看| 18禁止观看免费私人影院| ZZIJZZIJ亚洲日本少妇JIZJIZ| 亚洲国产无线乱码在线观看| 一级特级aaaa毛片免费观看|