Accessing OKHttp Response Body - android

So I need to figure out how to access the value I get from my first response in my second. I would think that I could just store it to a a variable and access it in another request. However, that does not seem to be the case.
Here is the bit that is giving me issues. So my first request is getting me a token and then I need to use that which is stored in commatoken in my second request.
private final OkHttpClient client = new OkHttpClient();
public void run() throws Exception {
Request request = new Request.Builder()
.url(API_URL + authPreferences.getToken())
.build();
client.newCall(request).enqueue(new Callback() {
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
Headers responseHeaders = response.headers();
for (int i = 0, size = responseHeaders.size(); i < size; i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}
System.out.println(response.body().string());
String commatoken = response.body().string();
}
});
Request dataRequest = new Request.Builder()
.header("Authorization", "jwt"+commatoken)
.url(ChffrMe_URL).build();
client.newCall(dataRequest).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
Headers responseHeaders = response.headers();
for (int i = 0, size = responseHeaders.size(); i < size; i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}
System.out.println(response.body().string());
}
});
}

I think we can call response.body().string() only once .... so save that data to a string variable first .. and access it wherever you need it.
String response_data;
..............
response_data = response.body().string();
You are calling response.body().string() twice ...
More info
https://stackoverflow.com/a/27922818/3552066

If you want to avoid about empty result:
assert response.body() != null;
String r = response.body().string();
And if you want access to each elements :
JSONObject json = new JSONObject(r);
Log.i("love", "Res: "+json.getString("result")); //Name -> Answer
See the result:
{"fname":"John","sname":"Alice","percentage":"46","result":"Can choose someone better."} // String from
I/love: Res: All the best! // Json form by Name

Related

Get results of multiple network requests when they are all done

I'm running multiple network requests(getResponse method) in a for loop and I'm trying to get list of the responses only when ALL of the network requests are done.
I am trying to use CompletableFuture. getResponse uses OKHttp (asynch request and response)
Log.d("api_log", "Started doing things");
List<CompletableFuture> futures = new ArrayList();
for (int i = 0; i < mylist.size(); i++) {
try {
int finalI = i;
futures.add(CompletableFuture.runAsync(() -> getResponse(context, mylist.get(finalI).id)));
}
catch (Exception e) {}
}
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenRunAsync(() -> Log.d("api_log", "Ended doing things"));
This is the getResponse method:
private void getResponse(final Context context, final String id) {
Log.d("api_log", "id is: " + id);
final String url = context.getString(R.string.myurl) + "/" + id;
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
Request request = new Request.Builder()
.url(url)
.method("GET", null)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, final Response response) throws IOException {
if (!response.isSuccessful()) {
return;
}
// response HAS RECEIVED
final String strResponse = response.body().string();
Log.d("api_log", "response: " + strResponse);
}
});
}
Actual: "Ended doing things" is printed before all the responses are printed.
Expected: "Ended doing things" should be printed after all the responses are printed.
How can I achieve it?

503 HTTP response code with Twitter OAUTH

