在Android Java中如何发送POST请求提交JSON数据?现有实现无法运行求解决
现有代码问题排查
- 键名错误:构造JSONObject时,你给
Name、Gender两个键名额外加了冒号,和你前端/React Native代码的参数名不一致,服务端会无法识别请求参数。 - 线程未启动:仅创建了Thread实例,没有调用
start()方法,整个请求逻辑不会执行。 - 缺少网络权限:未在AndroidManifest.xml中声明网络权限,系统会直接拦截所有网络请求,需要添加如下配置:
<uses-permission android:name="android.permission.INTERNET" />
- 未读取响应体:现有代码只打印了响应状态码,没有读取服务端返回的JSON数据,无法实现和前端success回调一致的逻辑。
- 线程切换问题:网络请求运行在子线程,如果你后续需要根据请求结果更新UI,必须切换到主线程操作,否则会抛出异常。
修复后的原生HttpURLConnection实现
// 全局创建Handler,用于切换到主线程 private Handler mainHandler = new Handler(Looper.getMainLooper()); public void sendPost() { Thread thread = new Thread(new Runnable() { @Override public void run() { try { URL url = new URL("https://site/data.json"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8"); conn.setRequestProperty("Accept","application/json"); conn.setDoOutput(true); conn.setDoInput(true); // 设置超时时间,避免长时间等待 conn.setConnectTimeout(10000); conn.setReadTimeout(10000); JSONObject jsonParam = new JSONObject(); // 修正键名,去掉多余冒号 jsonParam.put("Name", "Peter"); jsonParam.put("Gender", "M"); DataOutputStream os = new DataOutputStream(conn.getOutputStream()); os.writeBytes(jsonParam.toString()); os.flush(); os.close(); int responseCode = conn.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { // 读取响应体 BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } reader.close(); // 切换到主线程处理结果,对应前端success回调 mainHandler.post(() -> { // 这里可以解析response的JSON内容,更新UI }); } else { // 对应前端error回调 mainHandler.post(() -> { // 处理请求失败逻辑 }); } conn.disconnect(); } catch (Exception e) { e.printStackTrace(); mainHandler.post(() -> { // 处理异常逻辑 }); } } }); // 启动线程,不可遗漏 thread.start(); }
更推荐的OkHttp实现
目前Android开发主流使用OkHttp作为网络请求框架,无需手动管理线程、IO流,代码更简洁,稳定性更高。
首先在模块级build.gradle的dependencies块中添加OkHttp依赖,之后可以用如下代码实现同等逻辑:
// 全局初始化OkHttpClient实例 OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .build(); // 全局创建Handler,用于切换到主线程 private Handler mainHandler = new Handler(Looper.getMainLooper()); public void sendPostWithOkHttp() { // 构造请求体 JSONObject jsonParam = new JSONObject(); try { jsonParam.put("Name", "Peter"); jsonParam.put("Gender", "M"); } catch (JSONException e) { e.printStackTrace(); return; } RequestBody body = RequestBody.create( jsonParam.toString(), MediaType.parse("application/json; charset=utf-8") ); // 构造请求 Request request = new Request.Builder() .url("https://site/data.json") .post(body) .addHeader("Accept", "application/json") .build(); // 异步发起请求 client.newCall(request).enqueue(new Callback() { @Override public void onFailure(@NonNull Call call, @NonNull IOException e) { // 请求异常,切换到主线程处理 mainHandler.post(() -> { // 对应前端error回调 }); } @Override public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException { if (response.isSuccessful()) { String responseData = response.body().string(); mainHandler.post(() -> { // 对应前端success回调,解析responseData更新UI }); } else { mainHandler.post(() -> { // 处理请求失败逻辑 }); } } }); }
内容的提问来源于stack exchange,提问作者JessciaLau
相关产品推荐
相关产品推荐

