最近看到一个问题,如何用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文件,文件内容如下:

/**/ /* 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
然后,我们需要写一个cpp文件来实现
JNIEXPORT jstring JNICALL Java_JNIPasswordReader_readPassword (JNIEnv *, jobject);
接口。
于是,我写了一个PasswordDLL.cpp文件,内容如下:

// 这是主 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来生成对应的dll文件,在生成之前,需要把$JDK_HOME/include/jni.h和$JDK_HOME/include/win32/jni_md.h这两个文件copy到Microsoft Visio Studio 8/VC/include目录下,我就在这里卡了大概1个小时,一直说找不到jni.h文件
然后就可以使用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