亚洲国产电影在线观看,亚洲国产高清在线精品一区 ,亚洲综合色丁香麻豆http://www.tkk7.com/wuhen86/Jump Over yourself !zh-cnMon, 12 May 2025 16:24:02 GMTMon, 12 May 2025 16:24:02 GMT60JAVA中的反射機制http://www.tkk7.com/wuhen86/articles/355219.html無很無很Thu, 28 Jul 2011 05:45:00 GMThttp://www.tkk7.com/wuhen86/articles/355219.htmlhttp://www.tkk7.com/wuhen86/comments/355219.htmlhttp://www.tkk7.com/wuhen86/articles/355219.html#Feedback0http://www.tkk7.com/wuhen86/comments/commentRss/355219.htmlhttp://www.tkk7.com/wuhen86/services/trackbacks/355219.htmlJAVA反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。
Java反射機制主要提供了以下功能: 在運行時分析類的能力,判斷任意對象所屬類,類中有哪些方法,有哪些成員變量;在運行時控查對象,比如,只寫一個toString()方法供所有的類使用;實現通用數組操作代碼的功能。

1. 得到某個對象的屬性
1 public Object getProperty(Object owner, String fieldName) throws Exception {
2      Class ownerClass = owner.getClass();
3
4      Field field = ownerClass.getField(fieldName);
5
6      Object property = field.get(owner);
7
8      return property;
9 }
Class ownerClass = owner.getClass():得到該對象的Class。
Field field = ownerClass.getField(fieldName):通過Class得到類聲明的屬性。
Object property = field.get(owner):通過對象得到該屬性的實例,如果這個屬性是非公有的,這里會報IllegalAccessException。
2. 得到某個類的靜態屬性
1 public Object getStaticProperty(String className, String fieldName)
2              throws Exception {
3      Class ownerClass = Class.forName(className);
4
5      Field field = ownerClass.getField(fieldName);
6
7      Object property = field.get(ownerClass);
8
9      return property;
10 }
Class ownerClass = Class.forName(className) :首先得到這個類的Class。
Field field = ownerClass.getField(fieldName):和上面一樣,通過Class得到類聲明的屬性。
Object property = field.get(ownerClass) :這里和上面有些不同,因為該屬性是靜態的,所以直接從類的Class里取。
3. 執行某對象的方法
1 public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {
2
3      Class ownerClass = owner.getClass();
4
5      Class[] argsClass = new Class[args.length];
6
7      for (int i = 0, j = args.length; i < j; i++) {
8          argsClass[i] = args[i].getClass();
9      }
10
11      Method method = ownerClass.getMethod(methodName, argsClass);
12
13      return method.invoke(owner, args);
14 }
Class owner_class = owner.getClass() :首先還是必須得到這個對象的Class。
5~9行:配置參數的Class數組,作為尋找Method的條件。
Method method = ownerClass.getMethod(methodName, argsClass):通過Method名和參數的Class數組得到要執行的Method。
method.invoke(owner, args):執行該Method,invoke方法的參數是執行這個方法的對象,和參數數組。返回值是Object,也既是該方法的返回值。
4. 執行某個類的靜態方法
1 public Object invokeStaticMethod(String className, String methodName,
2              Object[] args) throws Exception {
3      Class ownerClass = Class.forName(className);
4
5      Class[] argsClass = new Class[args.length];
6
7      for (int i = 0, j = args.length; i < j; i++) {
8          argsClass[i] = args[i].getClass();
9      }
10
11      Method method = ownerClass.getMethod(methodName, argsClass);
12
13      return method.invoke(null, args);
14 }
基本的原理和實例3相同,不同點是最后一行,invoke的一個參數是null,因為這是靜態方法,不需要借助實例運行。
5. 新建實例
1
2 public Object newInstance(String className, Object[] args) throws Exception {
3      Class newoneClass = Class.forName(className);
4
5      Class[] argsClass = new Class[args.length];
6
7      for (int i = 0, j = args.length; i < j; i++) {
8          argsClass[i] = args[i].getClass();
9      }
10
11      Constructor cons = newoneClass.getConstructor(argsClass);
12
13      return cons.newInstance(args);
14
15 }
這里說的方法是執行帶參數的構造函數來新建實例的方法。如果不需要參數,可以直接使用newoneClass.newInstance()來實現。
Class newoneClass = Class.forName(className):第一步,得到要構造的實例的Class。
第5~第9行:得到參數的Class數組。
Constructor cons = newoneClass.getConstructor(argsClass):得到構造子。
cons.newInstance(args):新建實例。
6. 判斷是否為某個類的實例
1 public boolean isInstance(Object obj, Class cls) {
2      return cls.isInstance(obj);
3 }
7. 得到數組中的某個元素
1 public Object getByArray(Object array, int index) {
2      return Array.get(array,index);
3 }
其中,反射機制最重要的部分是允許你檢查類的結構。java.lang.reflect包中的三個類Field,Method,Constructor類分別描述類的字段,方法和構造器,它們都有一個getName方法,用來返回相應條目的名稱。



無很 2011-07-28 13:45 發表評論
]]>
java中讀取配置文件信息的六種方法http://www.tkk7.com/wuhen86/articles/355218.html無很無很Thu, 28 Jul 2011 05:34:00 GMThttp://www.tkk7.com/wuhen86/articles/355218.htmlhttp://www.tkk7.com/wuhen86/comments/355218.htmlhttp://www.tkk7.com/wuhen86/articles/355218.html#Feedback0http://www.tkk7.com/wuhen86/comments/commentRss/355218.htmlhttp://www.tkk7.com/wuhen86/services/trackbacks/355218.html1。使用Java.util.Properties類的load()方法
示例: InputStream in = lnew BufferedInputStream(new FileInputStream(name));
Properties p = new Properties();
p.load(in);

2。使用java.util.ResourceBundle類的getBundle()方法
示例: ResourceBundle rb = ResourceBundle.getBundle(name, Locale.getDefault());

3。使用java.util.PropertyResourceBundle類的構造函數
示例: InputStream in = new BufferedInputStream(new FileInputStream(name));
ResourceBundle rb = new PropertyResourceBundle(in);

4。使用class變量的getResourceAsStream()方法
示例: InputStream in = JProperties.class.getResourceAsStream(name);
Properties p = new Properties();
p.load(in);

5。使用class.getClassLoader()所得到的java.lang.ClassLoader的getResourceAsStream()方法
示例: InputStream in = JProperties.class.getClassLoader().getResourceAsStream(name);
Properties p = new Properties();
p.load(in);

6。使用java.lang.ClassLoader類的getSystemResourceAsStream()靜態方法



