也不啰嗦了,进主题吧: 我写了一个GUI的程序,我要说的是登录的问题;
这个程序原来用的是MySQL作后台数据库的,登录用到的是一张users表,里面有这样的两行记录:
name password state
admin 123 unlock
root abc unlock
所有字段都是varchar类型的,name为主键;
登录的时候,数据库连接正常,账号以admin密码以123登录的时候也可以轻松登录;
问题就是:当我以admin为账号,密码以123 登录时(注意:123后面多加了一个空格),居然同样可以登录,理论上是应该不可以的;
然后我试着以root为账号,以abc为密码登录,好,登录正常,当我再以root为账号,以abc 为密码(注意:abc后面多加了一个空格)登录时,
居然同样可以登录!当然,其他的任何情况都是不能登录的,已经测试过N遍了。
之后,我以为是数据类型的问题,就把users表的所有数据都删除了,重新设计了这张表,全都换成了char类型,可是:登录时还是一样的情况!
就是说,连账号后面加了空格(如admin )都可以正常登录,只要密码123不错,后面加多少个空格都可以。
我检查过了,账号和密码在随SQL语句被发送到数据库的前后,都是一样的,都是从文本区获得的字符串,一直都没有变过,就是送到数据库中处理的时候出问题了;
感觉就是查询系统自己把后面的空格去掉了一样!
然后,我干脆换了数据库,改用MS-SQL2000,一样的事情:不管是什么数据类型,char也好,varchar也好,还是nvarchar也好,和上面的情况一模一样!
奇怪的是:我再换Oracle10g数据库的时候,一样的登录方式,Oracle就完全符合理论了!就是:不管账号还是密码,该是什么就是什么,多一个空格就不能登录,要和数据库中的数据完全一样才行! 难道MySQL跟MS-SQL注定就不能做到一次准确无误的验证?只有Oracle才行?各位说说问题的所在,先谢过了
这个程序原来用的是MySQL作后台数据库的,登录用到的是一张users表,里面有这样的两行记录:
name password state
admin 123 unlock
root abc unlock
所有字段都是varchar类型的,name为主键;
登录的时候,数据库连接正常,账号以admin密码以123登录的时候也可以轻松登录;
问题就是:当我以admin为账号,密码以123 登录时(注意:123后面多加了一个空格),居然同样可以登录,理论上是应该不可以的;
然后我试着以root为账号,以abc为密码登录,好,登录正常,当我再以root为账号,以abc 为密码(注意:abc后面多加了一个空格)登录时,
居然同样可以登录!当然,其他的任何情况都是不能登录的,已经测试过N遍了。
之后,我以为是数据类型的问题,就把users表的所有数据都删除了,重新设计了这张表,全都换成了char类型,可是:登录时还是一样的情况!
就是说,连账号后面加了空格(如admin )都可以正常登录,只要密码123不错,后面加多少个空格都可以。
我检查过了,账号和密码在随SQL语句被发送到数据库的前后,都是一样的,都是从文本区获得的字符串,一直都没有变过,就是送到数据库中处理的时候出问题了;
感觉就是查询系统自己把后面的空格去掉了一样!
然后,我干脆换了数据库,改用MS-SQL2000,一样的事情:不管是什么数据类型,char也好,varchar也好,还是nvarchar也好,和上面的情况一模一样!
奇怪的是:我再换Oracle10g数据库的时候,一样的登录方式,Oracle就完全符合理论了!就是:不管账号还是密码,该是什么就是什么,多一个空格就不能登录,要和数据库中的数据完全一样才行! 难道MySQL跟MS-SQL注定就不能做到一次准确无误的验证?只有Oracle才行?各位说说问题的所在,先谢过了
if ("123".equals(txtpassword.value.trim())){
//登录的语句
}
你可以这样试一下,trim()表示去掉字符串两边的空格。估计这样写了以后,应该不会再出现你所说的加空格也能登录那种情况了。
if ("123".equals(txtpassword.value.trim())){
//登录的语句
}
查询语句都是一样的嘛?
如果你要限制,你只能在你登录时限制下!String.trim()应该可以!
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Test1 { public static void main(String[] args) throws Exception {
Statement stmt = null;
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql","root","123456");
stmt = conn.createStatement();
//经测试'zeng','zeng ','zeng '查询结果一样
//' zeng','zen g'查不出
String sql = "select Id,name from test where name = 'zeng '";
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()) {
System.out.println(rs.getRow()+"----"+rs.getInt(1) +"----"+rs.getString(2));
}
} catch(ClassNotFoundException e) {
e.printStackTrace();
} catch(SQLException e) {
e.printStackTrace();
} finally {
try {
if(stmt != null) {
stmt.close();
stmt = null;
}
if(conn != null) {
conn.close();
conn = null;
}
} catch(SQLException e) {
e.printStackTrace();
}
}
}}
.....//处理事件
if(e.getSource() == sureBt){
String name = textName.getText(); //得到的都是""空字符串,而不是null
String passwd = new String(textPassword.getPassword());
boolean pass=this.isPass(name,passwd);
if(pass)
JOptionPane.showMessageDialog(null,"恭喜你,登录成功!","登录成功",JOptionPane.INFORMATION_MESSAGE);
else{
JOptionPane.showMessageDialog(null,"对不起,帐号或密码错误,请重新输入","信息错误",JOptionPane.WARNING_MESSAGE);
textPassword.setText("");
textName.requestFocusInWindow();
}
}
.....//isPass方法,判断是否存在合法的账号及密码
public boolean isPass(String name,String passwd){
Connection conn = null;
Statement stmt=null;
String sql=null;
ResultSet rs=null;
boolean pass=false;
try{ //取得一个与MySQL的连接
//public static Connection getMySQLConn(String dbName,String user,String userPassword)是我在外部定义的一个静态方法
conn=DBConnection.getMySQLConn("book","root","123");
stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
sql="SELECT * FROM user WHERE name='"+name+"' AND password='"+passwd+"'";
rs = stmt.executeQuery(sql);
if(rs.next()) pass=true;
}catch (Exception e1) {
e1.printStackTrace();
}finally {
try {
if (stmt != null) stmt.close(); //关闭查询对象
if (rs != null) rs.close(); //关闭保存结果集的对象
if (conn != null) conn.close(); //关闭与数据源的连接
} catch (Exception e2) {
e2.printStackTrace();
}
}
return pass;
}.....绝对不是我的语句的问题,因为是同样的语句发生在3种不同的数据库上,结果不一样而已,尤其是Oracle
我的3种数据库形式的登录用的都是同一条语句,MySQL和MS-SQL就自动把空格给去掉了(JTextField和JPasswordField是不会去空格的,可以验证),
但是ORACLE就很精确,是什么字符就是什么字符,多一个空格就别想登录
所以最好要加equal()
我以前也有同样的问题,应该是数据库的原因...