1 前言
大家知道,在登录microsoft windows操作系统过程中,在登录窗口中需要用户输入注册用户名称和密码。细心的读者会发现:用户输入的注册用户名称内容为原码字符显示,而注册密码内容为掩码字符显示。例如,同样在两各文本区中输入字符"a",在用户名文本区中显示的是字符"a",而在密码区中显示的字符为掩码"*",这就是所谓的密码屏蔽输入。将输入的密码屏蔽回显,不仅增强了用户私有信息的安全性,更重要的是维护了计算机系统的稳定性和安全性。
java以其语言的面向对象能力、高安全性和java平台的系统无关性等技术优势,在商务软件开发过程中赢得了众多程序设计人员的青睐。jdk在awt和jfc类库中定义了用于密码字符屏蔽的应用程序设计接口(api),使应用系统开发人员在编写图形用户界面程序时,能够灵活地定义密码回显方式。但是,对于基于命令行方式的java应用程序,jdk没有定义相应的密码屏蔽策略,程序设计人员必须编写字符回显控制代码。本文将通过对实例代码的分析,对基于jdk平台开发java应用程序的密码屏蔽输入方法进行探讨,主要内容包括:
●awt组件对象密码屏蔽方法
●jswing组件对象密码屏蔽方法
●java命令行程序密码屏蔽方法
2 利用awt组件实现密码屏蔽输入
java抽象窗口工具包(abstract window toolkit,awt)是在jdk1.0版本中定义的用于编写java图形用户界面程序的应用程序设计接口,程序设计人员可以利用该包中定义的多种类型组件对象,编写具有用户界面的应用程序。
为了实现用户输入信息的屏蔽,可以利用awt组件库中定义的textfield对象,该对象的定义继承结构如下:
java.lang.object
|
+--java.awt.component
|
+--java.awt.textcomponent
|
+--java.awt.textfield
在该对象中,定义了用于设置和维护用户输入字符回显方式的方法,这些方法的定义形式为:
char getechochar():获取用户定义的文本区回显字符;
boolean echocharisset()判断是否定义了回显字符;
void setechochar(char c):设置文本区回显字符为字符c。
因此,在读者编写的java程序中,可以在创建textfield对象实例后,例如上述方法控制文本区回显字符的方式。下面的程序完整地演示了回显字符的定义方式:
//passwordmaskingdemo.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.joptionpane;
public class passwordmaskingdemo
{
public static void main(string args[])
{
final frame frmframe = new frame();
panel pnlpanel = new panel();
label lblusername = new label("用户名");
label lblpassword = new label("密码");
final textfield txtusername = new textfield("anyomonus");
final textfield txtpassword = new textfield("", 8);
txtusername.seteditable(false);
txtpassword.setechochar(′*′);
button btnbutton1 = new button("登录");
button btnbutton2 = new button("其它用户登录");
button btnbutton3 = new button("关闭");
btnbutton1.addactionlistener( new actionlistener()
{
public void actionperformed(actionevent e)
{
if( (txtpassword.gettext()).length() == 0 )
{
joptionpane.showmessagedialog
(frmframe, "密码不能为空");
return;
}
txtpassword.setcolumns(16);
system.out.println("anyomonus用户的密码:" +
txtpassword.gettext() );
}
});
btnbutton2.addactionlistener( new actionlistener()
{
public void actionperformed(actionevent e)
{
txtusername.seteditable(true);
}
});
btnbutton3.addactionlistener( new actionlistener()
{
public void actionperformed(actionevent e)
{
system.exit(0);
}
});
pnlpanel.add(lblusername);
pnlpanel.add(txtusername);
pnlpanel.add(lblpassword);
pnlpanel.add(txtpassword);
pnlpanel.add(btnbutton1);
pnlpanel.add(btnbutton2);
pnlpanel.add(btnbutton3);
frmframe.add(pnlpanel);
frmframe.settitle("演示textfield对象的应用方法");
frmframe.pack();
frmframe.show();
}
}
在上述程序中,与文本区回显控制相关的代码为:
final textfield txtpassword = new textfield("", 8);
txtpassword.setechochar(′*′);
在上面的代码中,首先创建初始内容为空、可输入8个字符的textfield对象实例txtpassword后,利用textfield对象中定义的setechochar方法设置该文本区的回显字符为星号"*",从而实现输入字符的掩码。因此总结为:可以利用textfield对象中定义的setechochar方法,实现awt组件对象程序中的字符掩码输入和回显控制。
3 利用jswing组件对象实现密码屏蔽输入
jswing组件对象是轻量级java组件对象,其中定义了多种组件对象类型,而且其外观也更加新颖。与awt组件对象相对应,在jswing组件对象中也定义了jtextfield对象,用于用户进行文本输入。那么,读者是否会联想利用对象中也定义的setechochar方法定义回显字符呢?实际情况不是这样。在jtextfield对象中没有定义该方法,而是以jtextfield为父对象,定义了用于进行密码输入的文本区对象jpasswordfield,该对象的定义继承结构如下:
java.lang.object
|
+--java.awt.component
|
+--java.awt.container
|
+--javax.swing.jcomponent
|
+--javax.swing.text.jtextcomponent
|
+--javax.swing.jtextfield
|
+--javax.swing.jpasswordfield
在jpasswordfield对象中,定义了多种类型用于控制字符回显方式的方法,其中setechochar方法即用于定义文本区回显字符,如下面代码段所示:
… …
jpasswordfield password = new jpasswordfield(8);
password.setechochar(′*′);
… …
与awt组件对象定义文本区的回显方式类似,上述代码创建了jpasswordfield对象实例后,设置该对象的回显字符为星号"*"。但是,读者需要注意的是:在jswing对象中,需要利用jpasswordfield对象来管理用户输入文本。
4 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 == ′ ′)
{
input = (char)system.in.read();
if (input == ′ ′)
break;
else
continue;
}
else if(input == ′ ′)
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(" " + initial + " " + 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);
}
}
5 结束语
本文着重讲解了基于java语言编写图形用户界面程序和命令行程序中,实现用户输入字符屏蔽的方法。从文中内容可以看出:对于图形用户界面程序,无论利用awt组件对象,还是利用jswing组件对象,均可以利用相应的组件对象并调用对象实例中定义的方法,实现用户输入字符的屏蔽,从而简化了代码编写难度。
对于基于命令行的java程序,由于jdk中没有定义相应的java对象,因此,需要编写屏蔽用户输入的代码,将用户输入不显示在终端窗口中,从而实现用户输入屏蔽。
本文选自:赛迪网
闽公网安备 35060202000074号