無很 2011-07-28 13:34 發表評論
]]>
JAVA深入探索-參數傳遞http://www.tkk7.com/wuhen86/articles/355216.html無很無很Thu, 28 Jul 2011 05:31:00 GMThttp://www.tkk7.com/wuhen86/articles/355216.htmlhttp://www.tkk7.com/wuhen86/comments/355216.htmlhttp://www.tkk7.com/wuhen86/articles/355216.html#Feedback0http://www.tkk7.com/wuhen86/comments/commentRss/355216.htmlhttp://www.tkk7.com/wuhen86/services/trackbacks/355216.html按值傳參
JAVA中的參數傳遞只存在傳值方式一種,但也有傳引用的概念。
這是java參數傳遞的核心說明。java不像C/C++那樣可以通過指針符或地址符來區分傳值還是傳引用,因為它只有一種參數傳遞的方式,那就是傳值方式。這對初學java的人來說很難理解,通過下面的例子可以看出真正的傳值在java中是如何實現的。
public static void swap(int a,int b){//交換兩個變量的值
       int temp = a;
       a = b;
       b = temp;
       System.out.println("swap:"+a+","+b);
}
......
    int a = 3;
int b = 5;
   swap(a,b);
       System.out.println(a +" "+b);//3 5
......
程序打印結果:
swap:5,3
3   5
由程序的結果可以看到,事實上,經過交換的方法swap()之后,主程序中的變量a,b的值并沒有被改變。
分析過程如下:在調用swap()方法的時候,程序把a、b的副本送到swap()方法中的變量a、b中去,而主程序中的變量a、b中的內容并沒有被改變。所以就會出現上面的結果。
其實,不僅是簡單的數據類型如此 ,如果傳遞的參數是一個對象,也會出現這樣的結果,這與簡單數據類型的情況類似,都可以劃為按值傳參一類中。我們看下面的程序及其分析過程:
public class User{
static void swap(User user1,User user2){
       User user = user1;
       user1 = user2;
       user2 = user;
}
public static void main(String[]args){
       User user3 = new User("ding", 20);
       User user4 = new User("zhao", 18);
       swap(user3, user4);  
   /*進行函數swap(user1,user2)的調用,但是并不會真正把user3和user4所指向的內存空間
      *進行交換,只是在調用的時候,會把user3中存放的內存地址復制一份傳給user1,把user4中存放的
      *內存地址復制一份傳給user2,相當于只是給user1和user2了一個副本,而真正的對象
      *user3和user4并沒有在swap()函數中被觸及。所以函數處理的結果是使user1和user2所指向的內存空間
      *進行交換,而user3和user4中的存放內容仍是原來的內容。*/
       System.out.println(user3.username + "   " +user3.age);//ding   20
       System.out.println(user4.username + "   " +user4.age);//zhao   18

程序的運行結果:
ding   20
zhao   18

傳遞引用
既然說java中的參數傳遞只有by value一種,為什么還要說傳遞引用呢?實際上,java與C++一樣,同樣存在對一個對象的引用進行傳遞的問題,但java中的引用傳遞機制是,把原來變量中保存的內存地址傳遞作為一個參數進行傳遞,而不是直接把引用傳過去。所以在java中仍把它稱做按值傳參。
同樣采用例子的方式來解釋java中的引用傳遞的問題:
.......
public static   void changAge(User user){
       User temp = user;//這時,temp中存放了和原對象相同的內存地址
       temp.age = temp.age + 20;//對user的年齡進行增加的操作,
       /*是對temp所指向的內存空間中的值直接進行操作,所以會對原對象的值造成影響。就相當于是傳遞了原對象的引用*/
}
......
       User user = new User("li",25);//仍采用上例中的User
       changAge(user);//改變user的年齡
       System.out.println(user.age);//45
.......
有了上面例子的說明,我們可能就會想到,如果我們的程序中私有變量是一個對象類型的變量時,在主程序中有了這個私有變量的拷貝,是不是就有可能在修改這個拷貝時不小心把原來的私有變量的值也給改變了呢?
我們來看下面的例子:
class Test{
private Date date=new Date();
public Date getDate(){
return date;
}
public static void main(String[] args){
Test tt=new Test();
Date myDate=tt.getDate();//返回了一個私有變量的拷貝
System.out.println(myDate);
myDate.setTime(new Date().getTime()-(long)(10*365.25*24*3600*1000));//對新產生的拷貝進行修改
System.out.println(tt.getDate());
System.out.println(myDate);
}
}
先來猜一下運行的結果,是前兩句輸出一樣呢還是后兩句輸出一樣(最后一句輸出比第一句輸出的日期早十年)?很多人都會說是前兩句輸出一樣.實際上,你會驚奇地發現,輸出結果顯示后兩者輸出一樣,私有變量在程序外部被改變了,程序的封裝性遭到了破壞。
出錯的原因很微妙.因為myDate和tt指向了同一個對象,對myDate的引用更改方法自動地改變了這個類的私有方法狀態。經過測試可以知道,如果myDate被重新賦值(比如myDate=new Date()),就不會出現上面的結果。但是現在的這個程序,私有變量還是在程序外部被改變了。
如果需要返回一個指向可變對象的引用,我們就需要克隆它,這樣就不會導致上面的私有變量被更改。
上面程序就應更改為:return (Date)date.clone();就可以防止私有變量被修改的麻煩了。
再來執行上面的程序,就會出現不一樣的結果。



無很 2011-07-28 13:31 發表評論
]]>
使用JNI技術實現JAVA程序調用dllhttp://www.tkk7.com/wuhen86/articles/355212.html無很無很Thu, 28 Jul 2011 04:37:00 GMThttp://www.tkk7.com/wuhen86/articles/355212.htmlhttp://www.tkk7.com/wuhen86/comments/355212.htmlhttp://www.tkk7.com/wuhen86/articles/355212.html#Feedback0http://www.tkk7.com/wuhen86/comments/commentRss/355212.htmlhttp://www.tkk7.com/wuhen86/services/trackbacks/355212.htmlJAVA的跨平臺的特性深受java程序員們的喜愛,但正是由于它為了實現跨平臺的目的,使得它和本地機器的各種內部聯系變得很少,大大約束了它的功能,比如與一些硬件設備通信,往往要花費很大的精力去設計流程編寫代碼去管理設備端口,而且有一些設備廠商提供的硬件接口已經經過一定的封裝和處理,不能直接使用java程序通過端口和設備通信,這種情況下就得考慮使用java程序去調用比較擅長同系統打交道的第三方程序,從1.1版本開始的JDK提供了解決這個問題的技術標準:JNI技術.
       JNI是Java Native Interface(Java本地接口)的縮寫,本地是相對于java程序來說的,指直接運行在操作系統之上,與操作系統直接交互的程序.從1.1版本的JDK開始,JNI就作為標準平臺的一部分發行.在JNI出現的初期是為了Java程序與本地已編譯語言,尤其是C和C++的互操作而設計的,后來經過擴展也可以與c和c++之外的語言編寫的程序交互,例如Delphi程序.
       使用JNI技術固然增強了java程序的性能和功能,但是它也破壞了java的跨平臺的優點,影響程序的可移植性和安全性,例如由于其他語言(如C/C++)可能能夠隨意地分配對象/占用內存,Java的指針安全性得不到保證.但在有些情況下,使用JNI是可以接受的,甚至是必須的,例如上面提到的使用java程序調用硬件廠商提供的類庫同設備通信等,目前市場上的許多讀卡器設備就是這種情況.在這必須使用JNI的情況下,盡量把所有本地方法都封裝在單個類中,這個類調用單個的本地庫文件,并保證對于每種目標操作系統,都可以用特定于適當平臺的版本替換這個文件,這樣使用JNI得到的要比失去的多很多.
       現在開始討論上面提到的問題,一般設備商會提供兩種類型的類庫文件,windows系統的會包含.dll/.h/.lib文件,而linux系統的會包含.so/.a文件,這里只討論windows系統下的c/c++編譯的dll文件調用方法.
       我把設備商提供的dll文件稱之為第三方dll文件,之所以說第三方,是因為JNI直接調用的是按它的標準使用c/c++語言編譯的dll文件,這個文件是客戶程序員按照設備商提供的.h文件中的列出的方法編寫的dll文件,我稱之為第二方dll文件,真正調用設備商提供的dll文件的其實就是這個第二方dll文件.到這里,解決問題的思路已經產生了,大慨分可以分為三步:
       1>編寫一個java類,這個類包含的方法是按照設備商提供的.h文件經過變形/轉換處理過的,并且必須使用native定義.這個地方需要注意的問題是java程序中定義的方法不必追求和廠商提供的頭文件列出的方法清單中的方法具有相同的名字/返回值/參數,因為一些參數類型如指針等在java中沒法模擬,只要能保證這個方法能實現原dll文件中的方法提供的功能就行了;
       2>按JNI的規則使用c/c++語言編寫一個dll程序;
       3>按dll調用dll的規則在自己編寫的dll程序里面調用廠商提供的dll程序中定義的方法.

       我之前為了給一個java項目添加IC卡讀寫功能,曾經查了很多資料發現查到的資料都是只說到第二步,所以剩下的就只好自己動手研究了.下面結合具體的代碼來按這三個步驟分析.

     1>假設廠商提供的.h文件中定義了一個我們需要的方法:
      __int16 __stdcall readData( HANDLE icdev, __int16 offset, __int16 len, unsigned char *data_buffer );
      a.__int16定義了一個不依賴于具體的硬件和軟件環境,在任何環境下都占16 bit的整型數據(java中的int類型是32 bit),這個數據類型是vc++中特定的數據類型,所以我自己做的dll也是用的vc++來編譯.
     b.__stdcall表示這個函數可以被其它程序調用,vc++編譯的DLL欲被其他語言編寫的程序調用,應將函數的調用方式聲明為__stdcall方式,WINAPI都采用這種方式.c/c++語言默認的調用方式是__cdecl,所以在自己做可被java程序調用的dll時一定要加上__stdcall的聲明,否則在java程序執行時會報類型不匹配的錯誤.
     c.HANDLE icdev是windows操作系統中的一個概念,屬于win32的一種數據類型,代表一個核心對象在某一個進程中的唯一索引,不是指針,在知道這個索引代表的對象類型時可以強制轉換成此類型的數據.
    這些知識都屬于win32編程的范圍,更為詳細的win32資料可以查閱相關的文檔.
    這個方法的原始含義是通過設備初始時產生的設備標志號icdev,讀取從某字符串在內存空間中的相對超始位置offset開始的共len個字符,并存放到data_buffer指向的無符號字符類型的內存空間中,并返回一個16 bit的整型值來標志這次的讀設備是否成功,這里真正需要的是unsigned char *這個指針指向的地址存放的數據,而java中沒有指針類型,所以可以考慮定義一個返回字符串類型的java方法,原方法中返回的整型值也可以按經過一定的規則處理按字符串類型傳出,由于HANDLE是一個類型于java中的Ojbect類型的數據,可以把它當作int類型處理,這樣java程序中的方法定義就已經形成了:
    String readData( int icdev, int offset, int len );
    聲明這個方法的時候要加上native關鍵字,表明這是一個與本地方法通信的java方法,同時為了安全起見,此文方法要對其它類隱藏,使用private聲明,再另外寫一個public方法去調用它,同時要在這個類中把本地文件加載進來,最終的代碼如下:

