REST Application - I don't receive the error from server in case of insucess - the output displays only if the request is successfull - rest

I have the next problem: I've made a simple application which retrieves information from a server (GET Method). The application works fine as long as the information is retrieved successfully.
In case of insuccess, I don't receive the error from the server (ex: 401 - Unauthorized, 403 - Forbidden - when the authentication token is incorrect for example).
How can I fix this so that my application will return the error from server ? I've done also a POST method and there it's working, I received all erorrs froem server in case of insuccess.
What i'm doing wrong with this code ? Why i don't receive an error in case of insuccess?
The only error I receive in output is 400 in all scenarios and this isn't enough.
For example, if the authorization token is incorrect, I should receive from server 401 - Unauthorized. I know this because i'm doing test with other REST application (like POSTMAN). Can it be fixed to show the errors related to that scenarios ?
void example2() {
// GET METHOD !
try {
String webPage = "https://www.clients.ro";
String name = "user";
String password = "pass";
String authString = name + ":" + password;
System.out.println("Decoded authorization token" + authString);
//byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
//String authStringEnc = new String(authEncBytes);
byte[] authEncBytes = authString.getBytes(StandardCharsets.UTF_8);
String authStringEnc = DatatypeConverter.printBase64Binary(authEncBytes);
System.out.println("Token encoded in Base64 " + authStringEnc);
URL url = new URL(webPage);
URLConnection urlConnection = url.openConnection();
urlConnection.setRequestProperty("Authorization", "Basic " + authStringEnc);
InputStream is = urlConnection.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
int numCharsRead;
char[] charArray = new char[1024];
StringBuffer sb = new StringBuffer();
while ((numCharsRead = isr.read(charArray)) > 0) {
sb.append(charArray, 0, numCharsRead);
}
String result = sb.toString();
System.out.println(result);
System.out.println();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

Related

Submitting POST request to Facebook Messenger API

I'm struggling to connect to the Facebook Messenger API. The server keeps returning:
The remote server returned an error: (400) Bad Request.
I've been at this for a few days, tried multiple methods, even tried a few VS packages that don't quite work. I've checked my Auth Token several times, and I don't know what else it might be.
Is there something obvious that's causing a bad request? I've copied the root URL from Facebook's API page. The token in the code below has been removed. The application throws an exception when I attempt to read the response. (WebResponse FBresponse = FBrequest.GetResponse();)
private string FBSendMessage(string user, string message)
{
string result = null;
string FBroot = "https://graph.facebook.com/v2.6/me/messages?access_token=";
string token = "EAA...DZD";
string FBURI = FBroot + token;
string FBstring = "{ \"recipient\": { \"id\":\"" + user + "\" }, \"message\": { \"text\":\"" + message + "\" } }";
try
{
//using (WebClient FBclient = new WebClient())
//{
// result =
// FBclient.UploadString(FBURI, FBstring);
//}
HttpWebRequest FBrequest = (HttpWebRequest)WebRequest.Create(FBURI);
FBrequest.Credentials = CredentialCache.DefaultCredentials;
FBrequest.ProtocolVersion = HttpVersion.Version11;
FBrequest.Method = "POST";
FBrequest.ContentType = "application/json";
byte[] FBbytes = Encoding.UTF8.GetBytes(FBstring);
FBrequest.ContentLength = FBbytes.Length;
Stream FBstream = FBrequest.GetRequestStream();
FBstream.Write(FBbytes, 0, FBbytes.Length);
FBstream.Close();
WebResponse FBresponse = FBrequest.GetResponse();
Output((((HttpWebResponse)FBresponse).StatusDescription), Log.Error);
FBstream = FBresponse.GetResponseStream();
StreamReader FBreader = new StreamReader(FBstream);
result = FBreader.ReadToEnd();
FBreader.Close();
FBresponse.Close();
}
catch(Exception ex)
{
Output(ex.Message, Log.Error);
}
return result;
}
I have determined that my code isn't the issue. The issue is that I'm making a request with an invalid user id. Facebook creates a user ID in the application context that isn't the same as your default user id. I have to receive a message to learn that contextualized id before I can send a message.

Google Cloud Storage XML API Policy document accessed through Google CloudEndpoint API. Lexical Error: Unmatched input

I am getting the following error
InvalidPolicyDocumentThe content of the
form does not meet the conditions specified in the policy
document.Policy document parsing error: Lexical
Error: Unmatched Input: <s>
My Async Task to call a HTTPURLConnection is below. The multipartv1 class is from here.
Inside an AsyncTask doinbackground
{multipartv1.addFormField("key", filename_insert_value);
multipartv1.addFormField("bucket", “myapplication”);
multipartv1.addFormField("Content-Type", "image/jpeg");
multipartv1.addFormField("GoogleAccessId", “myapplication#appspot.gserviceaccount.com");
multipartv1.addFormField("acl", "bucket-owner-read");
multipartv1.addFormField("success_action_redirect", "https://myapplication.appspot.com/getpolicydocumentsuccess");
multipartv1.addFormField("success_action_status", "201");
multipartv1.addFormField("x-goog-meta-programname", this.current_program_name);
multipartv1.addFormField("x-goog-meta-membername", this.member_element_id);
multipartv1.addFormField("x-goog-meta-tag1", tag1);
multipartv1.addFormField("x-goog-meta-tag2", tag2);
multipartv1.addFormField("x-goog-meta-tag3", tag3);
multipartv1.addFormField("x-goog-meta-tag4", tag4);
multipartv1.addFormField("x-goog-meta-tag5", tag5);
multipartv1.addFormField("policy", this.policy);
multipartv1.addFormField("signature", this.signature);
multipartv1.addFilePart("file", new File(this.file_absolute_path));
List<String> response_multipart = multipartv1.finish();
Log.e(Tag, "SERVER REPLIED:");
for (String line : response_multipart) {
Log.e(Tag, "Upload Files Response:::" + line);
}
The "policy" is generated from my backend (Google App Engine) using Google Cloud Endpoint API. This is as policy document supported by Google Cloud Storage XML API as listed here. The "policy" works perfectly when accessed through a Webapplication.
The "policy" looks like this -
ewkJCQoJCQkJImV4cGlyYXRpb24iOiAiMjAxNi0wNi0xNlQxMToxMToxMVoiLAoJCQkJImNvbmRpdGlvbnMiOiBbCgkJCQkJWyJzdGFydHMtd2l0aCIsICIka2V5IiwgIiIgXSwKCQkJCQl7ImFjbCI6ICJidWNrZXQtb3duZXItcmVhZCIgfSwKCQkJCQl7ImJ1Y2tldCI6ICJlbmdhZ2VkLXBhcnNlYy02MTIuYXBwc3BvdC5jb20ifSwKCQkJCQl7InN1Y2Nlc3NfYWN0aW9uX3JlZGlyZWN0Ijogc3VjY2Vzc19yZWRpcmVjdCB9LAoJCQkJCXsic3VjY2Vzc19hY3Rpb25fc3RhdHVzIjogIjIwMSJ9LAkJCQoJCQkJCVsiZXEiLCAiJENvbnRlbnQtVHlwZSIsICJpbWFnZS9qcGVnIiBdLAoJCQkJCVsic3RhcnRzLXdpdGgiLCAiJHgtZ29vZy1tZXRhLXByb2dyYW1uYW1lIiwgIiJdLAoJCQkJCVsic3RhcnRzLXdpdGgiLCAiJHgtZ29vZy1tZXRhLW1lbWJlcm5hbWUiLCAiIl0sCgkJCQkJWyJzdGFydHMtd2l0aCIsICIkeC1nb29nLW1ldGEtdGFnMSIsICIiXSwKCQkJCQlbInN0YXJ0cy13aXRoIiwgIiR4LWdvb2ctbWV0YS10YWcyIiwgIiJdLAoJCQkJCVsic3RhcnRzLXdpdGgiLCAiJHgtZ29vZy1tZXRhLXRhZzMiLCAiIl0sCgkJCQkJWyJzdGFydHMtd2l0aCIsICIkeC1nb29nLW1ldGEtdGFnNCIsICIiXSwKCQkJCQlbInN0YXJ0cy13aXRoIiwgIiR4LWdvb2ctbWV0YS10YWc1IiwgIiJdLAoJCQkJCVsiY29udGVudC1sZW5ndGgtcmFuZ2UiLCAwLCAzMDAwMDAwMF0KCQkJCQldCQkJCQoJCQkJfQ==
My fear is when I add the parameter for "policy" in my HttpURLConnection, something is messed up. The code to add the "policy" parameter is this -
public void addFormField(String name, String value) {
writer.append("--" + boundary).append(LINE_FEED);
writer.append("Content-Disposition: form-data; name=\"" + name + "\"")
.append(LINE_FEED);
writer.append("Content-Type: text/plain; charset=" + charset).append(
LINE_FEED);
writer.append(LINE_FEED);
writer.append(value).append(LINE_FEED);
writer.flush();
}
The HTTP Post call is here -
public List<String> finish() throws IOException {
List<String> response = new ArrayList<String>();
writer.append(LINE_FEED).flush();
writer.append("--" + boundary + "--").append(LINE_FEED);
writer.close();
// checks server's status code first
int status = httpConn.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpConn.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
response.add(line);
}
reader.close();
httpConn.disconnect();
} else {
throw new IOException("Server returned non-OK status: " + status);
}
return response;
}
The boundary string is this
String boundary = "===" + System.currentTimeMillis() + "===";

BOX API:how to get location attribute in response using https://api.box.com/2.0/files/{fileId}/content for downloading

My code is given below
WebResource webResource1 = cl.resource("https://api.box.com/2.0/files/{fileId}/content");
ClientResponse res1 = webResource1.header("Authorization", "Bearer"+p1.getAccess_token()).get(ClientResponse.class);
String jsonStr1 = res1.getEntity(String.class);
And my response is given below-
{Object-Id=[file_20317568941], Cache-control=[private], Date=[Wed, 24 Sep 2014 12:11:43 GMT], Content-Length=[27], X-Robots-Tag=[noindex, nofollow], Content-Disposition=[attachment;filename="upload.txt";filename*=UTF-8''upload.txt], Accept-Ranges=[bytes, bytes], Connection=[keep-alive], Content-Type=[text/plain; charset=UTF-8], Server=[nginx], X-Content-Type-Options=[nosniff]}
I am getting status code 200, OK; but to get the location attribute I need to have the status code 302 along with the location url (https://dl.boxcloud.com/*).
Without getting location: https://dl.boxcloud.com/* attribute in the response, how can I download file from box api?
last Saturday I got some time to look into your issue. The basic problem is that if you need to get the Location value you need to stop the automatic redirection. Following is the explanation & solutions of your problem:
Quoting Box API docs of Download a File:
If the file is available to be downloaded, the response will be a 302
Found to a URL at dl.boxcloud.com.
From Wikipedia article on HTTP 302:
The HTTP response status code 302 Found is a common way of performing
URL redirection.
An HTTP response with this status code will additionally provide a URL
in the Location header field. The user agent (e.g. a web browser) is
invited by a response with this code to make a second, otherwise
identical, request to the new URL specified in the Location field.
So to get the Location attribute in the response header you need to stop the automatic redirection. Otherwise as per the box doc you will get the raw data of the file instead of the download URL.
Following is a solution implemented using Commons HTTPClient:
private static void getFileDownloadUrl(String fileId, String accessToken) {
try {
String url = MessageFormat.format("https://api.box.com/2.0/files/{0}/content", fileId);
GetMethod getMethod = new GetMethod(url);
getMethod.setFollowRedirects(false);
Header header = new Header();
header.setName("Authorization");
header.setValue("Bearer " + accessToken);
getMethod.addRequestHeader(header);
HttpClient client = new HttpClient();
client.executeMethod(getMethod);
System.out.println("Status Code: " + getMethod.getStatusCode());
System.out.println("Location: " + getMethod.getResponseHeader("Location"));
} catch (Exception cause) {
cause.printStackTrace();
}
}
An alternate solution using java.net.HttpURLConnection:
private static void getFileDownloadUrl(String fileId, String accessToken) {
try {
String serviceURL = MessageFormat.format("https://api.box.com/2.0/files/{0}/content", fileId);
URL url = new URL(serviceURL);
HttpURLConnection connection = HttpURLConnection.class.cast(url.openConnection());
connection.setRequestProperty("Authorization", "Bearer " + accessToken);
connection.setRequestMethod("GET");
connection.setInstanceFollowRedirects(false);
connection.connect();
int statusCode = connection.getResponseCode();
System.out.println("Status Code: " + statusCode);
Map<String, List<String>> headerFields = connection.getHeaderFields();
List<String> locations = headerFields.get("Location");
if(locations != null && locations.size() > 0) {
System.out.println("Location: " + locations.get(0));
}
} catch (Exception cause) {
cause.printStackTrace();
}
}
Since Commons HTTPClient is outdated the following solution is based on the Apache HttpComponents:
private static void getFileDownloadUrl(String fileId, String accessToken) {
try {
String url = MessageFormat.format("https://api.box.com/2.0/files/{0}/content", fileId);
CloseableHttpClient client = HttpClientBuilder.create().disableRedirectHandling().build();
HttpGet httpGet = new HttpGet(url);
BasicHeader header = new BasicHeader("Authorization", "Bearer " + accessToken);
httpGet.setHeader(header);
CloseableHttpResponse response = client.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
System.out.println("Status Code: " + statusCode);
org.apache.http.Header[] headers = response.getHeaders(HttpHeaders.LOCATION);
if(header != null && headers.length > 0) {
System.out.println("Location: " + headers[0]);
}
} catch (Exception cause) {
cause.printStackTrace();
}
}

Restful URL custom authentication failing in java

This code is for getting the text from some URL which is having custom authentication as specified below.Tried with even ajax and Jquery as dataType:"jsonp" but it is also showing 401 error.
URL u;
HttpURLConnection con;
InputStream is = null;
DataInputStream dis;
String s;
try {
// u = new URL("http://q.addthis.com/feeds/1.0/trending.json?pubid=atblog");
u = new URL("http://m2mportal.connectm.com/EMS/rest/device");
is = u.openStream();
con=(HttpURLConnection) u.openConnection();
con.connect();
con.setDoOutput(true);
con.setRequestMethod("GET");
con.setRequestProperty("Accept","application/json");
con.setRequestProperty("Authorization","authenticate\":{\"userName\":\"admin01\",\"password\":\"admin01$\",\"appId\":\"123\"}");
con.setRequestProperty("userName","admin01");
con.setRequestProperty("password","admin01$");
con.setRequestProperty("appId","123");
dis = new DataInputStream(new BufferedInputStream(is));
while ((s = dis.readLine()) != null)
{
System.out.println(s);
}
}
catch (MalformedURLException mue)
{
System.out.println("Ouch - a MalformedURLException happened.");
mue.printStackTrace();
System.exit(1);
}
catch (IOException ioe)
{
System.out.println("Oops- an IOException happened.");
ioe.printStackTrace();
System.exit(1);
}
catch(IllegalStateException ise)
{
System.out.println("In IllegalState Exception........");
ise.printStackTrace();
}
When tried to authenticate against a url which is having some custom authentication as shown in the code it is returning 401 error
Oops- an IOException happened.
java.io.IOException: Server returned HTTP response code: 401 for URL: some url
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1625)
at java.net.URL.openStream(URL.java:1037)
at com.techm.JavaGetUrl.main(JavaGetUrl.java:16)
Java Result: 1
Actually problem here is Authorization property that you passed is not encoded.
You need to pass it to Base64 encoder so that http Authorization mechanism will use it.
Base64 encoding is commonly used when there is a need to encode / decode binary data stored and transferred over network.
Add encoding to your code . change your code to :
you need to use
Base64.encodeToString()
to perform encoding.
Following link will help you more:
http://www.javatips.net/blog/2011/08/how-to-encode-and-decode-in-base64-using-java

REST Services - JSON deserialization error: Encountered unexpected character '<'

public async void MakeRequest(string requestUrl)
{
try
{
HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
using (HttpWebResponse response = await request.GetResponseAsync() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception(string.Format(
"Server error(HTTP {0}:{1}.",
response.StatusCode,
response.StatusDescription));
DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(RootObject));
object objResponse = jsonSerializer.ReadObject(response.GetResponseStream());
root = (RootObject)objResponse;
if (root == null)
this.Frame.Navigate(typeof(MainPage));
}
}
catch (Exception ex)
{
ThrowException(ex);
}
}
Link : http://dev.virtualearth.net/REST/V1/Routes?wp.0=39.920829,32.853883&wp.1=39.877666,32.864728&key=BingMapsKey
Is there anything wrong in my in the codes above?
Just change this line for make the query with JSON and not XML format
So from this ...
string query = "http://dev.virtualearth.net/REST/v1/Locations/" +
queryString + "?output=xml" + " &key=" + BingMapsKey;
To this ...
string query = "http://dev.virtualearth.net/REST/v1/Locations/" +
queryString + "?output=json" + " &key=" + BingMapsKey;
i.e. just change output=xml to output=json
This code is working fine for me once I replace the undefined RootObject in your code with the BingMapsRESTService.Common.JSON.Response type found in the Bing Maps REST Service .NET Libraries that #rbrundritt suggested you use in your other post