How to query Github graphql API with java using HttpUrlConnect - java

I don't know what is wrong with my code I keep getting error 401 when I try making a request to the GitHub. My app uses the REST API before now I and to convert it to the Graphql but I am finding it difficult
private static String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
// If the URL is null, then return early.
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.setRequestProperty("Authorization","Bearer token");
urlConnection.setRequestProperty("Content-Type", "application/json");
DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
wr.writeBytes("{\"query\":\"query{search(type:USER query:\"location:lagos language:java\"){userCount}}}");
wr.flush();
wr.close();
int rc = urlConnection.getResponseCode();
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the earthquake JSON results.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
}
return jsonResponse;
}

Found the mistake
There was a problem with my token and the query format was wrong it should have been
"{\"query\": \"query { search ( type : USER, query : \\\"location:lagos\\\" ) { userCount }}\"}"
Thank for your suggestion

The Authorization header token might not be valid. HTTP 401 = not authorized.

I'd suggest trying to make same request with a Curl and when you see success - apply same parameters/headers to HttpUrlConnection.

Related

Can't send JSON in a Java HTTP POST request

I'm getting a 'Server returned HTTP response code: 500' error although I have checked what I'm sending (I even tried sending it with an online tool and it worked). The API Key and the JSON are correct. I get this error when trying to read the input stream with 'connection.getInputStream()'. Where could this be comming frome ? Did I forget something ? I am trying to implement this feature from the openrouteservice API : https://openrouteservice.org/dev/#/api-docs/v2/directions/{profile}/post
public static UPSRoute getRoute(Location start, Location end, String language) {
if (language.equals("fr")) {
JSONObject jsonObject = null;
try {
URL url = new URL("https://api.openrouteservice.org/v2/directions/foot-walking");
String payload = "{\"coordinates\":[[" + start.getCoordinates() + "],[" + end.getCoordinates() + "]],\"language\":\"fr\"}";
System.out.println(payload); //{"coordinates":[[1.463478,43.562038],[1.471717,43.560787]],"language":"fr"}
byte[] postData = payload.getBytes(StandardCharsets.UTF_8);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Authorization", API_KEY);
connection.setRequestProperty("Accept", "application/json, application/geo+json, application/gpx+xml, img/png; charset=utf-8");
connection.setDoOutput(true);
try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) {
wr.write(postData);
}
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); // Error is right here
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
connection.disconnect();
jsonObject = new JSONObject(content.toString());
} catch (IOException | JSONException e) {
e.printStackTrace();
}
return new UPSRoute(jsonObject);
} else {
return getRoute(start, end);
}
}
Here is the error :
java.io.IOException: Server returned HTTP response code: 500 for URL: https://api.openrouteservice.org/v2/directions/foot-walking/json
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1913)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1509)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:245)
at UPSRouteService.getRoute(UPSRouteService.java:63)
at Main.main(Main.java:5)
Thanks to Andreas, it was just missing the line :
connection.setRequestProperty("Content-Type", "application/json");
It works fine now.

Getting Null response From Async task With Response code 200 which means Success

When I Debug my code get Response code 200 which means success. Then also I'm getting null response.
Following is my AsyncTask Class:
private class AsyncAddfriend extends AsyncTask<String, String, String> {
HttpURLConnection conn;
URL url = null;
#Override
protected String doInBackground(String... params) {
try {
url = new URL("http://ishook.com/users/friends/send_friend_request_json/");
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
conn = (HttpURLConnection)url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
Uri.Builder builder = new Uri.Builder()
.appendQueryParameter("sessionId", params[0])
.appendQueryParameter("UserId", params[1])
.appendQueryParameter("friendId", params[2]);
String query = builder.build().getEncodedQuery();
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(query);
writer.flush();
writer.close();
os.close();
conn.connect();
} catch (IOException e) {
e.printStackTrace();
}
try {
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
// Pass data to onPostExecute method
return(result.toString());
}else{
return("unsuccessful");
}
} catch (IOException e) {
e.printStackTrace();
return "exception";
} finally {
conn.disconnect();
}
}}
I have Tested My API in postman its Working with response code 200 and giving Response in json format but in my code its not working .
Hope you will understand my problem.
Thank you very much for your time and assistance in this matter.
The problem is probably from this line:
String query = builder.build().getEncodedQuery();
You need to use:
String query = builder.build().toString();
This is because getEncodedQuery() is only returning the query, from the documentation:
String getEncodedQuery ()
Gets the encoded query component from this URI. The query comes after the query separator ('?') and before the fragment separator ('#'). This method would return "q=android" for "http://www.google.com/search?q=android".
UPDATED
You're building the query after opening the connection, hence you having the error.
You need to build the url with the query first:
Uri uri = Uri.parse("http://ishook.com/users/friends/send_friend_request_json/")
.buildUpon()
.appendQueryParameter("sessionId", params[0])
.appendQueryParameter("UserId", params[1])
.appendQueryParameter("friendId", params[2]);
.build();
URL url = new URL(builtUri.toString());
conn = (HttpURLConnection)url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.connect();
Note: I haven't test the code. So, don't expected it working automagically.

