Retrofit 2: response.body() is null, but status code is 200
I think there's a mistake in your model.
Try:
public class StackQuestions {
@SerializedName("items")
List<StackQuestion> questions;
}
Retrofit 2 - Response body null when response status is 422 (unprocessable entity)
By default, when your server is returning an error code response.body()
is always null
. What you are looking for is response.errorBody()
. A common approach would be something like this:
@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
}
}
If you need something advanced take a look at Interceptors and how to use them
Retrofit 2 login post request returns 500 but works well on postman
Problem solved (server problem).
One particular note: in the API this request was redirecting internally to the request for the web login, this redirecting was performing well from POstman and IOS but not coming from Android (my coworkers who developed the web version have detected this with Fiddler).
This request also did not belong to the mobile API that I was using, so the problem might be there.
The solution was to add a new login request to the mobile API and voilà, it worked.
Retrofit request:
@POST("mobile/login")
Call<JsonObject> login(@Body Map<String,String> parameters);
Postman Returning Null Values in SOAP Response
If you open in browser URI http://localhost:9006/Service?wsdl, you'll see WSDL generated by JAX-WS for your service. It should contain following snippet:
<types>
<xsd:schema>
<xsd:import namespace="http://example.soap.kdv.org/" schemaLocation="http://localhost:9006/Service?xsd=1"/>
</xsd:schema>
</types>
It contains reference to XML schema defining structure of XML messages used in web-service. If you open URI http://localhost:9006/Service?xsd=1 as well (URI can differ, please check it), you'll see definition of request and response message:
<xs:schema xmlns:tns="http://example.soap.kdv.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0" targetNamespace="http://example.soap.kdv.org/">
<xs:element name="message" type="tns:message"/>
<xs:element name="messageResponse" type="tns:messageResponse"/>
<xs:complexType name="message">
<xs:sequence>
<xs:element name="arg0" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="messageResponse">
<xs:sequence>
<xs:element name="return" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
It defines following structure of request message:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:exam="http://example.soap.kdv.org/">
<soapenv:Header/>
<soapenv:Body>
<exam:message>
<!--Optional:-->
<arg0>test</arg0>
</exam:message>
</soapenv:Body>
</soapenv:Envelope>
Try this message in postman, it should return you desired result.
Also I'd like to recommend SOAP UI tool for testing web services. When creating new SOAP project in this tool, it imports WSDLs and generates for you request messages.
Retrofit 2 Request works in Postman but not in App
Your code is returning but enqueue
is async so that is not guaranteed to happen before the return. If you read the enqueue
there is a callback there, which means it is gonna call
back
after is ready, since it is an HTTP request then that takes some time and it is finished after the return.
You have 2 alternatives, add the Callback<GetAddressResponse>
as an argument or any other callback as an argument, or you can make it suspend.
Callback
Coroutines are the recommended way of doing things now so this is no longer considered a good practice.
fun getAddressFromPostCode(postCode: String, callback: Callback<GetAddressResponse): List<Address>{
...
myCall.enqueue(callback)
}
The calling class has to implement the callback and pass it as an argument. You can make that more kotlin way by using a lambda:
fun getAddressFromPostCode(postCode: String, callback: (items: List<Address> -> Unit))
...
override fun onResponse(call: Call<GetAddressResponse>?, response: Response<GetAddressResponse>?) {
callback(response...)
}
}
So that makes the calling class use it this way
yourClass.getAddressFromPostCode(postalCode) { -> items
//do your thing with items
}
Coroutines
You can transform it to linear code by using suspend functions:
//make it return optional to know if it was failure
suspend fun getAddressFromPostCode(postCode: String): List<Address>? {
...
return try {
myCall.invoke().result?.body()
} catch (e: Exception) {
null
}
}
And then the calling class has to use it like this:
lifeCycleScope.launch {
val addresses = yourClass.getAddressFromPostCode(postalCode)
//do your thing on the UI with the addresses maybe pass it to an adapter
}
Android Retrofit response returning null object
Adding an extra slash "/" to the @POST
solved my issue.
public interface JsonPlaceHolderApi {
@GET("heroes")
Call<List<Post>> getPosts();
@POST("heroes/")
Call<Post> createPost(@Body Post post);
}
Related Topics
How to Get Minutes Difference Between Two Time in Android
How to Display an Image in Full Screen on Click in the Imageview
Where Is Android_Sdk_Root and How to Set It.
Check Programmatically If App Is Installed on the Device
Android Blur View (Blur Background Behind the View)
How to Check Miui Autostart Permission Programmatically
How to Make a New Line or Tab in <String> Xml (Eclipse/Android)
Open External Links in the Browser With Android Webview
How to Avoid Keyboard Pushing Layout Up on Android React-Native
How to Center the Elements in Constraintlayout
How to Measure Distance to Object With Camera
How to Connect Localhost in the Android Emulator
How to Completely Rename an Android Application
How to Make Push Notification With Specific Sound
Control the Playback Speed of Video in Android
How to Fix Mainactivity Does Not Have a Navcontroller