You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Retrofit2无法发送POST数据问题求助

解决Retrofit2 POST JSON数据无法被PHP服务端接收的问题

嘿,我看了你的代码和问题描述,这问题其实出在服务端PHP的逻辑混乱以及一个小拼写错误上,结合Retrofit的请求格式特性,咱们一步步解决:

问题根源拆解

你用Retrofit的@Body注解发送的是JSON格式的请求体(Content-Type为application/json),但你的PHP代码同时在尝试读取$_POST数组和php://input:

  • $_POST只对application/x-www-form-urlencoded或multipart/form-data格式的请求生效,JSON请求不会填充这个数组
  • 你还写错了fclose的语法(写成了$fclose($myfile)),导致日志文件无法正确写入,误以为请求体为空

解决方案

第一步:彻底修复服务端PHP代码

把PHP代码改成只处理JSON输入的逻辑,移除多余的$_POST判断,同时修复文件关闭的错误:

<?php
header("Content-type: application/json; charset=utf-8");

// 读取JSON格式的请求体
$inputJSON = file_get_contents('php://input');
$input = json_decode($inputJSON, TRUE);

// 安全初始化变量,避免未定义报错
$numb = isset($input['numb']) ? $input['numb'] : null;
$name = isset($input['name']) ? $input['name'] : null;

// 业务逻辑判断
if (empty($numb)) {
    $json = json_encode( array( "emp" => $name, "status" => "2"));
} else {
    $json = json_encode( array( "emp" => "nothing", "status" => "2"));
}

// 调试日志写入(修复fclose的拼写错误)
$myfile = fopen("testfile.txt", "w");
fwrite($myfile, $inputJSON . "\n");
fwrite($myfile, "numb: " . $numb . "\n");
fwrite($myfile, "name: " . $name);
fclose($myfile);

echo $json;
?>

第二步:可选但推荐 - 添加Retrofit日志拦截器调试

为了能直观看到Retrofit发送的请求详情(包括请求头、请求体),可以添加日志拦截器:

  1. 在build.gradle添加依赖:
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3'
  1. 修改APIClient.java配置日志拦截器:
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class APIClient {
    private static final String BASE_URL = "https://myurl.ru/";
    private static Retrofit retrofit;

    public static Retrofit getClient() {
        if (retrofit == null) {
            // 打印完整的请求和响应日志
            HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);

            OkHttpClient client = new OkHttpClient.Builder()
                    .addInterceptor(logging)
                    .build();

            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .client(client)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}

添加后你可以在Logcat里看到完整的请求内容,确认JSON是否正确发送。

第三步:测试验证

修改完服务端后重新运行你的Android应用,此时testfile.txt会正确记录请求的JSON内容,服务端也能正常解析numb和name参数,返回符合预期的响应。

为什么Postman测试正常?因为你在Postman里应该选了raw->JSON格式发送请求,和Retrofit的@Body行为一致,服务端当时能从php://input读到数据;但你的PHP代码冗余的$_POST判断会干扰逻辑,现在移除后就完全匹配Retrofit的请求格式了。

内容的提问来源于stack exchange,提问作者Maria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:18:48