使用JDBC连接Azure SQL数据库失败:SSL相关问题求助
解决Android Studio连接Azure SQL的SSL错误问题
我来帮你排查这个SSL连接故障,Azure SQL对加密连接有强制要求,你当前的配置可能踩了几个关键坑,咱们一步步来修复:
1. 修正连接字符串的SSL配置
Azure SQL默认强制要求SSL加密,你把encrypt=false改成encrypt=true才符合服务端的要求。另外trustServerCertificate=false和hostNameInCertificate=*.database.windows.net的设置是正确的,不用调整。修改后的连接字符串示例:
String connectionURL = "jdbc:sqlserver://****.database.windows.net:1433;database=****;user=****@****;password=*****;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30";
2. 替换StrictMode的非最佳实践
你当前用StrictMode.ThreadPolicy.Builder().permitAll()绕开主线程限制,虽然能临时解决,但会增加ANR(应用无响应)的风险。建议把数据库操作放到后台线程,比如用Java的AsyncTask,这里给一个实现示例:
private class DbConnectionTask extends AsyncTask<Void, Void, Connection> { @Override protected Connection doInBackground(Void... params) { Connection connection = null; try { // 加载JDBC驱动 Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); // 使用修正后的连接字符串 String connectionURL = "你的连接字符串"; connection = DriverManager.getConnection(connectionURL); } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } return connection; } @Override protected void onPostExecute(Connection connection) { if (connection != null) { // 连接成功,执行后续操作 Toast.makeText(getApplicationContext(), "数据库连接成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getApplicationContext(), "连接失败,请检查配置", Toast.LENGTH_SHORT).show(); } } } // 启动后台任务 new DbConnectionTask().execute();
3. 更新JDBC驱动版本
旧版本的Microsoft JDBC驱动对Azure SQL的SSL兼容性较差,确保你用的是最新版本。在Module级别的build.gradle中添加依赖:
// 根据你的Android SDK版本选择对应的JRE版本,比如jre8/jre11/jre17 implementation 'com.microsoft.sqlserver:mssql-jdbc:12.4.1.jre8'
4. 手动添加Azure根证书(可选)
部分安卓设备可能默认不信任Azure的SSL根证书,导致验证失败。你可以手动导入证书:
- 下载DigiCert Global Root CA证书(Azure SQL使用的根证书)
- 将证书文件放到
res/raw目录下 - 在代码中加载证书并配置SSL上下文:
try { // 加载raw目录下的证书 InputStream certStream = getResources().openRawResource(R.raw.digicert_global_root_ca); CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); X509Certificate cert = (X509Certificate) certFactory.generateCertificate(certStream); // 初始化密钥库 KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null, null); keyStore.setCertificateEntry("azure_cert", cert); // 创建信任管理器 TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmFactory.init(keyStore); // 配置SSL上下文 SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, tmFactory.getTrustManagers(), new SecureRandom()); // 使用数据源方式建立连接 SQLServerDataSource dataSource = new SQLServerDataSource(); dataSource.setURL(connectionURL); dataSource.setSslContext(sslContext); Connection connection = dataSource.getConnection(); } catch (Exception e) { e.printStackTrace(); }
按以上步骤调整后,应该能解决SSL相关的连接错误。
内容的提问来源于stack exchange,提问作者Mel H