package test;

public class LinkDll
{
    //從指定地址讀數據
    private native String readData( int icdev, int offset, int len );
    public String readData( int icdev, int offset, int len )
    {
        return this.readDataTemp( icdev, offset, len );
    }

    static 
    {        
        System.loadLibrary( "TestDll" );//如果執行環境是linux這里加載的是SO文件,如果是windows環境這里加載的是dll文件
    }
}

2>使用JDK的javah命令為這個類生成一個包含類中的方法定義的.h文件,可進入到class文件包的根目錄下(只要是在classpath參數中的路徑即可),使用javah命令的時候要加上包名javah test.LinkDll,命令成功后生成一個名為test_LinkDll.h的頭文件.
    文件內容如下:

/* DO NOT EDIT THIS FILE - it is machine generated*/
#include <jni.h>

/* Header for class test_LinkDll */
#ifndef _Included_test_LinkDll #define

Included_test_LinkDll
#ifdef __cplusplus extern "C" { #endif
/*
* Class:     test_LinkDll
* Method:    readDataTemp
* Signature: (III)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_test_LinkDll_readDataTemp(JNIEnv *, jobject, jint, jint, jint);
#ifdef __cplusplus } #endif
#endif

    可以看出,JNI為了實現和dll文件的通信,已經按它的標準對方法名/參數類型/參數數目作了一定的處理,其中的JNIEnv*/jobjtct這兩個參數是每個JNI方法固有的參數,javah命令負責按JNI標準為每個java方法加上這兩個參數.JNIEnv是指向類型為JNIEnv_的一個特殊JNI數據結構的指針,當由C++編譯器編譯時JNIEnv_結構其實被定義為一個類,這個類中定義了很多內嵌函數,通過使用"->"符號,可以很方便使用這些函數,如:
    (env)->NewString( jchar* c, jint len )
    可以從指針c指向的地址開始讀取len個字符封裝成一個JString類型的數據.
    其中的jchar對應于c/c++中的char,jint對應于c/c++中的len,JString對應于java中的String,通過查看jni.h可以看到這些數據類型其實都是根據java和c/c++中的數據類型對應關系使用typedef關鍵字重新定義的基本數據類型或結構體.
    具體的對應關系如下:
Java類型     本地類型             描述
boolean       jboolean             C/C++8位整型
byte             jbyte                   C/C++帶符號的8位整型
char             jchar                   C/C++無符號的16位整型
short            jshort                  C/C++帶符號的16位整型
int                 jint                      C/C++帶符號的32位整型
long             jlong                   C/C++帶符號的64位整型e
float             jfloat                   C/C++32位浮點型
double        jdouble               C/C++64位浮點型
Object          jobject                 任何Java對象,或者沒有對應java類型的對象
Class         jclass                  Class對象
String          jstring                  字符串對象
Object[]      jobjectArray         任何對象的數組
boolean[]    jbooleanArray     布爾型數組
byte[]          jbyteArray           比特型數組
char[]           jcharArray            字符型數組
short[]          jshortArray           短整型數組
int[]             jintArray                整型數組
long[]          jlongArray             長整型數組
float[]         jfloatArray              浮點型數組
double[]     jdoubleArray        雙浮點型數組
    更為詳細的資料可以查閱JNI文檔.
    需要注意的問題:test_LinkDll.h文件包含了jni.h文件;

3>使用vc++ 6.0編寫TestDll.dll文件,這個文件名是和java類中loadLibrary的名稱一致.
a>使用vc++6.0 新建一個Win32 Dynamic-Link Library的工程文件,工程名指定為TestDll
b>把源代碼文件和頭文件使用"Add Fiels to Project"菜單加載到工程中,若使用c來編碼,源碼文件后綴名為.c,若使用c++來編碼,源碼文件擴展名為.cpp,這個一定要搞清楚,因為對于不同的語言,使用JNIEnv指針的方式是不同的.
c>在這個文件里調用設備商提供的dll文件,設備商一般提供三種文件:dll/lib/h,這里假設分別為A.dll/A.lib/A.h.
這個地方的調用分為動態調用和靜態調用靜態調用即是只要把被調用的dll文件放到path路徑下,然后加載lib鏈接文件和.h頭文件即可直接調用A.dll中的方法:
把設備商提供的A.h文件使用"Add Fiels to Project"菜單加載到這個工程中,同時在源代碼文件中要把這個A.h文件使用include包含進來;
然后依次點擊"Project->settings"菜單,打開link選項卡,把A.lib添加到"Object/library modules"選項中.
具體的代碼如下:
//讀出數據,需要注意的是如果是c程序在調用JNI函數時必須在JNIEnv的變量名前加*,如(*env)->xxx,如果是c++程序,則直接使用(env)->xxx

#include<WINDOWS.H>
#include<MALLOC.H>
#include<STDIO.H>
#include<jni.h>
#include "test_LinkDll.h"
#include "A.h"

JNIEXPORT jstring JNICALL Java_test_LinkDll_readDataTemp( JNIEnv *env, jobject jo, jint ji_icdev, jint ji_len )
{
    //*************************基本數據聲明與定義******************************
     HANDLE H_icdev = (HANDLE)ji_icdev;//設備標志符
    __int16 i16_len = (__int16)ji_len;//讀出的數據長度,值為3,即3個HEX形式的字符
    __int16 i16_result;//函數返回值
    __int16 i16_coverResult;//字符轉換函數的返回值
        int i_temp;//用于循環的中間變量
      jchar jca_result[3] = { 'e', 'r', 'r' };//當讀數據錯誤時返回此字符串

    //無符號字符指針,指向的內存空間用于存放讀出的HEX形式的數據字符串
    unsigned char* uncp_hex_passward = (unsigned char*)malloc( i16_len );
    //無符號字符指針,指向的內存空間存放從HEX形式轉換為ASC形式的數據字符串
    unsigned char* uncp_asc_passward = (unsigned char*)malloc( i16_len * 2 );
    //java char指針,指向的內存空間存放從存放ASC形式數據字符串空間讀出的數據字符串
    jchar *jcp_data = (jchar*)malloc(i16_len*2+1);
    //java String,存放從java char數組生成的String字符串,并返回給調用者
    jstring js_data = 0;

    //*********讀出3個HEX形式的數據字符到uncp_hex_data指定的內存空間**********
    i16_result = readData( H_icdev, 6, uncp_hex_data );//這里直接調用的是設備商提供的原型方法.

    if ( i16_result != 0 )
    {
        printf( "讀卡錯誤......\n" );
        //這個地方調用JNI定義的方法NewString(jchar*,jint),把jchar字符串轉換為JString類型數據,返回到java程序中即是String
        return (env)->NewString( jca_result, 3 );
    }

    printf( "讀數據成功......\n" );

    //**************HEX形式的數據字符串轉換為ASC形式的數據字符串**************
    i16_coverResult = hex_asc( uncp_hex_data, uncp_asc_data, 3 );
    if ( i16_coverResult != 0 )
    {
        printf( "字符轉換錯誤!\n" );
        return (env)->NewString( jca_result, 3 );
    }

    //**********ASC char形式的數據字符串轉換為jchar形式的數據字符串***********
    for ( i_temp = 0; i_temp < i16_len; i_temp++ ) 
        jcp_data[i_temp] = uncp_hex_data[i_temp];
    //******************jchar形式的數據字符串轉換為java String****************
    js_data = (env)->NewString(jcp_data,i16_len); 
    return js_data;
}

動態調用,不需要lib文件,直接加載A.dll文件,并把其中的文件再次聲明,代碼如下:
#include<STDIO.H>
#include<WINDOWS.H>
#include "test_LinkDll.h"

//首先聲明一個臨時方法,這個方法名可以隨意定義,但參數同設備商提供的原型方法的參數保持一致.
typedef int ( *readDataTemp )( int, int, int, unsigned char * );//從指定地址讀數據

//從指定地址讀數據
JNIEXPORT jstring JNICALL Java_readDataTemp( JNIEnv *env, jobject jo, jint ji_icdev, jint ji_offset, jint ji_len )
{
    int i_temp;
    int i_result;
    int i_icdev = (int)ji_icdev;
    int i_offset = (int)ji_offset;
    int i_len = (int)ji_len;
    jchar jca_result[5] = { 'e', 'r', 'r' };
    unsigned char *uncp_data = (unsigned char*)malloc(i_len);
    jchar *jcp_data = (jchar *)malloc(i_len);
    jstring js_data = 0;
    //HINSTANCE是win32中同HANDLE類似的一種數據類型,意為Handle to an instance,常用來標記App實例,在這個地方首先把A.dll加載到內存空間,以一個App的形式存放,然后取

得它的instance交給dllhandle,以備其它資源使用.
    HINSTANCE dllhandle;
    dllhandle = LoadLibrary( "A.dll" );
    //這個地方首先定義一個已聲明過的臨時方法,此臨時方法相當于一個結構體,它和設備商提供的原型方法具有相同的參數結構,可互相轉換
    readDataTemp readData;

    //使用win32的GetProcAddress方法取得A.dll中定義的名為readData的方法,并把這個方法轉換為已被定義好的同結構的臨時方法,
    //然后在下面的程序中,就可以使用這個臨時方法了,使用這個臨時方法在這時等同于使用A.dll中的原型方法.
    readData = (readDataTemp) GetProcAddress( dllhandle, "readData" );

    i_result = (*readData)( i_icdev, i_offset, i_len, uncp_data );

    if ( i_result != 0 )
    {
        printf( "讀數據失敗......\n" );
        return (env)->NewString( jca_result, 3 );
    }

    for ( i_temp = 0; i_temp < i_len; i_temp++ )
    {
        jcp_data[i_temp] = uncp_data[i_temp];
    }

    js_data = (env)->NewString( jcp_data, i_len );

    return js_data;
}

