I am calling a link shortner api using post request and body of the post contains long url of type string but api return a null body as response and 200 and response code
This is the response I am getting from api
post request
Retrofit and api interface object
I unable to figure out where i am doing wrong please help
"https://rapidapi.com/BigLobster/api/url-shortener-service" here is the api page from rapidapi
I tried to change content type from application/json to application/x-www-form-urlencoded but i got response code as 400 on using content-type as application/x-www-form-urlencoded
Tried to add or remove okhttpclient but did not worked
Related
I am using Retrofit v2.4.0 in my project. I need to get token using one API call and using this token in header of the POST request I should use another API call where I should add one header and two parameter to the body of the request. The following code is of the second API call (JavaRx is used):
#FormUrlEncoded
#POST("auth/sendCode")
#Headers("Content-Type: application/json")
Single<SendCodeResponse> sendCode(#Header("token") String token,
#Field("phoneNumber") String phoneNumber,
#Field("langCode") String langCode);
However, it is not working. When I log my request, it is showing that the request body is not correct.
What is wrong with my code above?
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.
url:http://xxx.xxx.xxx/Order/Interface/V1/Polling?token=xxx¶m={"user":{"userID":2}}
post
token="xxx"
param="{"user":{"userID":2}}"
How to use Retrofit Post?
POST request parameters are not typed in the URL, they are typed on the body. For a request like that, you must use a GET request.
I cant control server, and it constantly response to me with Cache-Control: no-cache header. But I want to force OkHttp to cache that response regardless.
Can I somehow remove header from OkHttp response before it has cached?
You can indeed rewrite the Cache-Control headers for responses, thus allowing OkHttp to cache it. From the Recipes on their site ( https://github.com/square/okhttp/wiki/Interceptors )
private static final Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() {
#Override public Response intercept(Interceptor.Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder()
.header("Cache-Control", "max-age=60")
.build();
}
};
Just add this as a network interceptor using client.addNetworkInterceptor().
You cannot scrub out the no-cache header, but you can still get some caching through conditional GETs.
From OkHttp's Cache-Control docs:
In a response, this field's name "no-cache" is misleading. It doesn't prevent us from caching the response; it only means we have to validate the response with the origin server before returning it. We can do this with a conditional GET.
The no-cache doesn't prevent the response from being stored! When OkHttp later attempts to use that cached response, it will validate that the cached response is still good by contacting the origin server with an If-Modified-Since header. If the server returns 304 Not Modified, the response body is served from the cache.
You can increase your chances of a cache hit by adding a max-stale to your request headers. This one will cause it to use the cache for responses that expired as many as 365 days ago.
Cache-Control: max-stale=31536000
I'm trying to POST a JSONObject using the Retrofit library, but when I see the request at the receiving end, the content-length is 0.
In the RestService interface:
#Headers({
"Content-type: application/json"
})
#POST("/api/v1/user/controller")
void registerController(
#Body JSONObject registrationBundle,
#Header("x-company-device-token") String companyDeviceToken,
#Header("x-company-device-guid") String companyDeviceGuid,
Callback<JSONObject> cb);
And it gets called with,
mRestService.registerController(
registrationBundle,
mApplication.mSession.getCredentials().getDeviceToken(),
mApplication.mSession.getCredentials().getDeviceGuid(),
new Callback<JSONObject>() {
// ...
}
)
And I'm certain that the registrationBundle, which is a JSONObject isn't null or empty (the other fields are certainly fine). At the moment the request is made, it logs out as: {"zip":19312,"useAccountZip":false,"controllerName":"mine","registrationCode":"GLD94Q"}.
On the receiving end of the request, I see that the request has Content-type: application/json but has Content-length: 0.
Is there any reason why sending JSON in the body like this isn't working? Am I missing something simple in using Retrofit?
By default, you don't need to set any headers if you want a JSON request body. Whenever you test Retrofit code, I recommend setting .setLogLevel(RestAdapter.LogLevel.FULL) on your instance of RestAdapter. This will show you the full request headers and body as well as the full response headers and body.
What's occurring is that you are setting the Content-type twice. Then you're passing a JSONObject, which is being passed through the GsonConverter and mangled to look like {"nameValuePairs":YOURJSONSTRING} where YOURJSONSTRING contains your complete, intended JSON output. For obvious reasons, this won't work well with most REST APIs.
You should skip messing with the Content-type header which is already being set to JSON with UTF-8 by default. Also, don't pass a JSONObject to GSON. Pass a Java object for GSON to convert.
Try this if you're using callbacks:
#POST("/api/v1/user/controller")
void registerController(
#Body MyBundleObject registrationBundle,
#Header("x-company-device-token") String companyDeviceToken,
#Header("x-company-device-guid") String companyDeviceGuid,
Callback<ResponseObject> cb);
I haven't tested this exact syntax.
Synchronous example:
#POST("/api/v1/user/controller")
ResponseObject registerController(
#Body MyBundleObject registrationBundle,
#Header("x-company-device-token") String companyDeviceToken,
#Header("x-company-device-guid") String companyDeviceGuid);