Passing dynamic value to url using retrofit - android

I am trying to make a simple weather app using retrofit library. I want the city name to be dynamic. This is what i have done so far:
full url:
http://api.openweathermap.org/data/2.5/forecast/daily?q=dhaka&cnt=7&appid=1111
base url:
http://api.openweathermap.org/
in the main activity
LinkedHashMap<String,String>data=new LinkedHashMap<>();
data.put("q",targetCity);
data.put("cnt",Integer.toString(7));
data.put("appid",getString(R.string.api_key));
Call<WeatherResponse>weatherResponseCall=weatherServiceApi.getAllWeatherReport(data);
and in my api interface:
#GET("data/2.5/forecast/daily?")
Call<WeatherResponse>getAllWeatherReport(#QueryMap LinkedHashMap<String,String>data);
I am neither getting any error, nor any response data.
Please help.

You aren't executing the call function...
WeatherResponse response = call.execute().body();
If I were you, I would try using a ResponseBody from okhttp to get the data returned. Then using response.string() you can see what's retrieved from the request.
Or, to log the body data of each request/response you should add this interceptor when building your Retrofit object:
OkHttpClient client = httpClient.addInterceptor(interceptor.setLevel(HttpLoggingInterceptor.Level.BODY))
.build();
Retrofit retrofit = builder.client(client).build();
return retrofit.create(serviceClass);

Related

How to read custom header response (json object) in retrofit

I have an authorization api that returns null body but with access token in headers.
I am able to read the okhttp3.Headers object and also get header names as Set using
Headers headers = response.headers(); // response object of type Response<T>
Set<String> headerNames = headers.names();
But in the code the headers object does not show the custom header (access_token) returned as response. However, in postman i can see the custom header as shown below:
access_token -> { "Token":"adklasldalksdalkdask",
"Provider":"ABC" }
I am using interceptors to get the header as shown:
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
Can someone suggest how to read the access token as part of the custom header in auth response?
First print the entire response, body, code, message, header(by logging or something else) and try to find a clue from there.
I would recommend you to read the API docs and see the type of request it is asking for.
Use Postman to check which one of the following is working:
1.form-data
2.x-www-form-Urlencoded
3.raw
4.binary
And then accordingly set the annotations in the method declarations in the interface.
eg: in my case it was taking x-www-form-Urlencoded so I had to mention it using
#FormUrlEncoded
#Headers("Content-Type: application/x-www-form-urlencoded")
in the method declaration.

Android Retrofit GsonConverterFactory

I encode data on response .
put the key on header.
Now I can decode on Observer when I get string data.
But I would like to do on GsonConverterFactory
then I can just decode on gsonConverterFactory and use gson data when response
I would like to know how to get header in GsonConverterFactory responseBodyConverter?
you need to add okhttpclient to your retrofit client for getting header
please refer this link

Why Post method of okhttp occur error [Content-Type header specified in HTTP request is not supported: application/x-www-form-urlencoded]?

I call a Rest API of salesforce by post method:
url = "https://test-dev-ed.my.salesforce.com/services/apexrest/AccountUsers/"
client = OkHttpClient()
val jsonIn = FormBody.Builder()
.add("email",URLEncoder.encode("dt1#gmail.com", "UTF-8"))
.add("password", URLEncoder.encode("1","UTF-8"))
.build()
request = Request.Builder()
.post(jsonIn)
.header("Authorization", "Bearer "+accesstoken)
.addHeader("Content-Type","application/x-www-form-urlencoded")
.url(url)
.build()
response = client.newCall(request).execute()
This is rest api:
#HttpPost
global static ID createUser(String email, String password) {
AccountUser__c us=new AccountUser__c();
us.Email__c=email;
us.Password__c=password;
us.Status__c=0;
insert us;
return us.Id;
}
But result return is error:
[{"errorCode":"UNSUPPORTED_MEDIA_TYPE","message":"Content-Type header specified in HTTP request is not supported: application/x-www-form-urlencoded"}]
I had try change application/json to application/x-www-form-urlencoded , but still can't resolve.
I try call a Get method, it is ok.
Why Post method occur error [Content-Type header specified in HTTP request is not supported]?
I would like to suggest a better resolution. Retrofit Library
Even though it is not mandatory to use Retrofit, these are few eye catchy aspects which makes it reliable and handy in similar use case of yours.
Why to use Retrofit?
Type-safe REST Adapter that makes common networking tasks easy
For POST operations, retrofit helps in assembling what needed to be submitted. Eg:- Generating URL encoded form.
Takes care of URL manipulation, requesting, loading, caching, threading, synchronization, sync/async calls
Helps to generate URL using type-aware generated code tied to specific REST API
Parsing JSON using GSON
Retrofit is an API adapter wrapped over OkHttp
The problem that you are facing can be resolved using retrofit like this.
public interface APIConfiguration{
#Headers({"Accept:application/json",
"Content-Type:application/x-www-form-urlencoded"})
#FormUrlEncoded
#POST("user/registration")
Observable<DataPojo> registrationAPI(#FieldMap(encoded = true) Map<String, String> params);
}
That's it, with few annotation the library takes care of Form URL
Encoding and related dependencies.
As it is inappropriate to start from corresponding Retrofit dependencies and sample code, you can go through Reference One and Reference Two for more details.
As per my understanding just checkout the difference the content type header "application/x-www-form-urlencoded" is inefficient for sending large quantities of binary data or text containing non-ASCII characters. The content type "multipart/form-data" should be used for submitting forms that contain files, non-ASCII data, and binary data.
The content "multipart/form-data" follows the rules of all multipart MIME data streams.
https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4
Also try your http request by setting your content type header as multipart/formdata.

How do I get response headers with RxAndroid + Retrofit in Kotlin?

I have an API observable returning a CUSTOM_MODEL. I would like to get the response headers from this call too.
Change your retrofit definition to return Observable<Response<CUSTOM_MODEL>>. The headers can be accessed through the Response object and CUSTOM_MODEL will be available through Response.body().

Deserialize Retrofit response when response body is Void

I'm using Retrofit to get some data from a server. The problem is the response body is null (although I get a response code : 200 ) and if you check this github issue like I did you will see that they suggest you to use Call<Void> for empty response's body.
I did change it to Call<Void> and now when I'm making a request with Retrofit it enters onResponse and response is successful, but then I can't deserialize it with Gson.
Using :
DataServiceResponse serviceResponse = gson.fromJson(response.body(), DataServiceResponse.class);
is not possible since response.body() is void.

Categories

Resources