4>以上即是一個java程序調用第三方dll文件的完整過程,當然,在整個過程的工作全部完成以后,就可以使用java類LinkDll中的public String radData( int, int, int )方法了,效果同直接使用c/c++調用這個設備商提供的A.dll文件中的readData方法幾乎一樣.

總結:JNI技術確實是提高了java程序的執行效率,并且擴展了java程序的功能,但它也確確實實破壞了java程序的最重要的優點:平臺無關性,所以除非必須(不得不)使用JNI技術,一般還是提倡寫100%純java的程序.根據自己的經驗及查閱的一些資料,把可以使用JNI技術的情況羅列如下:
    1>需要直接操作物理設備,而沒有相關的驅動程序,這時候我們可能需要用C甚至匯編語言來編寫該設備的驅動,然后通過JNI調用;
    2>涉及大量數學運算的部分,用java會帶來些效率上的損失;
    3>用java會產生系統難以支付的開銷,如需要大量網絡鏈接的場合;
    4>存在大量可重用的c/c++代碼,通過JNI可以減少開發工作量,避免重復開發.
另外,在利用JNI技術的時候要注意以下幾點:
    1>由于Java安全機制的限制,不要試圖通過Jar文件的方式發布包含本地化方法的Applet到客戶端;
    2>注意內存管理問題,雖然在本地方法返回Java后將自動釋放局部引用,但過多的局部引用將使虛擬機在執行本地方法時耗盡內存;
    3>JNI技術不僅可以讓java程序調用c/c++代碼,也可以讓c/c++代碼調用java代碼.

注:有一個名叫Jawin開源項目實現了直接讀取第三方dll文件,不用自己辛苦去手寫一個起傳值轉換作用的dll文件,有興趣的可以研究一下.但是我用的時候不太順手,有很多規則限制,像自己寫程序時可以隨意定義返回值,隨意轉換類型,用這個包的話這些都是不可能的了,所以我的項目還沒開始就把它拋棄了.



無很 2011-07-28 12:37 發表評論
]]>
J2EE 13種技術規范http://www.tkk7.com/wuhen86/articles/355211.html無很無很Thu, 28 Jul 2011 04:34:00 GMThttp://www.tkk7.com/wuhen86/articles/355211.htmlhttp://www.tkk7.com/wuhen86/comments/355211.htmlhttp://www.tkk7.com/wuhen86/articles/355211.html#Feedback0http://www.tkk7.com/wuhen86/comments/commentRss/355211.htmlhttp://www.tkk7.com/wuhen86/services/trackbacks/355211.htmlJ2EE平臺由一整套服務(Services)、應用程序接口(APIs)和協議構成,它對開發基于Web的多層應用提供了功能支持,下面對J2EE中的13種技術規范進行簡單的描述(限于篇幅,這里只能進行簡單的描述):
1.JDBC(Java Database Connectivity):
JDBC API為訪問不同的數據庫提供了一種統一的途徑,象ODBC一樣,JDBC對開發者屏蔽了一些細節問題,另外,JDCB對數據庫的訪問也具有平臺無關性。
2.JNDI(Java Name and Directory Interface):
JNDI API被用于執行名字和目錄服務。它提供了一致的模型來存取和操作企業級的資源如DNS和LDAP,本地文件系統,或應用服務器中的對象。
3.EJB(Enterprise JavaBean):
J2EE技術之所以贏得某體廣泛重視的原因之一就是EJB。它們提供了一個框架來開發和實施分布式商務邏輯,由此很顯著地簡化了具有可伸縮性和高度復雜的企業級應用的開發。EJB規范定義了EJB組件在何時如何與它們的容器進行交互作用。容器負責提供公用的服務,例如目錄服務、事務管理、安全性、資源緩沖池以及容錯性。但這里值得注意的是,EJB并不是實現J2EE的唯一途徑。正是由于J2EE的開放性,使得有的廠商能夠以一種和EJB平行的方式來達到同樣的目的。
4.RMI(Remote Method Invoke):
正如其名字所表示的那樣,RMI協議調用遠程對象上方法。它使用了序列化方式在客戶端和服務器端傳遞數據。RMI是一種被EJB使用的更底層的協議。
5.Java IDL/CORBA:
在Java IDL的支持下,開發人員可以將Java和CORBA集成在一起。 他們可以創建Java對象并使之可在CORBA ORB中展開, 或者他們還可以創建Java類并作為和其它ORB一起展開的CORBA對象的客戶。后一種方法提供了另外一種途徑,通過它Java可以被用于將你的新的應用和舊的系統相集成。
6.JSP(Java Server Pages):
JSP頁面由HTML代碼和嵌入其中的Java代碼所組成。服務器在頁面被客戶端所請求以后對這些Java代碼進行處理,然后將生成的HTML頁面返回給客戶端的瀏覽器。
7.Java Servlet:
Servlet是一種小型的Java程序,它擴展了Web服務器的功能。作為一種服務器端的應用,當被請求時開始執行,這和CGI Perl腳本很相似。Servlet提供的功能大多與JSP類似,不過實現的方式不同。JSP通常是大多數HTML代碼中嵌入少量的Java代碼,而servlets全部由Java寫成并且生成HTML。
8.XML(Extensible Markup Language):
XML是一種可以用來定義其它標記語言的語言。它被用來在不同的商務過程中共享數據。XML的發展和Java是相互獨立的,但是,它和Java具有的相同目標正是平臺獨立性。通過將Java和XML的組合,您可以得到一個完美的具有平臺獨立性的解決方案。
9.JMS(Java Message Service):
MS是用于和面向消息的中間件相互通信的應用程序接口(API)。它既支持點對點的域,有支持發布/訂閱(publish/subscribe)類型的域,并且提供對下列類型的支持:經認可的消息傳遞,事務型消息的傳遞,一致性消息和具有持久性的訂閱者支持。JMS還提供了另一種方式來對您的應用與舊的后臺系統相集成。
10.JTA(Java Transaction Architecture):
JTA定義了一種標準的API,應用系統由此可以訪問各種事務監控。
11.JTS(Java Transaction Service):
JTS是CORBA OTS事務監控的基本的實現。JTS規定了事務管理器的實現方式。該事務管理器是在高層支持Java Transaction API (JTA)規范,并且在較底層實現OMG OTS specification的Java映像。JTS事務管理器為應用服務器、資源管理器、獨立的應用以及通信資源管理器提供了事務服務。
12.JavaMail:
JavaMail是用于存取郵件服務器的API,它提供了一套郵件服務器的抽象類。不僅支持SMTP服務器,也支持IMAP服務器。
13.JAF(JavaBeans Activation Framework):
JavaMail利用JAF來處理MIME編碼的郵件附件。MIME的字節流可以被轉換成Java對象,或者轉換自Java對象。大多數應用都可以不需要直接使用JAF。

 

