Android中Retrofit发送对象数组至PHP后,PHP端如何获取数据?
解决Retrofit发送对象数组到PHP的问题
问题原因分析
- 第一种@FormUrlEncoded方式失败:Retrofit的
@Field注解仅支持原始类型或字符串,传入自定义对象列表时,会直接调用对象的toString()方法,导致PHP端收到myapp.backupArticle@f3ee606这类无意义的字符串,而非对象的实际字段数据。 - 第二种@Body方式失败:Retrofit发送的是JSON格式请求体,但PHP默认不会将JSON请求体解析到
$_POST或$_REQUEST数组中,需要手动读取原始输入并解析。
解决方案
方案一:使用JSON格式发送(推荐)
这种方式简洁高效,适合复杂对象传输。
Android端改造
- 创建包装类整合所有需要发送的数据:
public class BackupRequest { @SerializedName("deviceName") @Expose private String deviceName; @SerializedName("articles") @Expose private List<backupArticle> articles; public BackupRequest(String deviceName, List<backupArticle> articles) { this.deviceName = deviceName; this.articles = articles; } }
- 更新Retrofit接口:
@POST(Consts.BACKUP_SCRIPT_UP) Call<Integer> backupUpload(@Body BackupRequest request);
确保Retrofit实例已配置Gson转换器(多数项目默认已配置):
Retrofit retrofit = new Retrofit.Builder() .baseUrl(你的基础URL) .addConverterFactory(GsonConverterFactory.create()) .build();
PHP端处理
读取原始请求体并解析JSON:
// 读取原始JSON数据 $rawInput = file_get_contents('php://input'); // 解析为关联数组 $data = json_decode($rawInput, true); // 获取数据 $deviceName = $data['deviceName']; $articles = $data['articles']; // 遍历处理每个文章对象 foreach ($articles as $article) { $clistName = $article['clistName']; $name = $article['name']; $ord = $article['ord']; // 其他字段同理处理... }
方案二:使用表单编码发送(不推荐,仅适合简单场景)
若必须使用表单编码,需手动将每个对象的字段拆分为表单参数:
@FormUrlEncoded @POST(Consts.BACKUP_SCRIPT_UP) Call<Integer> backupUpload( @Field("deviceName") String deviceName, @Field("articles[0][clistName]") String article0ClistName, @Field("articles[0][name]") String article0Name, // 依次添加所有文章的所有字段... );
这种方式代码繁琐且不易维护,仅适用于固定数量的简单对象。
验证发送内容
添加Retrofit日志拦截器,查看实际发送的请求内容:
// 初始化日志拦截器 HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BODY); // 配置OkHttpClient OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(logging) .build(); // 应用到Retrofit Retrofit retrofit = new Retrofit.Builder() .baseUrl(你的基础URL) .client(client) .addConverterFactory(GsonConverterFactory.create()) .build();
之后在Logcat中可查看完整请求头和请求体,确认数据格式是否正确。
内容的提问来源于stack exchange,提问作者Chris972
相关产品推荐
相关产品推荐

