Retrofit Body Giving Null Values But Coming Perfect in Postman

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



Leave a reply



Submit