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

安卓APP中Retrofit POST请求返回400错误排查求助

Troubleshooting Retrofit 400 Bad Request with POST Requests (Android)

Hey there! Sorry to hear you're hitting that frustrating 400 Bad Request error with your Retrofit POST call—especially since Postman works perfectly. That discrepancy usually means your app is formatting the request differently than Postman, so let’s walk through the most likely fixes, starting with the POJO classes you suspect.

1. Validate POJO Serialization Annotations & Naming

This is the #1 culprit when Postman works but Retrofit doesn’t. APIs often use snake_case (like genre_id) while Java uses camelCase (genreId), so you need explicit mapping with @SerializedName:

// Incorrect: No mapping for snake_case API fields
public class Genre {
    private int genreId; // API expects "genre_id"
}

// Correct: Use @SerializedName to match API field names
public class Genre {
    @SerializedName("genre_id")
    private int genreId;
}
  • Also, if you’re using GsonBuilder.excludeFieldsWithoutExposeAnnotation(), make sure all required fields have the @Expose annotation—missing it will exclude the field from the request body entirely.
  • Double-check that your POJO has all required fields the API expects (no missing fields, no extra fields that the API rejects).

2. Confirm Request Body Type & Retrofit Setup

Retrofit handles request bodies differently based on annotations—make sure you’re using the right one for your API:

  • If your API accepts JSON (like Postman likely does), use @Body (not @FormUrlEncoded or @Field):
    // Right for JSON request bodies
    @POST("movies")
    Call<Movie> createMovie(@Body Movie movie);
    
    // Wrong if API expects JSON (this sends form-data instead)
    @FormUrlEncoded
    @POST("movies")
    Call<Movie> createMovie(@Field("title") String title, @Field("genre") Genre genre);
    
  • Verify your Retrofit instance includes GsonConverterFactory (this tells Retrofit to serialize POJOs to JSON):
    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create()) // Critical for JSON serialization
        .build();
    
  • Check that your Content-Type header matches Postman’s—Retrofit sets application/json automatically when using @Body and Gson, but if you’ve added custom headers, make sure they don’t override this.

3. Log the Exact Request Body to Compare with Postman

The fastest way to spot the issue is to see what your app is actually sending. Add HttpLoggingInterceptor to your Retrofit setup to print the full request (including body) to Logcat:

// Add this dependency first if you don't have it: implementation 'com.squareup.okhttp3:logging-interceptor:4.11.0'
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

OkHttpClient okHttpClient = new OkHttpClient.Builder()
    .addInterceptor(loggingInterceptor)
    .build();

// Use this client in your Retrofit instance
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(BASE_URL)
    .client(okHttpClient)
    .addConverterFactory(GsonConverterFactory.create())
    .build();

Now check Logcat for the POST request’s body. Compare it line-for-line with the request body you used in Postman. You’ll almost certainly see a mismatch:

  • Missing required fields
  • Incorrect field names
  • Null values where the API expects a non-null value
  • Wrong data types (e.g., a String where an Integer is expected)

4. Check for Null Values & Invalid Data

APIs often reject requests with null values for required fields. Make sure when you create your Movie or Genre objects, you’re setting all mandatory fields:

// Bad: Missing required "title" field
Movie movie = new Movie();
movie.setGenre(genre);

// Good: All required fields are set
Movie movie = new Movie();
movie.setTitle("Inception");
movie.setGenre(genre);
movie.setReleaseYear(2010);

Also, confirm data types match exactly—if the API expects release_year as an integer, don’t pass it as a String.

5. Verify Endpoint Path & Base URL

Double-check that your API endpoint path matches Postman’s exactly:

  • If Postman uses https://your-api.com/api/v1/movies, make sure your base URL is https://your-api.com/api/v1/ (ends with a slash) and your endpoint is @POST("movies")
  • Avoid typos in the path (e.g., movie instead of movies)
  • Ensure you’re using @POST (not @GET or another HTTP method)

Once you fix the mismatch between your app’s request and Postman’s, that 400 error should disappear and you’ll get the 200 response you’re expecting!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:56:41