Retrofit 2 - 当响应状态为 422(不可处理的实体)时,响应主体为空
Retrofit 2 - Response body null when response status is 422 (unprocessable entity)
我正在使用 Retrofit 在我的网络服务器中发出 POST 请求。
但是,当响应状态为422 (unprocessable entity)
时,我似乎无法获取响应正文。响应主体总是 null
.
我想知道我是否做错了什么,或者是否有解决方法。因为我在 Postman 的请求中使用了相同的 json,并且它通常 returns 正文。
这是方法:
@Headers("Content-Type: application/vnd.api+json")
@POST("my_endpoint")
Call<JsonObject> postEntry(@Header("Authorization") String authorization, @Body JsonObject json);
正文是一个 JsonObject,我没有像文档中所说的那样进行序列化。但我不认为这是问题所在。
默认情况下,当您的服务器返回错误代码时,response.body()
始终是 null
。您要找的是response.errorBody()
。一种常见的方法是这样的:
@Override
public void onResponse(Response<JsonObject> response, Retrofit retrofit) {
if (response.isSuccess()) {
response.body(); // do something with this
} else {
response.errorBody(); // do something with that
}
}
如果您需要高级的东西,请查看 Interceptors and
在这种情况下,您必须转换响应。
看看这个link
上面link中已经提供了所有步骤。
对于 Kotlin 用户,这里是代码解决方案。
ErrorResponse.kt(这显然取决于你的错误反应)
import com.squareup.moshi.Json
data class ErrorResponse(
@Json(name="name")
val name: String? = null,
@Json(name="message")
val message: String? = null,
@Json(name="errors")
val errors: Errors? = null,
@Json(name="statusCode")
val statusCode: Int? = null
)
ApiFactory.kt(如果您需要完整代码,请告诉我)
fun parseError(response: Response<*>): ErrorResponse {
val converter = ApiFactory.retrofit()
.responseBodyConverter<ErrorResponse>(
ErrorResponse::class.java, arrayOfNulls<Annotation>(0)
)
val error: ErrorResponse
try {
error = converter.convert(response.errorBody()!!)!!
} catch (e: IOException) {
e.printStackTrace()
return ErrorResponse()
}
return error
}
并在 Presenter(我使用 MVP)
GlobalScope.launch(Dispatchers.Main) {
try {
val response = ApiFactory.apiService.LOGIN(username, password)
.await()
val body = response.body()
body?.let {
// Handle success or any other stuff
if (it.statusCode == 200) {
mView.onSuccess(it.data!!)
}
} ?:
// This is the else part where your body is null
// Here is how you use it.
// Pass the response for error handling
mView.showMessage(ApiFactory.parseError(response).message!!)
} catch (e: Exception) {
e.printStackTrace()
}
}
这就是你滚动它的方式!
这就是所有人!
我遇到了同样的错误。我的 API 正在使用 POSTMAN 请求工作,但无法通过 Android 改造调用工作。
起初我尝试使用@Field,但出现错误,但后来我尝试使用@Body 并且成功了。
Retrofit 接口调用示例[=12=]
@POST("api/v1/app/instance")
Call<InstanceResponse> updateTokenValue(
@HeaderMap Map<String, String> headers,
@Body String body);
和API调用代码为:
Map<String, String> headerMap=new HashMap<>();
headerMap.put("Accept", "application/json");
headerMap.put("Content-Type", "application/json");
headerMap.put("X-Authorization","access_token");
Map<String, String> fields = new HashMap<>();
fields.put("app_name", "video");
fields.put("app_version", "2.0.0");
fields.put("firebase_token", "token");
fields.put("primary", "1");
ApiInterface apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
Call<InstanceResponse> call = apiInterface.updateTokenValue(
headerMap,new Gson().toJson(fields));
我正在使用 Retrofit 在我的网络服务器中发出 POST 请求。
但是,当响应状态为422 (unprocessable entity)
时,我似乎无法获取响应正文。响应主体总是 null
.
我想知道我是否做错了什么,或者是否有解决方法。因为我在 Postman 的请求中使用了相同的 json,并且它通常 returns 正文。
这是方法:
@Headers("Content-Type: application/vnd.api+json")
@POST("my_endpoint")
Call<JsonObject> postEntry(@Header("Authorization") String authorization, @Body JsonObject json);
正文是一个 JsonObject,我没有像文档中所说的那样进行序列化。但我不认为这是问题所在。
默认情况下,当您的服务器返回错误代码时,response.body()
始终是 null
。您要找的是response.errorBody()
。一种常见的方法是这样的:
@Override
public void onResponse(Response<JsonObject> response, Retrofit retrofit) {
if (response.isSuccess()) {
response.body(); // do something with this
} else {
response.errorBody(); // do something with that
}
}
如果您需要高级的东西,请查看 Interceptors and
在这种情况下,您必须转换响应。 看看这个link
上面link中已经提供了所有步骤。
对于 Kotlin 用户,这里是代码解决方案。
ErrorResponse.kt(这显然取决于你的错误反应)
import com.squareup.moshi.Json
data class ErrorResponse(
@Json(name="name")
val name: String? = null,
@Json(name="message")
val message: String? = null,
@Json(name="errors")
val errors: Errors? = null,
@Json(name="statusCode")
val statusCode: Int? = null
)
ApiFactory.kt(如果您需要完整代码,请告诉我)
fun parseError(response: Response<*>): ErrorResponse {
val converter = ApiFactory.retrofit()
.responseBodyConverter<ErrorResponse>(
ErrorResponse::class.java, arrayOfNulls<Annotation>(0)
)
val error: ErrorResponse
try {
error = converter.convert(response.errorBody()!!)!!
} catch (e: IOException) {
e.printStackTrace()
return ErrorResponse()
}
return error
}
并在 Presenter(我使用 MVP)
GlobalScope.launch(Dispatchers.Main) {
try {
val response = ApiFactory.apiService.LOGIN(username, password)
.await()
val body = response.body()
body?.let {
// Handle success or any other stuff
if (it.statusCode == 200) {
mView.onSuccess(it.data!!)
}
} ?:
// This is the else part where your body is null
// Here is how you use it.
// Pass the response for error handling
mView.showMessage(ApiFactory.parseError(response).message!!)
} catch (e: Exception) {
e.printStackTrace()
}
}
这就是你滚动它的方式! 这就是所有人!
我遇到了同样的错误。我的 API 正在使用 POSTMAN 请求工作,但无法通过 Android 改造调用工作。
起初我尝试使用@Field,但出现错误,但后来我尝试使用@Body 并且成功了。
Retrofit 接口调用示例[=12=]
@POST("api/v1/app/instance")
Call<InstanceResponse> updateTokenValue(
@HeaderMap Map<String, String> headers,
@Body String body);
和API调用代码为:
Map<String, String> headerMap=new HashMap<>();
headerMap.put("Accept", "application/json");
headerMap.put("Content-Type", "application/json");
headerMap.put("X-Authorization","access_token");
Map<String, String> fields = new HashMap<>();
fields.put("app_name", "video");
fields.put("app_version", "2.0.0");
fields.put("firebase_token", "token");
fields.put("primary", "1");
ApiInterface apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
Call<InstanceResponse> call = apiInterface.updateTokenValue(
headerMap,new Gson().toJson(fields));