轉自:http://hi.baidu.com/dinguangx/blog/item/c6f5003ddcd688c19e3d6279.html



無很 2011-07-28 12:34 發表評論
]]>
pl/sql中添加 shortcuts插件http://www.tkk7.com/wuhen86/articles/355188.html無很無很Thu, 28 Jul 2011 01:05:00 GMThttp://www.tkk7.com/wuhen86/articles/355188.htmlhttp://www.tkk7.com/wuhen86/comments/355188.htmlhttp://www.tkk7.com/wuhen86/articles/355188.html#Feedback0http://www.tkk7.com/wuhen86/comments/commentRss/355188.htmlhttp://www.tkk7.com/wuhen86/services/trackbacks/355188.html在pl/sql中添加快捷鍵的支持只需要把一個文本類型的文件plugin.txt放入到pl/sql安裝目錄下的plugins文件夾中。

其中plugin.txt 文件中的內容為(自定義的內容,可以根據自己的習慣設置):

s = select * from
sc* = select count(*) from
w = where
ss = select /*+parallel(a,6)*/ * from

打開pl/sql developer進入[首選項]->[用戶界面]->[編輯器]->[autoreplace],選中enabled復選框,再查找 plugin.txt所在的路徑,點擊[應用]即完成插件的安裝。

重啟pl/sql developer,打開sql編輯窗口,輸入s,再按空格,就可以出現select * from,這樣就可以不必每次都輸入這段經常使用而又經常打錯的語句了。



無很 2011-07-28 09:05 發表評論
]]>
myeclipse工程改為Eclipsehttp://www.tkk7.com/wuhen86/articles/351347.html無很無很Mon, 30 May 2011 08:33:00 GMThttp://www.tkk7.com/wuhen86/articles/351347.htmlhttp://www.tkk7.com/wuhen86/comments/351347.htmlhttp://www.tkk7.com/wuhen86/articles/351347.html#Feedback0http://www.tkk7.com/wuhen86/comments/commentRss/351347.htmlhttp://www.tkk7.com/wuhen86/services/trackbacks/351347.html中加入 org.eclipse.wst.common.project.facet.core.natureorg.eclipse.wst.common.modulecore.ModuleCoreNatureorg.eclipse.jem.workbench.JavaEMFNature中加入 org.eclipse.wst.common.project.facet.core.builderorg.eclipse.wst.validation.validationbuilder 做完以上步驟後,刷新項目;點擊右鍵->項目->右鍵 ->Properties->Project Facets->Modify Project在彈出的面板中,選擇Java和Dynamic Web Module 下一步是配置Context Root 和Content Directory 以及源碼路徑,配置完成。

無很 2011-05-30 16:33 發表評論
]]>
如何不重新啟動 Emacs 就讓 .emacs 的配置起作用http://www.tkk7.com/wuhen86/articles/350470.html無很無很Wed, 18 May 2011 05:53:00 GMThttp://www.tkk7.com/wuhen86/articles/350470.htmlhttp://www.tkk7.com/wuhen86/comments/350470.htmlhttp://www.tkk7.com/wuhen86/articles/350470.html#Feedback0http://www.tkk7.com/wuhen86/comments/commentRss/350470.htmlhttp://www.tkk7.com/wuhen86/services/trackbacks/350470.html我剛剛使用 Emacs 的時候,總是

vi ~/.emacs

然后重新啟動 emacs ,效率很低 ,暗自嘟囔, emacs 怎么沒有這種功能,不重起,就自動更新 .emacs 的設置 呢?

后來我發現,這個功能完全沒有必要,我的做法是:

  • 用 emacs 打開 .emacs 文件,C-x C-e 光標前面的運行一條語句。立即生效。
  • 選擇一個 region , M-x eval-region
  • M-x load-file ~/.emacs
  • M-x eval-buffer

都是立即生效,可以馬上試驗一條語句的效果。 例如,在任何一個文件中,寫

(setq frame-title-format "emacs@%b")

把光標停在在這條語句后面, C-x C-e ,馬上看到 emacs 的 標題欄上發生變化。

我用這種方法調試我的每一個小的配置文件,按上篇文章說的方法, 把他放在 ~/Emacs/myconfig/my-site-start.d 中。

轉自:http://ann77.emacser.com/Emacs/EmacsDotEmacsWithoutRestart.html

Technorati : ,



無很 2011-05-18 13:53 發表評論
]]>
Emacs快捷鍵http://www.tkk7.com/wuhen86/articles/329476.html無很無很Fri, 20 Aug 2010 08:01:00 GMThttp://www.tkk7.com/wuhen86/articles/329476.htmlhttp://www.tkk7.com/wuhen86/comments/329476.htmlhttp://www.tkk7.com/wuhen86/articles/329476.html#Feedback0http://www.tkk7.com/wuhen86/comments/commentRss/329476.htmlhttp://www.tkk7.com/wuhen86/services/trackbacks/329476.html基本命令

C-x C-c : 退出Emacs

C-x C-f : 打開一個文件,如果文件不存在,則創建一個文件

C-g : 取消未完成的命令

編輯

C-z (redefined): Undo;原來C-z是掛起Emacs(然后用fg命令調出);C-x u 是默認的命令; 移動一下光標,再C-z就可以redo

M-d : 刪除光標后的詞語

移動光標

C-v : 向前翻頁

M-v : 向后翻頁

M-r : 將光標移動到屏幕中間那行

C-a : 移到行首

M-a : 移到句首,從行首到句首之間可能有空格

C-e : 移到行尾

M-e : 移到句尾

M-{ : 向上移動一段

M-} : 向下移動一段

C-right : 向前移動一個單詞

C-left : 向后移動一個單詞

C-up : 向前移動一段

C-down : 向后移動一段

M-< : 移到整個文本開頭

M-> : 移到整個文本末尾

C-u 數字 命令 : 執行多次(數字表示次數)該命令;“M-數字 命令” 也可以

M-x goto-line : 移動到某一行

C-l : 重繪屏幕,效果就是當前編輯行移動窗口中央

Buffer 相關

C-x k : 關閉當前buffer

