I am novice android developer and developing app for the first time so please be gentle if i am making any mistake in asking question.
I have API Document which is attached (Consist of Access Token) and i want to call category Using GetCateogry method as stated in the APIdocument also want to display the Category in the Gridview.
I have tried different methods but enable to figure out how to display the Json Response to GridView. I am bit confuse about how to handle Access token using GET & Post method.
Any help would be Highly Appreciated.
Thanks in advance.
Postman showing Getcategory
API Dcoument
Access Token
If you're using a library like Retrofit to manage your network requests (which I highly recommend), you could easily add the token as header to your request with:
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder()
.header("Authentication", "accessToken"); // <-- this is the important line
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
OkHttpClient client = httpClient.build();
Check out this tutorial for further reading.
Related
I am using Picasso for image loading. Picasso doesn't have a disk cache. OkHttp maintains an HTTP cache that is controlled by HTTP cache headers. I want to set an expiry for disk cached images so added cache-control headers in HTTP response cache-control: public, max-age=7200 but it is not respecting cache headers. The current behavior is the default HTTPResponseCache which honors RFC 7234.
Is there anything we are missing?
You can rewrite cache headers in the response with a network interceptor. Here's an example from the OkHttp interceptors doc to get you started:
/** Dangerous interceptor that rewrites the server's cache-control header. */
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();
}
};
Note that you might need to remove headers from the server's response to get your desired caching behavior.
Note also that it's strictly better to fix the server to do what you want; that way it'll work correctly on iOS and on the web.
I'm trying to send a json post request to some API which in response sends a binary file back.
I'm doing well in Postman:
Header:
Body and result:
And I get the following code from Code section in Postman for Java/OKHTTP
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\r\n \"Text\":\"Hello\",\r\n \"APIKey\":\"MY_API_KEY\",\r\n \"Speaker\":\"Female1\",\r\n \"Format\":\"mp3/32/m\",\r\n \"Quality\":\"quality/normal\"\r\n}");
Request request = new Request.Builder()
.url("http://url/CloudService/ReadText")
.post(body)
.addHeader("content-type", "application/json")
.addHeader("cache-control", "no-cache")
.addHeader("postman-token", "0a1ce7c9-7a95-a2b9-7cde-8a7e6ce58386")
.build();
Response response = client.newCall(request).execute();
But when I use the above code in android it fails, I'm sure that I got Internet permission and the code is executed within an AsyncTask.
I'm not asking about the API or how to send json Post request to some API and get a binary file in response. I've used client.newCall(request).enqueue(new Callback(){//stuff here}); but none works. In response I got a 307 status code (instead of 200 in Postman) and no binary data at all. The API is very unclear and said nothing about the failure and I'm still working on that.
All I'm asking is that does Postman generates equivalent code for OkHttp correctly? and if not what is your suggestion for equivalent of this request in Java/OkHttp?
Just to provide another example, the following is also a working Python requests script to do the same job:
url = 'http://url/CloudService/ReadText'
api_key = 'MY_API_KEY'
body = {
'Text': 'Hello',
'Speaker': 'Female1',
'Format': 'mp3/32/m',
'Quality': 'quality/normal',
'APIKey': api_key
}
header = {
'Content-type': 'application/json'
}
r = requests.post(url, data=json.dumps(body), headers=header)
So after 3 days I found the problem, the server API did not mention that the URL endpoint must be ended with an / and even in their sample code they didn't use one.
It seems that both Postman and Python requests use an / at the end of URL in case of need, but Postman at least does not mention that in the generated equivalent code. Also OkHttp does not operate in the same manner.
However using a trailing / solved the problem.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am having an issue in my app, I need to be able to see or log the full network request so that I can see exactly what parameters are being posted to my server with what headers, currently it only shows me the URL, is there a way of doing this in android studio or is there some code I can write to display this data?
To further explain things seems the terms network request, parameters and headers are confusing people, I use the google volley library for all my htpp requests; GET, POST, PUT etc. Now when posting data to a URL or getting data via a specific URL i need to be able to confirm that the right parameters and headers are being sent to the server.
If you are talking about testing the parameters for your API, you probably looking for REST clients like:
Postman
Rest Client
to validate services. But before that, you should have proper documentation of all the web services.
Solution:
In Android Studio, to debug your code, simply place breakpoints on the code and press debug button to execute
You can place breakpoint by clicking on left of each line where breakpoint is shown.
Also check this tutorial:
Simple Debugging in Android Studio and follow further videos for proper debugging.
I would recommend you to use OkHttp for making all network calls. OkHttp provides Interceptors which will serve your exact purpose.
Defining an interceptor:
class LoggingInterceptor implements Interceptor {
#Override public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
logger.info(String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers()));
HttpUrl url = request.url(); // url of the request.
Headers reqHeaders = request.headers(); // Here you are able to access headers which are being sent with the request.
RequestBody body = request.body(); // provides body of request, which you can inspect to see what is being sent.
Response response = chain.proceed(request);
long t2 = System.nanoTime();
logger.info(String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()));
Headers resHeaders = response.headers(); // Headers received in the response.
return response;
}
}
Using it to make network calls:
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new LoggingInterceptor())
.build();
Request request = new Request.Builder()
.url("http://www.publicobject.com/helloworld.txt")
.header("User-Agent", "OkHttp Example")
.build();
Response response = client.newCall(request).execute();
response.body().close();
Explore the Interceptors for more customization.
I have a requirement to get a request body and to perform some logic operations with Retrofit 2.0 before doing enque operation. But unfortunately I am not able to get the post body content from my service call. At present after searching a lot I found only one solution like logging the request that I am posting using Retrofit 2.0 from this method by using HttpLoggingInterceptor with OkHttpClient. I am using the following code to log the request body in the Android Logcat:
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(Level.BODY);
OkHttpClient httpClient = new OkHttpClient();
httpClient.interceptors().add(logging);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit.create(apiClass);
Problem I am facing with the above method:
Request body are seen only on the default Android Logcat like
02-04 01:35:59.235 5007-5035/com.example.retrofitdemo D/OkHttp:{"nameValuePairs":{"id":"1","name":"chandru","type":"user"}}
But the above method returns only response body in the logcat, I am not able to get it as either String or JSONObject. Eventhough if I could able to get the response body using HttpLoggingInterceptor, my request body will be shown in the Logcat with the tag "OkHttp" all the time even after the application goes into the production (So primarily this leads like a kind of relieving the post data in the logcat).
My Requirement:
I need to get the request body as String or JSONObject or whatever method without reviling the post data in the Logcat.
What I tried:
I tried to fetch the request body even after onResponse from Response<T> response, but though I couldn't able to get it done possible. Please find the code that I am using for this purpose as follows:
Gson gson = new Gson();
String responseString = gson.toJson(response.raw().request().body());
Note: The above converted request body using gson.toJson method returns only the meta data not the request post data.
Kindly help me with this by providing your valuable tips and solutions. I have no idea how to do this. I am completely stuck up with this for the past two days. Please forgive if my question is too lengthy. Your comments are always welcome. Do let me know if my requirement is not clear. Thanks in advance.
I have got it working from this link
Retrofit2: Modifying request body in OkHttp Interceptor
private String bodyToString(final RequestBody request) {
try {
final RequestBody copy = request;
final Buffer buffer = new Buffer();
if (copy != null)
copy.writeTo(buffer);
else
return "";
return buffer.readUtf8();
} catch (final IOException e) {
return "did not work";
}
}
Retrofit dependencies i am using are
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3'
compile 'com.squareup.okhttp3:okhttp:3.0.0-RC1'
compile 'com.squareup.okhttp3:logging-interceptor:3.0.0-RC1'
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'
I too had the similar issue, I had set JSON as #Body type in retrofit, so the namevaluepair appears in front of the raw body, and it can be seen inside the interceptor.
Even though if we log/debug the jsonObject.toString we see the request as correct without the namevaluepair presented.
What i had done was by setting
Call<ResponseBody> getResults(#Body JsonObject variable);
and in the calling of the method i converted the JSONObject to JsonObject by
new JsonParser().parse(model).getAsJsonObject();
I am trying to use DELETE method of HttpMethod. The code that I am using for that is
response = restTemplate.exchange(url, HttpMethod.DELETE, requestEntity, Response.class);
I am also using JacksonJson for mapping json. The delete functionality returns the json which should be mapped to Response class. But calling the above line doesn't works and gives internal server error with 500 as response code. But, the same API does work with RESTClient in the browser so I guess there is something that I am not doing correctly.
After doing some more research it seems that DELETE method doesn't supports request body. As we had the control over REST API we have changed the request body to be added as parameters. After doing this change the request is working properly.
Hope it helps someone.
A little late to the party I'd like to chime in here as well (document my solution for posterity)
I'm too using spring's rest template, also trying to perform a delete request with a payload AND i'd also like to be able to get the response code from the server side
Disclaimer: I'm on Java 7
My solution is also based on a post here on SO, basically you initially declare a POST request and add a http header to override the request method:
RestTemplate tpl = new RestTemplate();
/*
* http://bugs.java.com/view_bug.do?bug_id=7157360
* As long as we are using java 7 we cannot expect output for delete
* */
HttpHeaders headers = new HttpHeaders();
headers.add("X-HTTP-Method-Override", "DELETE");
HttpEntity<Collection<String>> request = new HttpEntity<Collection<String>>(payload, headers);
ResponseEntity<String> exchange = tpl.exchange(uri, HttpMethod.POST, request, String.class);