密码以反斜杠结尾时JDBC无法连接SQL Express数据库求助
问题场景
尝试通过JDBC连接SQL Express数据库实例,数据库密码为Passw0rd\。当密码不以反斜杠结尾时能正常建立连接,但以反斜杠结尾时,会触发Login failed for user 'DBA'的登录失败错误。
报错信息
打印的连接参数
jdbcURL:
jdbc:sqlserver://hostname:2638;instanceName=SQLEXPRESSSYMC;integratedSecurity=false;encrypt=true;trustServerCertificate=true,
user: DBA password: Passw0rd\
异常堆栈
com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:262), com.microsoft.sqlserver.jdbc.TDSTokenHandler.onEOF(tdsparser.java:283), com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:129), com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:37), com.microsoft.sqlserver.jdbc.SQLServerConnection.sendLogon(SQLServerConnection.java:5233), com.microsoft.sqlserver.jdbc.SQLServerConnection.logon(SQLServerConnection.java:3988), com.microsoft.sqlserver.jdbc.SQLServerConnection$LogonCommand.doExecute(SQLServerConnection.java:3932), com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7375), com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:3206), com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:2713), com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:2362), com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnection.java:2213), com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:1276), com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:861), java.sql/java.sql.DriverManager.getConnection(DriverManager.java:677), java.sql/java.sql.DriverManager.getConnection(DriverManager.java:228)
核心错误提示
com.microsoft.sqlserver.jdbc.SQLServerException: Login failed for user 'DBA'. ClientConnectionId:3be3d544-73d3-4710-aa4e-dfe78b6dcbb1
测试代码
String url = "jdbc:sqlserver://hostname:2638;instanceName=SQLEXPRESSSYMC;integratedSecurity=false;encrypt=true;trustServerCertificate=true"; String password = "Passw0rd\\"; try { System.out.println("url:" +url ); System.out.println("Password:"+password); Connection conn = DriverManager.getConnection(url , "DBA", password); System.out.println("connected"); } catch (Exception e) { e.printStackTrace(); }
备注:当密码包含反斜杠但不以其结尾时(例如String password = "Passw0rd\\a";),连接可正常建立。
解决方法
问题根源是SQL Server JDBC驱动会将密码末尾的反斜杠识别为转义符,导致实际发送给数据库的密码缺失了最后一个反斜杠,进而登录失败。可通过以下两种方式修复:
方式一:增强转义处理
在Java字符串中,用四个反斜杠\\\\表示密码末尾的一个实际反斜杠。Java会先解析为两个反斜杠,驱动则会将第二个反斜杠识别为密码的一部分。修改后的密码定义:String password = "Passw0rd\\\\";方式二:通过URL属性传递密码
将密码直接写入JDBC URL的连接参数中,此时只需用双反斜杠表示实际反斜杠即可:String url = "jdbc:sqlserver://hostname:2638;instanceName=SQLEXPRESSSYMC;integratedSecurity=false;encrypt=true;trustServerCertificate=true;user=DBA;password=Passw0rd\\\\"; Connection conn = DriverManager.getConnection(url);
内容的提问来源于stack exchange,提问作者Shekar

