Retrofit2 POST传递String Body调用IGDB API无效果问题排查
解决IGDB API POST请求未识别Body的问题
问题分析
你的请求返回空Body的默认结果,主要有两个原因:
- 查询语法错误:IGDB的查询语言不允许多个
where子句,你当前的查询包含两个where,会被API判定为无效查询,从而返回默认结果。 - Retrofit Body传递配置问题:直接用
String作为@Body参数时,若未正确配置Content-Type和转换器,IGDB可能无法识别请求体内容。
修复步骤
1. 修正查询语法
将两个where子句合并为一个,使用&连接多个条件:
val validQuery = "fields id, name; where status = (0, 2, 3, 4) & rating > 0; offset 0;"
2. 配置Retrofit支持String类型Body
方式一:添加Content-Type头部并引入Scalars转换器
- 修改API接口:在
@Headers中添加Content-Type: text/plain,确保IGDB能正确识别请求体格式:
interface GameApiClient { @Headers( "Client-ID: XXXXXXXXXXXXXXXXXXXXXX", "Authorization: Bearer XXXXXXXXXXXXXX", "Accept: */*", "Content-Type: text/plain" ) @POST("games") suspend fun getAllGames(@Body query: String): Response<List<Game>> }
- 更新Retrofit实例:添加
ScalarsConverterFactory,让Retrofit支持String类型的请求体和响应:
// 在RetrofitHelper的getRetrofit()方法中 val retrofit = Retrofit.Builder() .baseUrl("你的IGDB API基础URL") .addConverterFactory(ScalarsConverterFactory.create()) // 添加这一行 .addConverterFactory(GsonConverterFactory.create()) // 保留你原有的JSON转换器 .build()
方式二:显式使用RequestBody(更稳妥)
如果方式一仍有问题,可以直接构建RequestBody并指定媒体类型:
- 修改API接口:
interface GameApiClient { @Headers( "Client-ID: XXXXXXXXXXXXXXXXXXXXXX", "Authorization: Bearer XXXXXXXXXXXXXX", "Accept: */*" ) @POST("games") suspend fun getAllGames(@Body query: RequestBody): Response<List<Game>> }
- 调用接口时构建RequestBody:
suspend fun getGames(): List<Game> { return withContext(Dispatchers.IO) { val mediaType = MediaType.parse("text/plain") val requestBody = RequestBody.create(mediaType, "fields id, name; where status = (0, 2, 3, 4) & rating > 0; offset 0;") val response = retrofit.create(GameApiClient::class.java) .getAllGames(requestBody) response.body() ?: emptyList() } }
验证
完成上述修改后,重新发起请求,IGDB应该能正确解析你的查询条件,返回符合要求的游戏列表。
内容的提问来源于stack exchange,提问作者Daniel Hernández
相关产品推荐
相关产品推荐

