使用Retrofit向支付网关发送JSON返回null问题求助
排查Retrofit返回Null响应的常见问题
Postman正常但Retrofit返回null,说明支付网关接口本身是通的,问题大概率出在Retrofit的配置、请求构建或数据解析环节。我帮你梳理几个最容易踩坑的排查方向:
1. 先确认RetrofitClient的核心配置
你只贴了ApiUtils的代码,RetrofitClient的实现是关键,尤其是JSON序列化器和请求头这两点:
- 必须添加
GsonConverterFactory(或你用的其他序列化器),否则Retrofit无法解析JSON响应,直接返回null:Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) // 这行不能少! .client(new OkHttpClient.Builder().build()) .build(); - 支付网关通常需要特定请求头(比如
Content-Type: application/json、授权头),Postman里你可能手动加了,但Retrofit里没配置。可以在接口方法上加@Headers,或者全局配置:// 全局添加请求头示例 OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(chain -> { Request request = chain.request().newBuilder() .header("Content-Type", "application/json") .header("Authorization", "Bearer your_auth_token") // 如果网关要求授权的话 .build(); return chain.proceed(request); }) .build();
2. 检查APIService的接口方法定义
Postman的请求细节必须和Retrofit接口完全匹配:
- 确认请求方式(POST/PUT)和路径正确,比如Postman里的请求路径是
/api/rest/v2/payments,接口里要写@POST("api/rest/v2/payments") - 发送JSON体必须用
@Body注解,不能用@Field或@Query(那是表单提交用的):// 正确的JSON请求写法 @POST("your-gateway-endpoint") Call<PaymentResponse> submitPayment(@Body PaymentRequest requestBody); - 如果Postman里用的是表单提交(x-www-form-urlencoded),那Retrofit要改用
@FormUrlEncoded+@Field,别搞混了。
3. 验证Request/Response模型的序列化
模型类的字段必须和网关的JSON结构完全对应,否则Gson解析会返回null:
- 字段名要匹配(大小写敏感),如果JSON里是
transaction_id,你的模型类要加@SerializedName注解:public class PaymentResponse { @SerializedName("transaction_id") private String transactionId; // 其他字段、getter/setter } - 如果JSON有嵌套结构,模型类也要对应嵌套,不能漏层级,比如网关返回
{"data":{"status":"success"}},你就得建一个包含Data类的Response模型。
4. 开启Retrofit日志,对比Postman请求
这是最有效的排查手段,能直接看到Retrofit发送的请求和网关返回的原始数据:
- 添加OkHttp的日志拦截器:
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BODY); // 打印完整的请求/响应 OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(logging) .build(); - 运行后看Logcat日志,重点对比:
- 请求体是否和Postman里的完全一致?
- 请求头有没有缺失关键字段?
- 如果网关返回错误状态码(比如400/500),
response.body()会是null,这时候要调用response.errorBody().string()获取错误信息。
5. 检查异步回调的处理逻辑
如果用的是异步请求,别忽略错误响应的处理:
apiService.submitPayment(requestModel).enqueue(new Callback<PaymentResponse>() { @Override public void onResponse(Call<PaymentResponse> call, Response<PaymentResponse> response) { if (response.isSuccessful()) { PaymentResponse data = response.body(); // 处理成功数据 } else { // 打印错误响应内容 try { String errorMsg = response.errorBody().string(); Log.e("PaymentError", errorMsg); } catch (IOException e) { e.printStackTrace(); } } } @Override public void onFailure(Call<PaymentResponse> call, Throwable t) { t.printStackTrace(); // 网络错误或解析错误 } });
你可以先按上面的步骤排查,尤其是开启日志这一步,基本能定位问题。如果还是解决不了,把APIService的完整代码、Request/Response模型类,还有日志里的请求响应内容贴出来,我再帮你细化分析。
内容的提问来源于stack exchange,提问作者Vision
相关产品推荐
相关产品推荐

