最近看到一个问题,如何用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