Java命令行程序密码屏蔽输入实现方式
与基于AWT或者JSwing的图形用户界面程序相比,在基于命令行的Java程序中实现密码屏蔽输入要比较麻烦一些,原因在于JDK没有提供任何基于文本的字符回显控制方法,因此需要编写相应的控制代码。基于通用性方面的考虑,在本文中将编写用于屏蔽用户输入的对象InputMasking,该对象的定义如下:
//InputMasking.java
import java.io.*;
public class InputMasking
{
String getPassword(String initial) throws IOException
{
MaskingThread listeningthread = new MaskingThread(initial);
Thread thread_instance = new Thread(listeningthread);
String password = "";
thread_instance.start();
while (true)
{
char input = (char)System.in.read();
listeningthread.stopMasking();
if (input == '\r')
{
input = (char)System.in.read();
if (input == '\n')
break;
else
continue;
}
else if(input == '\n')
break;
else
password += input;
}
return password;
}
}
该对象在后台启动线程的控制下,从系统输入设备中读取字符并对该字符进行分析。如果遇到行结束标志,则返回该线程获取的字符串对象password。读者一定会关心后台线程对象MaskingThread的作用,该线程对象周期地刷新终端窗口,其目的在于屏蔽用户输入的字符,使该字符不能够在窗口中显示出来。该线程对象的定义为:
//MaskingThread.java
import java.io.*;
class MaskingThread extends Thread
{
private boolean stop = false;
private int index;
private String initial;
public MaskingThread(String initial)
{
this.initial = initial;
}
public void run()
{
while(!stop)
{
try
{
this.sleep(1);
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
if (!stop)
{
System.out.print("\r" + initial + " \r" + initial);
}
System.out.flush();
}
}
public void stopMasking()
{
this.stop = true;
}
}
在InputMasking对象和MaskingThread对象的配合下,使得基于命令行的Java应用程序能够实现用户输入密码字符的屏蔽,其核心方法是利用后台线程时时刷新终端窗口,屏蔽用户输入字符。下面的CmdLineUtility对象即利用前面定义的两个对象进行用户输入屏蔽,请读者实际运行上述程序,以了解命令行Java程序屏蔽输入的方式:
//CmdLineUtility.java
import java.io.*;
public class CmdLineUtility
{
public static void main(String argv[])
{
InputMasking masking = new InputMasking();
String password = null;
try
{
password = masking.getPassword("请输入登录密码: ");
}
catch(IOException ex)
{
ex.printStackTrace();
}
System.out.println("您输入的密码为: " + password);
}
}