Retrofit中onFailure抛异常求助:JSON解析错误
Hey there, let's dig into this Retrofit parsing issue you're facing—it's super common when something suddenly breaks after working fine, so let's break down the possible causes and fixes step by step.
First, confirm exactly what the server is sending back
This is the most critical step because the error messages tell us the response isn't matching what your Retrofit setup expects:
- The
Expected BEGIN_ARRAY but was STRINGerror means your code is expecting a JSON array (like[{"key":"value"}, ...]) but the server is returning a plain string (e.g.,"Server error", empty string, or even HTML). - When you remove
setLenient(true)and get "Malformed json", that confirms the response isn't valid JSON at all.
To see the actual response:
- Use a tool like Postman to hit the same endpoint with the same headers/parameters your app uses, and check the raw response body.
- Or add Retrofit's
HttpLoggingInterceptorto your client setup to log the full response:
This will print the exact response from the server in your logcat—you'll likely see something unexpected here (like an error message string instead of the JSON array you're expecting).HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(logging) .build();
Check for server-side changes
Since this worked before and suddenly broke, the most likely culprit is a change on the server:
- Maybe the backend team updated the endpoint logic, and now returns a plain text error message instead of a structured JSON error when something goes wrong.
- Or the endpoint now returns a JSON object instead of an array, or even an HTML error page (like a 500 server error page) when it encounters an issue.
- It's also possible that the server is returning an empty response body, which Gson can't parse as an array.
Verify your Retrofit setup (just in case)
While less likely since it worked before, double-check for accidental changes:
- Make sure your interface method is still defined to return a list, e.g.,
Call<List<YourModel>> getYourData();—if someone changed it toCall<YourModel>, that would cause a mismatch (though your error suggests the opposite issue). - Confirm your Gson converter setup hasn't been altered—if you're using a custom
Gsoninstance, ensure it's still configured to parse arrays correctly.
Quick debugging hack to see the raw response
If you want to bypass the parser temporarily to inspect the response, change your interface method to return Call<ResponseBody> instead of your model type:
@GET("your-target-endpoint") Call<ResponseBody> getRawData();
Then in your callback, extract and print the raw string:
@Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { if (response.isSuccessful()) { try { String rawResponse = response.body().string(); Log.d("RetrofitDebug", "Raw server response: " + rawResponse); } catch (IOException e) { e.printStackTrace(); } } else { // Don't forget to check the error body too! try { String errorResponse = response.errorBody().string(); Log.d("RetrofitDebug", "Error response: " + errorResponse); } catch (IOException e) { e.printStackTrace(); } } }
This will show you exactly what the server is sending, which is the key to fixing the issue.
Next steps once you know the response
- If the server is returning a plain text error, reach out to your backend team to get them to return a structured JSON error (so you can parse it consistently).
- If the response format changed entirely (array to object, etc.), update your Retrofit interface and model classes to match the new format.
- If it's an intermittent server issue, you might need to add retry logic or error handling in your app to gracefully handle invalid responses.
内容的提问来源于stack exchange,提问作者Siddarth G

