posts - 32, comments - 153, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          最近看到一個(gè)問題,如何用Java實(shí)現(xiàn)從控制臺(tái)輸入密碼?
          本來以為是很簡單的問題,查了一下發(fā)現(xiàn)Java居然沒提供這樣一個(gè)方法。目前實(shí)現(xiàn)的方式有2個(gè),一個(gè)是利用JNI來調(diào)用C/C++方法,另一個(gè)是使用多線程。
          下面是使用JNI的方法:
          首先,寫出我們的Java類:


          public ? class ?JNIPasswordReader? {

          ????
          private ? native ?String?readPassword();
          ????
          static {
          ????????System.loadLibrary(
          " PasswordDLL " );
          ????}

          ????
          /**
          ?????*?
          @param ?args
          ?????
          */

          ????
          public ? static ? void ?main(String[]?args)? {
          ????????
          // ?TODO?Auto-generated?method?stub
          ????????JNIPasswordReader?reader? = ? new ?JNIPasswordReader();
          ????????String?pwd?
          = ?reader.readPassword();
          ????????System.out.println(
          " \nYour?Password?is: " ? + ?pwd);
          ????}


          }

          這一段使用System.loadLiberary("..");來加載本地類庫,PasswordDLL是文件名,不需要加dll后綴,系統(tǒng)會(huì)自動(dòng)辨認(rèn)。

          編譯成JNIPasswordReader.class以后,使用
          javah -jni JNIPasswordReader
          命令,生成一個(gè)JNIPasswordReader.h文件,文件內(nèi)容如下:

          /* ?DO?NOT?EDIT?THIS?FILE?-?it?is?machine?generated? */
          #include?
          < jni.h >
          /* ?Header?for?class?JNIPasswordReader? */

          #ifndef?_Included_JNIPasswordReader
          #define ?_Included_JNIPasswordReader
          #ifdef?__cplusplus
          extern ? " C " ? {
          #endif
          /*
          ?*?Class:?????JNIPasswordReader
          ?*?Method:????readPassword
          ?*?Signature:?()Ljava/lang/String;
          ?
          */

          JNIEXPORT?jstring?JNICALL?Java_JNIPasswordReader_readPassword
          ??(JNIEnv?
          * ,?jobject);

          #ifdef?__cplusplus
          }

          #endif
          #endif

          然后,我們需要寫一個(gè)cpp文件來實(shí)現(xiàn)
          JNIEXPORT?jstring?JNICALL?Java_JNIPasswordReader_readPassword??(JNIEnv?*,?jobject);
          接口。
          于是,我寫了一個(gè)PasswordDLL.cpp文件,內(nèi)容如下:

          // ?這是主?DLL?文件。
          #include? " stdafx.h "
          #include?
          " JNIPasswordReader.h "
          #include?
          < iostream >
          #include?
          < iomanip >
          #include?
          < conio.h >
          using ? namespace ?std;

          /*
          ?*?Class:?????JNIPasswordReader
          ?*?Method:????readPassword
          ?*?Signature:?()V
          ?
          */

          JNIEXPORT?jstring?JNICALL?Java_JNIPasswordReader_readPassword
          ??(JNIEnv?
          * ?env,?jobject) {
          ??????
          char ?str[ 20 ]? = ? { 0 } ;?
          ????jstring?jstr;
          ????
          char ?ch;
          ????
          char ? * pstr? = ?str;
          ????
          while ( true )
          ????
          {
          ????????ch?
          = ?getch();
          ????????
          if (isdigit(ch) || isalpha(ch))
          ????????
          {
          ????????????cout
          << " * " ;
          ????????????
          * pstr ++ ? = ?ch;
          ????????}

          ????????
          else ? if (ch? == ? ' \b ' ? && ?pstr? > ?str)
          ????????
          {
          ????????????
          * ( -- pstr)? = ? 0 ;
          ????????????cout
          << " \b?\b " ;
          ????????}

          ????????
          else ? if (ch? == ? 0x0A ? || ?ch? == ? 0x0D )
          ????????
          {
          ????????????
          break ;
          ????????}

          ????}

          ????jstr?
          = ?env -> NewStringUTF(str);
          ????
          return ?jstr;
          }

          我使用VS2005來生成對應(yīng)的dll文件,在生成之前,需要把$JDK_HOME/include/jni.h和$JDK_HOME/include/win32/jni_md.h這兩個(gè)文件copy到Microsoft Visio Studio 8/VC/include目錄下,我就在這里卡了大概1個(gè)小時(shí),一直說找不到j(luò)ni.h文件

          然后就可以使用VS2005來生成dll了,生成好對應(yīng)的PasswordDLL.dll以后,把該dll文件放到系統(tǒng)變量PATH能找到的地方,比如windows/system32/或者jdk/bin目錄,我是放到JDK_HOME/bin下面了
          放好以后,
          執(zhí)行java JNIPasswordReader
          就可以輸入密碼了。

          關(guān)于JNI的更詳細(xì)內(nèi)容,可以參考:
          《在Windows中實(shí)現(xiàn)Java本地方法》http://www.ibm.com/developerworks/cn/java/jnimthds/index.html

          我的Password.dll文件
          http://www.aygfsteel.com/Files/richardeee/PasswordDLL.zip


          評論

          # re: 利用JNI調(diào)用C/C++方法實(shí)現(xiàn)Java中從控制臺(tái)輸入密碼  回復(fù)  更多評論   

          2007-02-24 22:55 by 喜來樂哈哈
          JDK6.0有一個(gè)新類Console,可以解決這個(gè)問題

          Console console = System.console();
          if (console != null) {
          String user = new String(console.readLine("Enter username:"));
          String pwd = new String(console.readPassword("Enter passowrd:"));
          console.printf("User is :" + user + "\n");
          console.printf("Password is: " + pwd + "\n");
          } else {
          System.out.println("Console is unavailable");
          }

          但是在某些情況下System.console()返回一個(gè)null。比如輸入被重定向。具體的看JDK6的API Doc
          http://java.sun.com/javase/6/docs/api/java/io/Console.html

          # re: 利用JNI調(diào)用C/C++方法實(shí)現(xiàn)從控制臺(tái)輸入密碼  回復(fù)  更多評論   

          2007-02-24 23:03 by 喜來樂哈哈
          不好意思,剛在你裝載的文章里看到我寫的方法。我想你應(yīng)該是知道這種方法的。

          是不是這種方法有不符合你的要求的地方?

          # re: 利用JNI調(diào)用C/C++方法實(shí)現(xiàn)從控制臺(tái)輸入密碼  回復(fù)  更多評論   

          2007-02-25 08:09 by Zou Ang
          @喜來樂哈哈
          呵呵,你的意思是我用JNI么?首先我的JDK版本是5.0的,其次我在寫這個(gè)之前還真沒見到您的那篇JNI文章……其實(shí)解決密碼輸入的最好方法我覺得還是利用JDK6.0的特性,畢竟把Java跟本地代碼綁在一塊還是不太好

          # re: 利用JNI調(diào)用C/C++方法實(shí)現(xiàn)從控制臺(tái)輸入密碼  回復(fù)  更多評論   

          2007-02-25 10:30 by 喜來樂哈哈
          @Zou Ang
          同意你的觀點(diǎn), 本地代碼是最后一個(gè)選擇,實(shí)在沒法才用.

          # re: 利用JNI調(diào)用C/C++方法實(shí)現(xiàn)從控制臺(tái)輸入密碼[未登錄]  回復(fù)  更多評論   

          2007-03-14 10:48 by java愛好者
          Sun的網(wǎng)站以前有篇文章是講jdk6之前如何處理密碼輸入,該文建議的解決方案是用多線程來處理,一個(gè)線程專門刷新屏幕輸入,防止密碼被顯示。

          # re: 利用JNI調(diào)用C/C++方法實(shí)現(xiàn)從控制臺(tái)輸入密碼  回復(fù)  更多評論   

          2007-03-14 10:55 by Zou Ang
          @java愛好者
          這種方法好像在比較慢的機(jī)器上會(huì)閃爍
          主站蜘蛛池模板: 石台县| 上栗县| 武清区| 巴彦县| 三原县| 温州市| 梅州市| 垫江县| 环江| 呈贡县| 芷江| 边坝县| 三江| 泸定县| 都江堰市| 南阳市| 建德市| 蒲城县| 万安县| 阿克| 衡阳市| 正蓝旗| 泽普县| 南漳县| 新和县| 白山市| 荆州市| 平塘县| 呼伦贝尔市| 榆社县| 响水县| 庆云县| 东兰县| 中江县| 砚山县| 万州区| 英德市| 宁乡县| 五大连池市| 青阳县| 汉沽区|