C-x b : 切換到前一個編輯的buffer

C-x C-b : 列出當前所有buffer

C-x C-s : 保存當前buffer

C-x s : 保存所有未保存的buffer,會提示你是否需要保存

C-x C-w : 文件另存為

拷貝與粘貼

M-space (redefined): 設置mark; C-@ 是默認命令

C-w (redefined) : 剪切一塊區域;如果沒有設置mark,則是剪切一行

M-w (redefined) : 拷貝一塊區域;如果沒有設置mark, 則是拷貝一行

C-k : 從當前位置剪切到行尾

C-y : 粘貼

M-y : 用C-y拉回最近被除去的文本后,換成 M-y可以拉回以前被除去的文本。鍵入多次的M-y可以拉回更早以前被除去的文本。

C-x r k : 執行矩形區域的剪切

C-x r y : 執行矩形區域的粘貼

窗口操作

C-x 0 : 關閉當前窗口

C-x 1 : 將當前窗口最大化

C-x 2 : 垂直分割窗口

C-x 3 : 水平分割窗口

M-o (redefined) : 在窗口之間切換; C-x o 是默認命令

C-x 5 1/2/3/0 : 對frame類似的操作

C-x < : 窗口內容右卷

C-x > : 窗口內容左卷(這兩個命令在垂直分割窗口后比較有用)

(C-u) C-x ^ : 加高當前窗口,如果有C-u,則每次加高4行

(C-u) C-x } : 加寬當前窗口

