Today I started developing a new Android app which is based on the Windows Azure Mobile Services.
I've tried to use the SDK provided by Microsoft for the whole day, without any success. Every time the app performs a web request, this one returns a 400, BAD REQUEST code.
I go to a lower level, with the following code.
URL url = new URL("https://xxxx.azure-mobile.net/api/contents"); //host obscured
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setDoInput(true);
//I obscure the authentication and app key, but they are correct in the program
conn.addRequestProperty("AUTHORIZATION", "Basic xxxxxxxxxxxxxxx");
conn.addRequestProperty("X-ZUMO-APPLICATION", "xxxxxxxxxxxxxxxx");
conn.addRequestProperty("ACCEPT", "application/json");
//connect
conn.connect();
int code = conn.getResponseCode(); //400 in the emulator, 200 in a standard java code
String message = conn.getResponseMessage();
InputStream is = conn.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String read = null;
StringBuilder sb = new StringBuilder();
do {
//Read the content
read = br.readLine();
sb.append(read);
} while(read != null);
//print the content
System.out.println(sb.toString());
//Close the buffers
br.close();
isr.close();
is.close();
System.out.println("Status Code: "+code);
System.out.println(message);
conn.disconnect();
It works perfectly in a standard java application, but in the emulator I still get 400 BAD REQUEST. I really do not understand why!
Maybe an issue of the emulator?
I was running an Android Emulator with API 10.
I'd like to try the code on a real device, but the mac does not recognize it... And the device worked until yesterday since I debugged an application with it.
If you know what I am doing wrong, please help me.
EDIT 20-03-2014:
I made some other attempts. I tried with the HttpClient API. No luck.
I'm still getting 400 as response code and Bad Request as response Message.
The thrown Exception is UnknownHostException... But the InetAddress.getByName(); successfully get an IP address for my web service.
The app still work with Android version greater than 4, I have not tried with Android 3.
I'm very sad and frustrated...
Thank you for your time,
Rik.
SOLVED
Oddly, the problem was in the AUTHENTICATION header.
I computed the header with the following code:
public setHeader(String code, String username)
{
StringBuilder sb = new StringBuilder(username);
sb.append(":");
sb.append(code);
sb = new StringBuilder(Base64.encodeToString(sb.toString().getBytes(), Base64.DEFAULT));
sb.insert(0, "Basic ");
auth = sb.toString();
}
The Base64.encodeToString() method adds a \n at the end of the line. .__.
By adding a trim() in the last line, I threw away the new line and everything went fine in both 2.3.3 and 4 Android versions.
Related
I have a dialogflow project that I'm trying to access from Java with a rest call.
It is giving me an authentication issue.
I have followed all online instructions (and many forum suggestions) to no avail.
I have tried generating the key json, as per the instructions here:
https://dialogflow.com/docs/reference/v2-auth-setup
and setting my environment variable as described, but nothing seems to work.
I have checked my projectID, and am running off the same machine with the environment variable, and have double, triple and quadruple checked it's name and location, but I still get the following error:
java.net.HttpRetryException: cannot retry due to server authentication, in streaming mode
Here is my code (though it's a REST call, so I don't know if it's so relevant):
String url = https://dialogflow.googleapis.com/v2/projects/MYPROJECT/agent/sessions/SESSION_NUM:detectIntent
URL url = new URL(full_url);
String inText = "Hello World";
String outText = "";
HttpURLConnection con = (HttpURLConnection) url.openConnection();
try {
con.setDoOutput(true);
con.setRequestMethod("POST");
// set body of http post
Map<String,String> arguments = new HashMap<>();
JSONObject inTextJsn = new JSONObject();
inTextJsn.append("text",inText);
inTextJsn.append("languageCode","en");
JSONObject fieldJsn = new JSONObject();
fieldJsn.append("text", inTextJsn);
arguments.put("queryInput", fieldJsn.toString());
StringJoiner sj = new StringJoiner("&");
for(Map.Entry<String,String> entry : arguments.entrySet())
sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "="
+ URLEncoder.encode(entry.getValue(), "UTF-8"));
// post http post as bytes
byte[] bytes_out = sj.toString().getBytes(StandardCharsets.UTF_8);
con.setFixedLengthStreamingMode(bytes_out.length);
con.connect();
try (OutputStream os = con.getOutputStream()) {
os.write(bytes_out);
}
BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream(),
"UTF-8"));
// read all lines to a string
String line;
String response = "";
while ((line = reader.readLine()) != null) {
response += line;
}
JSONObject responseJsn = new JSONObject(response);
outText = responseJsn.get("fulfillmentText").toString();
} catch (Exception e) {
System.err.println(e);
} finally {
con.disconnect();
}
return restResponse;
The gist of the code is to simply send a message ("Hello World!") to my dialogflow, and get back my agent's response (the code may have bugs - it's a bit hard to test when I can't get passed this authentication issue, so please help with the authentication, not code bugs).
Thanks all!
The directions at that page assume you're going to use the gcloud program to generate a currently valid bearer token, which is then sent along with the HTTP headers. That page illustrates
Your code doesn't seem to be generating an Authorization HTTP header at all, which is why you're getting the error you do.
Since you're using Java, you should look at the google-auth-library-java library, which will give you the tools to generate the token you need to provide in the Authorization header.
You may also wish to check out the google-cloud-java library. This contains Java classes to directly perform operations against Dialogflow instead of coding the REST/HTTP calls yourself. (However, it is still at an Alpha level for Dialogflow, so may not be stable or forwards compatible.)
I am doing an desktop application using Java that can send SMS to a multiple phone numbers via browser. To send the SMS, I need to put in parameters that username, password, message to be sent and the recipient's number.
I have used this and it worked but the problem is it opens up a browser to every recipient so it is not advisable especially if its going to be sent to a lot:
Runtime rt = Runtime.getRuntime();
String url = String.format("http://www.companysms.com/RemoteAPI/SendSMS.aspx?username=%s&encoding=url&password=%s&messagedata=%s&receiver=%s&binary=0", txtUsername.getText(),txtPassword.getText(), txtMessage.getText(),tblMessage.getValueAt(i, 2));
rt.exec("rundll32 url.dll,FileProtocolHandler "+ url);
I have tried this one too but it gives me the HTTP response code 400:
HttpURLConnection connection = (HttpURLConnection) myURL.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.connect();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder results = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
results.append(line);
}
connection.disconnect();
If I use the URLencoder with "UTF-8", it makes it worse because i cant be sure of what the message the user will send and if they will use any of the special characters. Is there a way to have the first set of codes that I used to not open browser after sending the SMS or is there another way of doing this? Any help is appreciated. Thanks!
I'm using HttpURLConnection to send JSON data from an Android Application to my Tomcat Server.
The POST works fine with small sized JSONs. On bigger data sets it fails with a FileNotFoundException.
What can it be?
Here's the code:
try {
URL url = new URL(urlIn);
strOut = "";
huc = (HttpURLConnection) url.openConnection();
huc.setRequestProperty("Connection", "Close");
huc.setRequestMethod("POST");
huc.setRequestProperty("User", userId);
huc.setRequestProperty("Action", action);
huc.setRequestProperty("JSON", jsonData);
huc.setConnectTimeout(10000);
in = new BufferedReader(new InputStreamReader(huc.getInputStream()));
while ((inputLine = in.readLine()) != null){
if (strOut.equalsIgnoreCase("")){
strOut = inputLine;
} else {
strOut = strOut + inputLine;
}
}
} catch (Exception e) {
strOut = "";
e.printStackTrace();
}
When jsonData get to a certain size (arround 10000 chars), the POST fails with the error mentioned. The content of the JSON does not have any special character.
Thanks in advance.
Best regards, Federico.
HTTPUrlConnection throws a FileNotFoundException if the server responds with a 404 response code, so the reason why this happens seems to be located on the server side rather than the client side. Most likely the server is configured to accept request headers up to a particular length and will return an error if that size is exceeded. A short Google-search brought up a couple of results, sizes of 16 KB are mentioned but shorter values are also reasonable.
As I mentioned in my comment to your question, you should change your process to receive the JSON-data (and the other values for User and Action as well BTW) as part of the request body, e.g. as url-encoded query string or as multipart formdata. Both ways are supported by HTTP client libraries you can use or are easily built manually.
After lots of reading and trying I gave up with configuring Tomcat to accept larger headers.
So I convinced the team in charge of the Tomcat app to make a servlet that is able to receive this data in the body, just as Lothar suggested.
Thanks!
I've been trying to query NCBI blast website using Android and BioJava. I'm using Eclipse with the Android emulator. When I run the code as an Android app I get the following errors:
W/System.err(533): java.io.IOException: An error occured submiting sequence to BLAST server. Cause: content-length promised 2000 bytes, but received 214
When I take the very same code and run it as a regular Java app it works perfectly. Any ideas on what it might be?
It also occured to me while I was trying to make a POST request in Android . If you set Content-Length in headers and the actual content has a different length, it will throw an IOException in Android (in plain JDK it worked, although it is wrong)
You can reproduce the Exception using the following code:
try {
URL oracle = new URL("http://oasth.gr/tools/lineTimes.php");
HttpURLConnection yc = (HttpURLConnection) oracle.openConnection();
yc.setRequestProperty("User-Agent",
"Mozilla/5.0 (X11; Linux i686; rv:2.0b12) Gecko/20110222 Firefox/4.0b12");
yc.setRequestProperty("Referer",
"http://oasth.gr/tools/lineTimes.php");
yc.setRequestProperty("Accept-Language",
"el-gr,el;q=0.8,en-us;q=0.5,en;q=0.3");
yc.setRequestProperty("Accept-Charset",
"ISO-8859-7,utf-8;q=0.7,*;q=0.7");
// content length should be 29 !!
yc.setRequestProperty("Content-Length", "1000");
// content length is 29 !
String parames = "bline=63&goes=a&lineStops=886";
yc.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(yc.getOutputStream());
wr.write(parames);
wr.flush();
Log.d(TAG, "" + yc.getResponseCode());
BufferedReader in = new BufferedReader(new InputStreamReader(
yc.getInputStream()));
String inputLine;
StringBuilder sbu = new StringBuilder();
while ((inputLine = in.readLine()) != null)
sbu.append(inputLine);
wr.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
Log.e("getLinesArrival Exception", e.getMessage());
}
so if you remove line
yc.setRequestProperty("Content-Length", "1000");
it will work!
My httpURLConnection fails with 404 - Resource not Found error. The same URL works on my firefox poster and returns 200/ok. Both the applications(webapp and the URL-app) are located on the same machine. I found from another thread that I need to add below 2 lines to make it work when the same URL works from browser-
urlConnection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
urlConnection.setRequestProperty("Accept","/");
Unfortunately adding above lines didn't fix the problem. Am I doing anything wrong in the code below ? Any useful suggestions will be much appreciated.
{
String computerName = InetAddress.getLocalHost().getHostName();
url = new URL("http://"+computerName+":8080"+"/cerprovider/devices");
urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setDefaultUseCaches(false);
urlConnection.setUseCaches(false);
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.setRequestProperty("Connection", "Keep-Alive");
urlConnection.setRequestProperty("Content-Length", Integer.toString(Integer.MAX_VALUE));
urlConnection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
urlConnection.setRequestProperty("Accept","*/*");
urlConnection.setConnectTimeout(500);
// Create I/O streams
outStream = new DataOutputStream(urlConnection.getOutputStream());
//inStream = new DataInputStream(urlConnection.getInputStream());
// Send request
outStream.writeBytes(<blah>.toString());
outStream.flush();
outStream.close();
BufferedReader in = null;
String responseErrorString = "";
_tracer.info("Response code --"+urlConnection.getResponseCode());
InputStream error = urlConnection.getErrorStream();
_tracer.info("Error from the connection --"+error.toString());
StringBuilder buf = new StringBuilder();
for(int c = -1; (c = error.read()) != -1; )
buf.append((char)c);
responseErrorString = new String (buf);
_tracer.info("responseErrorString--"+responseErrorString);
}
try to send request again. In my project I am using Apache HttpClient to send request & many times the 404 error resolve by sending request again. (but not all the time)
Also use httpfox plugin on firefox to check what exactly happening when u send request.
404 error is supposed to b for 'resource temporarily not available'.