Android向Flask服务传参时遇SSL库失败错误,求解决方案
解决Android向Flask发送JSON请求时的SSL握手失败问题
看起来你遇到的核心问题有两个:一是Flask服务默认没有配置HTTPS支持,导致你用https://访问时触发SSL握手错误;二是即使配置了HTTPS,自签名证书在Android端会被默认拒绝,同时SSL协议版本兼容也可能存在问题。下面是分步的解决方案:
方案一:临时改用HTTP调试(适合开发阶段)
如果只是开发调试,最简单的方法是切换到HTTP协议,避免SSL相关的复杂配置:
修改Android代码中的URL
把原代码里的HTTPS地址改成HTTP:
// 替换原URL定义 URL url = new URL("http://192.168.43.31:5000/a/");
修正Android的JSON写入逻辑
你当前用os.writeBytes(jsonParam.toString())可能存在编码隐患,建议换成更可靠的字节流写入方式:
// 替换原来的os.writeBytes部分 OutputStream os = conn.getOutputStream(); byte[] input = jsonParam.toString().getBytes("UTF-8"); os.write(input, 0, input.length); os.flush(); os.close();
完善Flask端的请求处理
给Flask接口添加打印逻辑,方便你确认是否收到数据:
#!flask/bin/python from flask import Flask , request app = Flask(__name__) @app.route('/a/', methods=['GET', 'POST']) def get_request1(): if request.method == 'POST': # 打印原始请求数据 print("Received raw data:", request.data) # 解析JSON格式数据 json_data = request.get_json() print("Parsed JSON:", json_data) return "Request received" if __name__ == '__main__': app.run(host="0.0.0.0",debug=True, port=5000)
方案二:配置Flask的HTTPS并让Android信任自签名证书(适合需要HTTPS的场景)
如果必须使用HTTPS,需要完成Flask的SSL配置,同时让Android端信任自签名证书:
步骤1:生成自签名SSL证书
使用OpenSSL生成证书和密钥文件(放在Flask项目根目录):
openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365
步骤2:修改Flask代码启动HTTPS服务
在app.run()中指定SSL证书和密钥:
#!flask/bin/python from flask import Flask , request app = Flask(__name__) @app.route('/a/', methods=['GET', 'POST']) def get_request1(): if request.method == 'POST': json_data = request.get_json() print("Received JSON:", json_data) return "OK" if __name__ == '__main__': # 启用HTTPS,指定证书文件路径 app.run(host="0.0.0.0", debug=True, port=5000, ssl_context=('cert.pem', 'key.pem'))
步骤3:让Android信任自签名证书
Android默认不信任自签名证书,需要将证书转换为Android支持的格式,并自定义SSL信任逻辑:
转换证书格式(使用keytool)
将生成的cert.pem转换为BKS格式(需先安装BouncyCastle工具):
keytool -importcert -alias myflaskcert -file cert.pem -keystore mycert.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider
添加自定义SSL工具类
public class SSLUtils { public static SSLSocketFactory getSSLSocketFactory(Context context, int certRawResId) { try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); InputStream certInputStream = context.getResources().openRawResource(certRawResId); Certificate ca; try { ca = cf.generateCertificate(certInputStream); } finally { certInputStream.close(); } KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null, null); keyStore.setCertificateEntry("ca", ca); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(keyStore); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, tmf.getTrustManagers(), null); return sslContext.getSocketFactory(); } catch (Exception e) { e.printStackTrace(); return null; } } }
修改Android网络请求代码
在请求中使用自定义的SSL SocketFactory:
Thread thread = new Thread(new Runnable() { @Override public void run() { try { URL url = new URL("https://192.168.43.31:5000/a/"); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); // 设置自定义SSL信任 conn.setSSLSocketFactory(SSLUtils.getSSLSocketFactory(getApplicationContext(), R.raw.mycert)); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8"); conn.setRequestProperty("Accept","application/json"); conn.setDoOutput(true); conn.setDoInput(true); JSONObject jsonParam = new JSONObject(); jsonParam.put("name", name); Log.i("JSON", jsonParam.toString()); OutputStream os = conn.getOutputStream(); byte[] input = jsonParam.toString().getBytes("UTF-8"); os.write(input, 0, input.length); os.flush(); os.close(); Log.i("STATUS", String.valueOf(conn.getResponseCode())); Log.i("MSG" , conn.getResponseMessage()); conn.disconnect(); } catch (Exception e) { e.printStackTrace(); } } }); thread.start();
额外注意事项
- 确保Android设备和Flask服务器在同一个局域网内,能正常ping通
192.168.43.31 - 开发阶段如果使用HTTP,需要在AndroidManifest.xml中添加
android:usesCleartextTraffic="true" - 生产环境建议用Nginx等反向代理处理HTTPS,不要让Flask直接处理SSL请求
内容的提问来源于stack exchange,提问作者ahmedhelali100
相关产品推荐
相关产品推荐

