我点击this eclipse bug,其中System.console()
无法用于Java应用程序启动。我有一个小型Java应用程序,它还需要输入一个只能在IDE中启动的密码。有没有其他方法安全从控制台读取密码(意味着不在控制台上显示)只使用JDK类?
修改
我知道System.in
,但这是在控制台中显示输入的字符,因此不安全。
EDIT2:
我还想注意,可以在windows下创建一个批处理文件,或者在项目中的linux / unix下创建一个小的bash脚本。通过使用系统默认编辑器在eclipse中打开此文件,它将在System.console()
可用的新控制台窗口中启动。这样你就可以在eclipse中启动应用程序。但是必须首先构建项目,以便存在二进制文件。
答案 0 :(得分:3)
也许不使用控制台尝试使用JPasswordField
对话框。以下是http://blogger.ziesemer.com/2007/03/java-password-dialog.html的示例。
final JPasswordField jpf = new JPasswordField();
JOptionPane jop = new JOptionPane(jpf, JOptionPane.QUESTION_MESSAGE,
JOptionPane.OK_CANCEL_OPTION);
JDialog dialog = jop.createDialog("Password:");
dialog.addComponentListener(new ComponentAdapter() {
@Override
public void componentShown(ComponentEvent e) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
jpf.requestFocusInWindow();
}
});
}
});
dialog.setVisible(true);
int result = (Integer) jop.getValue();
dialog.dispose();
char[] password = null;
if (result == JOptionPane.OK_OPTION) {
password = jpf.getPassword();
}
if (password != null)
System.out.println("your password: " + new String(password));
答案 1 :(得分:3)
如果System.console()
返回null
,则表示就Java而言,没有可用的控制台。
您无法使用System.in
,因为它可能无法连接到控制台。
即使你可以,也没有可移植的方式来关闭Java中的回显。
您可以使用Swing(或其他)弹出一个窗口来询问密码,但是如果系统无头无法工作。
如果您准备做不便携的事情,那么(在Linux / UNIX上)您可以尝试打开" / dev / console"或" / dev / tty"。然后你可以使用termios将tty驱动程序置于noecho模式。但是你需要在本机代码中至少完成其中的一部分。
答案 2 :(得分:3)
我遇到了同样的问题。 (亲爱的Eclipse社区:修复那个bug真的很难吗?) 和其他人一样,我需要IDE用于开发/调试和独立运行。
所以我写了这个方法:
private static String readPwd() throws IOException {
Console c=System.console();
if (c==null) { //IN ECLIPSE IDE
System.out.print("Password: ");
InputStream in=System.in;
int max=50;
byte[] b=new byte[max];
int l= in.read(b);
l--;//last character is \n
if (l>0) {
byte[] e=new byte[l];
System.arraycopy(b,0, e, 0, l);
return new String(e);
} else {
return null;
}
} else { //Outside Eclipse IDE
return new String(c.readPassword("Password: "));
}
}
此解决方法的缺点是,在Eclipse中,您将在程序运行时看到密码。
答案 3 :(得分:1)
类似于@Pshemo给出的答案,人们可以回到Swing:
final String passwd;
final String message = "Enter password";
if( System.console() == null ) {
final JPasswordField pf = new JPasswordField();
passwd = JOptionPane.showConfirmDialog( null, pf, message,
JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE ) == JOptionPane.OK_OPTION
? new String( pf.getPassword() ) : "";
} else
passwd = new String( System.console().readPassword( "%s> ", message ) );