最近看到一個問題,如何用Java實現從控制台輸入密碼?
本來以為是很簡單的問題,查了一下發現Java居然沒提供這樣一個方法。目前實現的方式有2個,一個是利用JNI來調用C/C++方法,另一個是使用多線程。
下面是使用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後綴,系統會自動辨認。
編譯成JNIPasswordReader.class以後,使用
javah -jni JNIPasswordReader
命令,生成一個JNIPasswordReader.h文件,文件內容如下:
#ifdef __cplusplus
}
#endif
#endif
然後,我們需要寫一個cpp文件來實現
JNIEXPORT jstring JNICALL Java_JNIPasswordReader_readPassword (JNIEnv *, jobject);
接口。
於是,我寫了一個PasswordDLL.cpp文件,內容如下:
/**/ /*
* 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來生成dll了,生成好對應的PasswordDLL.dll以後,把該dll文件放到系統變量PATH能找到的地方,比如windows/system32/或者jdk/bin目錄,我是放到JDK_HOME/bin下面了
放好以後,
執行java JNIPasswordReader
就可以輸入密碼了。
關於JNI的更詳細內容,可以參考:
《在Windows中實現Java本地方法》http://www.ibm.com/developerworks/cn/java/jnimthds/index.html
我的Password.dll文件
http://www.blogjava.net/Files/richardeee/PasswordDLL.zip