I try to get authorization token from Twitter (app-only), the code almost fully follows oficial guide, but get 503 Service unavailable code.
#Override
protected Boolean doInBackground(Void... params) {
String cred_enc = tw_cons_key + ":" + tw_priv_cons_key;
cred_enc = Base64.encodeToString(cred_enc.getBytes(), Base64.NO_WRAP);
Request request = new Request.Builder().url("https://api.twitter.com/oauth2/token")
.header("Authorization:", "Basic " + cred_enc)
.header("Content-Type:", "application/x-www-form-urlencoded;charset=UTF-8")
.post(RequestBody.create(MEDIA_TYPE_MARKDOWN, postBody))
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
ResponseBody body = response.body();
if (response.isSuccessful()) {
Headers headers = response.headers();
//response check
for (int i = 0; i < headers.size(); i++) {
System.out.println("Headers: " + i + " " + headers.name(i) + " : " + headers.value(i));
}
System.out.println(body.string());
try {
JSONObject jsonObject = new JSONObject(body.string());
} catch (JSONException e) {
e.printStackTrace();
}
} else {
throw new IOException("Unexpected code" + response);
}
body.close();
}
});
return true;
}
What may be the possible reason?
It required me to write a simple server on localhost to find out what HTTP request was actually generated.
The problem was with colons: .header("Authorization:"resulted in Authorization:: in the network request!
After I removed colons from the header key values, both HttpUrlConnection and OkHttp code variants worked seamlessly.

How to use OKHttp with async calls and callbacks?

Investigating OKHttp and want to use as docs claims possible: "It supports both synchronous blocking calls and async calls with callbacks".
But how can I set a callback, or a chunk of code needs to execute after response received? I have not find anything on their site.
Should I nest call into an Async thread like:
AsyncTask.execute(new Runnable() {
#Override
public void run() {
//TODO your background code
From the sample
https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/AsynchronousGet.java
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
client.newCall(request).enqueue(new Callback() {
#Override public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override public void onResponse(Call call, Response response) throws IOException {
try (ResponseBody responseBody = response.body()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
Headers responseHeaders = response.headers();
for (int i = 0, size = responseHeaders.size(); i < size; i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}
System.out.println(responseBody.string());
}
}
});

How to pass body to OKHttp message?

I have found this example below to send HTTP POST message with OKHttp.
I do not understand how to pass a body string to RequestBody. Why it takes two argument?
RequestBody formBody = new FormBody.Builder()
.add("message", "Your message")
.build();
Request request = new Request.Builder()
.url("http://rhcloud.com")
.post(formBody).addHeader("operation", "modifyRecords")
.build();
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
try (ResponseBody responseBody = response.body()) {
if (!response.isSuccessful())
throw new IOException("Unexpected code " + response);
Headers responseHeaders = response.headers();
for (int i = 0, size = responseHeaders.size(); i < size; i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}
System.out.println(responseBody.string());
}
}
});
}
}
I'm not sure if I understand what you mean quite right, but if you are asking why the FormBody .add() takes two arguments, it's because these are Key-Value-Pairs. The first parameter is the name and the second the value.
Anyway I think this example shows a clearer way how to post a string:
public static final MediaType MEDIA_TYPE_MARKDOWN
= MediaType.parse("text/x-markdown; charset=utf-8");
private final OkHttpClient client = new OkHttpClient();
public void run() throws Exception {
String postBody = ""
+ "Releases\n"
+ "--------\n"
+ "\n"
+ " * _1.0_ May 6, 2013\n"
+ " * _1.1_ June 15, 2013\n"
+ " * _1.2_ August 11, 2013\n";
Request request = new Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(RequestBody.create(MEDIA_TYPE_MARKDOWN, postBody))
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
System.out.println(response.body().string());
}

Multiple OkHttp newCall not executing at once

So I will be making multiple GET requests and would love for them to execute all at once. However, as it is right now I have to hit the sign in button twice for the second newCall to go off. I would prefer if more newCall went off. But looking at it, the second newCall needs the response from the first one before it can. Is there a way that once the first gets the response, the second one executes instead of having to hit the sign in button twice?
Button code:
SignInButton signInButton = (SignInButton) findViewById(R.id.sign_in_button);
signInButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (authPreferences.getUser() != null && authPreferences.getToken() != null) {
System.out.println(authPreferences.getToken());
doCoolAuthenticatedStuff();
try {
run();
} catch (Exception e) {
e.printStackTrace();
}
//new RetrieveFeedTask().execute();
} else {
chooseAccount();
}
}
});
run() code
public void run() throws Exception {
Request request = new Request.Builder()
.url(API_URL + authPreferences.getToken())
.build();
client.newCall(request).enqueue(new Callback() {
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
Headers responseHeaders = response.headers();
for (int i = 0, size = responseHeaders.size(); i < size; i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}
try
{
String token = response.body().string();
JSONObject json = new JSONObject(token);
commatoken = json.getString("access_token");
} catch (JSONException e)
{
}
// commatoken = response.body().string();
// System.out.println(commatoken);
}
});
final Request dataRequest = new Request.Builder()
.header("content-type", "application/x-www-form-urlencoded")
.header("authorization", "JWT "+ commatoken)
.url(ChffrMe_URL).build();
client.newCall(dataRequest).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response responseMe) throws IOException {
if (!responseMe.isSuccessful()) throw new IOException("Unexpected code " + responseMe);
Headers responseHeaders = responseMe.headers();
for (int i = 0, size = responseHeaders.size(); i < size; i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}
try
{
String myInfo = responseMe.body().string();
JSONObject json = new JSONObject(myInfo);
commaMyInfo = json.getString("points");
} catch (JSONException e)
{
}
runOnUiThread(new Runnable() {
#Override
public void run() {
responseView.setText("Comma Points: " +commaMyInfo);
}
});
//responseView.setText(responseMe.body().string());
//System.out.println(responseMe.body().string());
}
});
}

Categories

Resources