HttpURLConnection always failing with 401

I'm trying to use HttpURLConnection for connecting to server from Android app which I'm developing. For now, I'm testing the connection code not in an app but as a plain java program with main class. I guess this doesn't make any difference as far as HttpUrlConnection.
Please examine the code snippet. Another issue is even errorStream is throwing null. This I feel is because of malformed URL.
private static String urlConnectionTry() {
URL url; HttpURLConnection connection = null;
try {
String urlParameters = "email=" + URLEncoder.encode("email", "UTF-8") +
"&pwd=" + URLEncoder.encode("password", "UTF-8");
//Create connection
url = new URL("http://example.com/login");
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setRequestProperty("uuid", getUuid());
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(true);
//Send request
DataOutputStream wr = new DataOutputStream (
connection.getOutputStream ());
wr.writeBytes (urlParameters);
wr.flush ();
wr.close ();
//Get Response
InputStream is = connection.getErrorStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
return response.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if(connection != null) {
connection.disconnect();
}
}
}
private static String getUuid() {
try {
Document doc=Jsoup.connect("http://example.com/getUuid").get();
Elements metaElems = doc.select("meta");
for (Element metaElem : metaElems) {
if(metaElem.attr("name").equals("uuid")) {
return metaElem.attr("content");
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
You're probably receiving 401 because the credentials that was sent to the server is not authorized- it's probably not registered or the password is incorrect.
As for the null error stream, take a look at this SO answer.
If the connection was not connected, or if the server did not have an error while connecting or if the server had an error but no error data was sent, this method will return null.
It is probably better if you check first the response code using HttpUrlConnection#getResponseCode(). Decide on whether you'll be checking the contents of the error stream based on the response code you get.

Unexpected status line when making post request from android device

Hi I have an Android app that needs to connect to an API (currently running locally) to authenticate the user, so I'm trying to send a POST request with a JSON object as the request body but whenever I try to login I get the following error:
Unexpected status line: ��
java.net.ProtocolException: Unexpected status line: ��
Here's my code:
String API_URL = "http://10.0.2.2:8443/api/";
try {
URL url = new URL(API_URL);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.connect();
JSONObject jsonObject = new JSONObject();
jsonObject.put("customerId", 1);
jsonObject.put("password" , mPassword);
jsonObject.put("username" , mEmail);
DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
wr.writeBytes(jsonObject.toString());
Log.d("REQUEST BODY", jsonObject.toString());
wr.flush();
wr.close();
int response = urlConnection.getResponseCode();
Log.d("RESPONSE", String.valueOf(response));
if(response == HttpURLConnection.HTTP_OK) {
InputStream bis = new BufferedInputStream(urlConnection.getInputStream());
return getStringFromInputStream(bis);
}
}
finally{
urlConnection.disconnect();
}
}
catch(Exception e) {
Log.e("ERROR", e.getMessage(), e);
return null;
}
Can anyone please tell me what I might be doing wrong? Thanks!
EDIT
Not sure if this helps but the problem seems to occur when I call urlConnection.getResponseCode();.
Possibly you are recycling the connection
try adding urlConnection.setRequestProperty("Connection", "close"); before connecting

HttpURLConnection 403 response after 200

Ok so I'm working on an app with 2 activities.
Let's call the 1st one LoginActivity which appears on top of my MainActivity. Also, I have a class SenderReceiver which extends AsyncTask that takes care of the connection to my https server.
The 1st time I call SenderReceiver from my LoginActivity, everything works fine & I get a 200 response & I'm able to use the JSON retrieved.
After that, the LoginActivity finishes & returns a result to the MainActivity. This is when I know I'm logged in & I can proceed.
Now whenever I execute SenderReceiver to get other information, I get the 403 response with a java.io.FileNotFoundException: https://url_of_my_server. But if I call the login again, it works.
Below is the SenderReceiver code snippet which connects to the server.
I'm also connecting to the same server on the iOS version of the app & never have issues with subsequent calls after the login.
Now this is my 1st time using https connections & such, I'm not really sure how it works on Android so I must be missing something or doing something wrong.
#Override
protected Boolean doInBackground(Object... params) {
frag = (Fragment)params[0]; // For later
addedParams = (List<NameValuePair>)params[1];
postPage = (String)params[2];
InputStream is = null;
try {
URL url = new URL(Constants.kWebService);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setReadTimeout(15000);
conn.setConnectTimeout(20000);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
//conn.setDoInput(true);
conn.setRequestProperty("CONTENT_TYPE", "application/json");
conn.setRequestProperty("X-requested-with", "XMLHttpRequest");
String base64EncodedCredentials = "Basic " + Base64.encodeToString((Constants.kHTTPSUser+":"+Constants.kHTTPSPass).getBytes(), Base64.NO_WRAP);
conn.setRequestProperty("Authorization", base64EncodedCredentials);
String param = "page="+postPage+"&";
for(int i = 0; i < addedParams.size(); i++) {
String and = (i < addedParams.size()-1)? "&": "";
param += addedParams.get(i).getName()+"="+ URLEncoder.encode(addedParams.get(i).getValue(), "UTF-8")+and;
}
conn.setFixedLengthStreamingMode(param.getBytes().length);
PrintWriter out = new PrintWriter(conn.getOutputStream());
out.print(param);
out.close();
// Starts the query
conn.connect();
int responseCode = conn.getResponseCode();
is = conn.getInputStream();
// Convert the InputStream into a string
responseSTR = Constants.inputStreamToString(is).toString();
return true;
// Makes sure that the InputStream is closed after the app is
// finished using it.
} catch (ProtocolException pe) {
Constants.Log("Protocol Exception:"+pe.getMessage());
} catch (IOException io) {
Constants.Log("IO Exception:"+io.getMessage());
io.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException io) {
Constants.Log("is.close IO Exception:"+io.getMessage());
}
}
}
return false;
}
Fixed it!
All I had to do was to set the cookie header with:
conn.setRequestProperty("Cookie", Constants.kCookies);
& retrieve that cookie after the response in order to set it with:
List<String> cookies = conn.getHeaderFields().get("Set-Cookie");
if(cookies != null) {
Constants.kCookies = cookies.get(0);
}
That way in the initial HttpURLConnection connections (i.e:login) the cookie is empty & not needed. Once a connection is successful (after "login") it receives the cookie & sets it.
After that, any subsequent connection sends that cookie as part of the header.
The updated method below:
#Override
protected Boolean doInBackground(Object... params) {
frag = (Fragment)params[0];
addedParams = (List<NameValuePair>)params[1];
postPage = (String)params[2];
InputStream is = null;
try {
URL url = new URL(Constants.kWebService);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setReadTimeout(15000);
conn.setConnectTimeout(20000);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
//conn.setDoInput(true);
conn.setRequestProperty("CONTENT_TYPE", "application/json");
conn.setRequestProperty("X-requested-with", "XMLHttpRequest");
String base64EncodedCredentials = "Basic " + Base64.encodeToString((Constants.kHTTPSUser+":"+Constants.kHTTPSPass).getBytes(), Base64.NO_WRAP);
conn.setRequestProperty("Authorization", base64EncodedCredentials);
// Get the cookie from my Constants file & set it, Constants.kCookies is a static String
conn.setRequestProperty("Cookie", Constants.kCookies);
String param = "page="+postPage+"&";
for(int i = 0; i < addedParams.size(); i++) {
String and = (i < addedParams.size()-1)? "&": "";
param += addedParams.get(i).getName()+"="+ URLEncoder.encode(addedParams.get(i).getValue(), "UTF-8")+and;
}
conn.setFixedLengthStreamingMode(param.getBytes().length);
PrintWriter out = new PrintWriter(conn.getOutputStream());
out.print(param);
out.close();
// Starts the query
conn.connect();
int responseCode = conn.getResponseCode();
Constants.Log("The response code is: " + responseCode);
is = conn.getInputStream();
// Retrieve the cookie from the response & if not null save it to Constants.kCookies
List<String> cookies = conn.getHeaderFields().get("Set-Cookie");
if(cookies != null) {
Constants.kCookies = cookies.get(0);
}
// Convert the InputStream into a string
responseSTR = Constants.inputStreamToString(is).toString();//readIt(is, len);
return true;
// Makes sure that the InputStream is closed after the app is
// finished using it.
} catch (ProtocolException pe) {
Constants.Log("Protocol Exception:"+pe.getMessage());
} catch (IOException io) {
Constants.Log("IO Exception:"+io.getMessage());
io.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException io) {
Constants.Log("is.close IO Exception:"+io.getMessage());
}
}
}
return false;
}

Categories

Resources