(C-u) C-x { : 壓窄當前窗口

ESC C-v : 在其它窗口進行卷屏操作

搜索和替換

C-s : 向前搜索(增量式搜索);連續C-s,跳到下一個搜索到的目標

C-s RET : 普通搜索

C-r : 向前搜索

C-s RET C-w : 按單詞查詢

M-% : 查詢替換,也就是替換前會詢問一下

M-x replace-string : 普通替換

Tags

M-! etags .c .h : 創建TAGS文件

M-. : 跳到tag所在位置

M-x list-tags : 列出tags

Bookmark

C-x r m : 設置書簽bookmark

C-x r b : 跳到bookmark處

幫助

C-h ? : 查看幫助信息

C-h f : 查看一個函數

C-h v : 查看一個變量

C-h k : 查看一個鍵綁定 (C-h c 也是查看鍵綁定,但是信息較簡略)

C-h C-f : 查看一個函數的Info,非常有用

C-h i : 看Info

其它

C-M-\ : 對選中區域,按照某種格式(比如C程序)進行格式化

C-x h : 全部選中

M-! : 執行外部shell命令

M-x shell : 模擬shell的buffer

M-x term : 模擬terminal, C-c k 關閉terminal

C-x C-q : 修改buffer的只讀屬性

翻頁
C-v 下一頁
M-v 上一頁
選擇
M-h     選擇段落
C-x h   全部選擇
普通區塊
C-SPC   M-x set-mark-command 單個位置set mark
C-@     同上
M-@     對word進行set Mark
M-w     先set Mark,移到光標,M-w就可以復制
C-w     剪切
矩形區塊
用這些快捷鍵要先關閉cua-mode
C-x r t      用串填充矩形區域
C-x r o      插入空白的矩形區域
C-x r y      插入之前刪除的矩形區域, 粘貼時,矩形左上角對齊光標
C-x r k      刪除矩形區域
C-x r c      將當前矩形區域清空
寄存器
----------------------------------------------------------------------
光標位置和窗口狀態
C-x r SPC <寄存器名>                   存貯光標位置
C-x r w <寄存器名>                     保存當前窗口狀態
C-x r f <寄存器名>                     保存所有窗口狀態
C-x r j <寄存器名>                     光標跳轉
文本和數字
C-x r s <寄存器名>                     將連續區塊拷貝到寄存器中
C-x r r <寄存器名>                     將矩形區塊拷貝到寄存器中
C-u <數字> C-x r n <寄存器名>           將數字拷貝到寄存器中
C-x r i <寄存器名>                     在緩沖區中插入寄存器內容
M-x view-register                     查看寄存器內容
M-x list-registers                    查看寄存器列表
宏模式
C-x (                    開始一個宏的定義
C-x )                    結束一個宏的定義
C-x e                    執行宏
M-x name-last-kbd-macro  給最后一個宏命名
M-x insert-kbd-macro     在當前文件中插入一個已定義并命名過的宏
書簽
C-x r m <name>           設置書簽
C-x r b <name>           跳轉到書簽
C-x r l                  書簽列表
M-x bookmark-delete      刪除書簽
M-x bookmark-load        讀取存儲書簽文件
M-x bookmark-save        保存到文件
目錄模式
----------------------------------------------------------------------
C-x d     M-x dired     啟動目錄模式
C-x C-d   簡單目錄

 

程序
C-x C-z 掛起程序
C-c C-x 退出程序
C-c k   關閉buffer
C-l     重畫屏幕
C-g     結束命令,或者假死中恢復,也可以按3次ESC
文件
C-x C-s 保存
C-x C-w 另存為
C-x C-f 打開文件
C-x C-r 只讀方式打開
C-x C-v 讀入另外一個文件代替當前buffer的文件
C-x s   保存所有
C-x i   將文件的內容插入
M-x revert-buffer    恢復到原始狀態
跳轉
前/后     單位
C-f/b    字
M-f/b    詞
C-a/e    行內
M-a/e    句
M-</>    文檔
C-p/n    行間
M-{/}    段落
C-x ]/[  頁
C-x C-x  文件內,mark之間
M-g g  跳到指定行
M-x goto-char 跳到指定字符
編輯
M-u       后面單詞變為大寫
M-l       后面單詞變為小寫
M-c       后面單詞的首字母變大寫
M-/       補全
C-j       從當前位置分成兩行,相當于RET + tab
M-(       插入()
C-q tab   插入tab
C-q C-m   插入^M
M-;       插入注釋
C-o       回車
刪除
M-d   后一詞
C-d   后一字
M-del 前一詞
M-k   到句尾
M-"   前面的所有空白
M-z   刪到指定字母處
C-k   刪除到行尾
文本換位
C-t        字符
M-t        單詞
C-x C-t    行
M-x transpose-* 其他命令
撤銷
C-/
C-x u
C-_
C-z
重做
C-g M-x undo
C-g C-/
C-g C-z
C-g C-_
粘貼
C-y
C-v
tab/空格轉換
M-x tabify
M-x untabify
讓選擇的區塊自動對齊
M-x indent-region
其他命令
C-u <數字> <命令> 重復命令n次
M-<數字>   <命令> 同上
M-!     運行shell命令
C-u M-! 執行一條外部命令,并輸出到光標位置
M-x cd  改變工作目錄
M-x pwd 當前工作目錄
C-" 啟動輸入法
M-` 菜單
F10 菜單
M-x eval-buffer 在.emacs的buffer中運行,重新加載emacs配置
查找替換
----------------------------------------------------------------------
C-r 向上查找
C-s 向下查找
C-s C-w 向下查找,光標位置的單詞作為查找字符串
C-s C-y 向下查找,光標位置到行尾作為查找字符串
C-s RET <查找字符串> RET   非遞增查找
C-s RET C-w              不受換行、空格、標點影響
C-M-s                    正則式向下查找
用向上查找命令就將上面命令的s替換為r
M-%   替換
C-M-% 正則式替換
y 替換當前的字符串并移動到下一個字符串
n 不替換當前字符串,直接移動到下一個字符串
! 進行全局替換,并要求不再顯示
. 替換當前字符串,然后退出查找替換操作
q 退出查找替換操作,光標定位到操作開始時的位置
其他命令
M-x replace-*
M-x search-*
窗口
C-x 0 關掉當前窗口
C-x 1 關掉其他窗口
C-x o 切換窗口
C-x 2 水平兩分窗口
C-x 3 垂直兩分窗口
C-x 5 2 新frame
buffer
C-x C-b        查看
C-x b          切換
C-x C-q        設為只讀
C-x k          刪除
C-x left/right 切換



無很 2010-08-20 16:01 發表評論
]]>
JSF2.0初探http://www.tkk7.com/wuhen86/articles/325634.html無很無很Fri, 09 Jul 2010 04:51:00 GMThttp://www.tkk7.com/wuhen86/articles/325634.htmlhttp://www.tkk7.com/wuhen86/comments/325634.htmlhttp://www.tkk7.com/wuhen86/articles/325634.html#Feedback2http://www.tkk7.com/wuhen86/comments/commentRss/325634.htmlhttp://www.tkk7.com/wuhen86/services/trackbacks/325634.html一直想研究Java JSF,上網找了下,遺憾的是國內JSF的資料少的可憐.于是上網找了參考點資料,去官方網站下載了JSF的開發包.廢話少說,看配置.

一,配置JSF

把JSF2.0內的兩個開發包jsf-api.jar,jsf-impl.jar拷貝到Eclipse項目的lib目錄中(建立web項目略). 在web.xml中添加以下內容:

<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>

<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>

<context-param>
<param-name>com.sun.faces.resourceUpdateCheckPeriod</param-name>
<param-value>-1</param-value>
</context-param>

<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.do</url-pattern> <!--此處名字可以隨便起,可以是*.action,*.faces 等 我習慣用*.do-->
</servlet-mapping>

這樣jsf框架已經添加進項目中了.接下來就要建立Bean了.如下所示:

package com.joy.jsf.beans;

//@ManagedBean(name="users") jsf2.0可以不用配置文件來管理bean
public class User {

private String userName;
private String userPassword;
private String errorMessage;

public String getErrorMessage() {
return errorMessage;
}

public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getUserPassword() {
return userPassword;
}

public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}

public String Check() {
if (!this.userName.equals("JOY") || !this.userPassword.equals("123456")) {
this.errorMessage = "名稱或密碼錯誤";
return "failure";
} else {
return "success";
}
}
}

之后要定制導航規則,新建face-config.xml 如下所示:

<faces-config>
<!-- <application>
<variable-resolver>
org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver>
</application> -->
<navigation-rule>
<from-view-id>/index.jsp</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/pages/welcome.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>failure</from-outcome>
<to-view-id>/index.jsp</to-view-id>
</navigation-case>
</navigation-rule>

<!--<managed-bean> <managed-bean-name>users</managed-bean-name> <managed-bean-class>
com.joy.jsf.beans.User </managed-bean-class> <managed-bean-scope>request</managed-bean-scope>
</managed-bean> -->
</faces-config>

配置文件建立完了,添加view頁面. index.jsp和welcome.jsp

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="f" uri=">
<%@ taglib prefix="h" uri="
>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>首頁</title>
</head>
<body>
<f:view>
<h:form>
姓名:<h:inputText value="#{users.userName }" /><br/>
密碼:<h:inputText value="#{users.userPassword }"></h:inputText><br/>
<h:commandButton value="submit" action="#{users.Check}"></h:commandButton>
<br/>
<h:outputText value="#{users.errorMessage}"/><p>

</h:form>
</f:view>
</body>
</html>

welcome.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="f" uri="
>
<%@ taglib prefix="h" uri="
>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>歡迎回來</title>
</head>
<body>
<f:view>
<h:form>
Hello <h:outputText value="#{users.userName }"></h:outputText> ,Welcome to here!

</h:form>
</f:view>
</body>
</html>

保存,部署,運行http://localhost:8080/JSF/index.do

二,整合Spring

添加spring開發包,spring.jar,stadard.jar,commons-logging.jar,jstl.jar

web.xml 添加如下配置

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
<description>添加Srping支持</description>
<display-name>Spring</display-name>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

然后在face-config.xml中添加

<application>
<variable-resolver>
org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver>
</application>

從spring工廠中獲取bean ,如果和jsf的托管bean一起使用,則托管bean的優先級要高于spring.

添加applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=" xmlns:xsi="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx

<bean id="users" class="com.joy.jsf.beans.User">

</bean>
</beans>

重新部署,運行.

OK.



無很 2010-07-09 12:51 發表評論
]]>
主站蜘蛛池模板: 91福利视频免费| 99视频在线看观免费| 免费理论片51人人看电影| 亚洲理论片中文字幕电影| 99在线观看视频免费| 亚洲激情电影在线| 亚洲另类激情专区小说图片| 免费播放美女一级毛片| 亚洲国产精品一区二区第四页| 亚洲欧洲免费无码| 成年丰满熟妇午夜免费视频| 中国china体内裑精亚洲日本| 免费毛片在线播放| 全部一级一级毛片免费看| 中文字幕亚洲不卡在线亚瑟| 国产偷伦视频免费观看| 亚洲欧洲日产专区| 夜夜爽免费888视频| 未满十八私人高清免费影院| 国产亚洲成av人片在线观看| 91精品免费久久久久久久久| 亚洲色成人WWW永久在线观看| 国产午夜无码视频免费网站| 成人网站免费大全日韩国产| 亚洲色图在线观看| 日本免费福利视频| 伊人久久国产免费观看视频| 亚洲av无码国产精品色午夜字幕| av无码国产在线看免费网站| 最新亚洲人成网站在线观看 | 国产精品免费观看久久| 国产成人亚洲综合在线| 中文字幕专区在线亚洲| 亚洲一区二区三区免费在线观看 | 国产亚洲精久久久久久无码| 日韩av无码成人无码免费| 男女交性无遮挡免费视频| 少妇中文字幕乱码亚洲影视| 毛片免费全部播放一级| 叮咚影视在线观看免费完整版| 四虎必出精品亚洲高清|