I have a problem. I'm trying to execute POST method to my Node.js server. After POST method I'm getting all the data in server but then my app isn't responding a few seconds. Is there some bugs in my code?
My POST method:
public static void setTemp(String address, String hot, String cold) throws IOException
{
URL url = new URL(address); //in the real code, there is an ip and a port
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
try {
conn.connect();
JSONObject jsonParam = new JSONObject();
jsonParam.put("hot", hot);
jsonParam.put("cold", cold);
DataOutputStream os = new DataOutputStream(conn.getOutputStream());
os.writeBytes(jsonParam.toString());
os.flush();
os.close();
Log.i("STATUS", String.valueOf(conn.getResponseCode()));
Log.i("MSG" , conn.getResponseMessage());
} catch (Exception e) {
}
finally {
conn.disconnect();
}
}
This is how I call the POST method:
private void setTemp(String hot, String cold)
{
try {
WebAPI.setTemp(Tools.RestURLPost, hot, cold);
}
catch(IOException e) {
e.printStackTrace();
}
}
And here you can find my Node.js method which I use to test successful parsing of JSON:
router.post('/post', function(req, res, next) {
console.log(req.body);
});
Without seeing the whole code it's hard to know but you're never ending the request in Node, so use: req.send/json, otherwise the Android application will wait until the request is done, which won't happen and it will timeout.
router.post('/post', function(req, res, next) {
console.log(req.body);
res.json({ success: true });
});
Related
I am newbie in android programming. I have to make an app for my thesis. So i made the program and test it on VM and all was fine, but when i tried to run it on real device the program did not work. My project is to make an app that reads data from Arduino and plot them on a graph. When i test it on real device my app could not read the data. From the side of Arduino i saw that the connection was established.
Thank you for any advice-help.
MY code for connection is:
private class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
try {
return downloadContent(params[0]);
} catch (IOException e) {
return "Unable to retrieve data. URL may be invalid.";
}
}
#Override
protected void onPostExecute(String result) {
// Toast.makeText(graphActivity.this, result, Toast.LENGTH_LONG).show();
textStatus.setText(result);
// myNum= Double.parseDouble(result);
// mytime= mytime+1;
// series.appendData(new DataPoint(mytime*1d ,myNum),true,28800);
}
}
private String downloadContent(String myurl) throws IOException {
InputStream is = null;
int length = 500;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.connect();
int response = conn.getResponseCode();
Log.d(TAG, "The response is: " + response);
is = conn.getInputStream();
// Convert the InputStream into a string
String contentAsString = convertInputStreamToString(is, length);
return contentAsString;
} finally {
if (is != null) {
is.close();
}
}
}
public String convertInputStreamToString(InputStream stream, int length) throws IOException, UnsupportedEncodingException {
reader = new InputStreamReader(stream);
char[] buffer = new char[length];
reader.read(buffer);
return new String(buffer);
}
I wanted to say that the problem solved. The code runs perfect with no changes. The problem was from the arduino side. I made some changes to arduino code and BOOM... it works :D :). If someone want to use the code its ok. Runs either on AVD either on real device.
In my android application I am trying to save some data in MongoDB database. I using this code (given below) for that. This code is displaying Toast that data is saved, but the data is not present in my database. I am not getting any exception. so kindly tell what can be the problem?
Code:
#Override
protected Boolean doInBackground(String... reminder) {
try {
URL requestUrl = new URL("MongoDB address");
HttpURLConnection connection = (HttpURLConnection) requestUrl.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.connect();
OutputStream save = connection.getOutputStream();
save.write(reminder[0].getBytes());
save.close();
connection.disconnect();
new Handler(context.getMainLooper()).post(new Runnable() {
public void run() {
Toast.makeText(context, "data is saved", Toast.LENGTH_LONG).show();
}
});
}
catch(Exception exception) {
Log.e("ERROR", "DB Saving", exception);
}
return true;
}
So we're encountering a scenario where our Android clients are receiving a redirect from the server (following a POST -- Post/Redirect/Get) and Android is removing the body for the conversion to GET but seems to be leaving the Content-Length header in the GET request. I've verified that the request isn't making it into the web application (by placing a delegating handler that fires before a controller is selected). We also verified via cURL that if the content-length is removed from the request, the request goes through just fine.
So we're trying to find a solution on either front:
a) how do we stop android from sending that header? or
b) how do we tell IIS to allow or strip out the content-length header so that the request can get through?
UPDATE:
Requested java code that makes the call, as requested...
OutputStream postOut = null;
HttpURLConnection connection = null;
try {
URL url = new URL("<<url here>>");
connection = (HttpURLConnection) url.openConnection();
final String method = "POST";
final String data = "name=frank";
final String contentType = "application/x-www-form-urlencoded";
connection.setDoInput(true);
connection.setRequestProperty("Accept", contentType);
connection.setRequestProperty("Connection", "Close");
connection.setRequestProperty("Content-Type", contentType);
connection.setRequestMethod(method);
connection.setConnectTimeout(0);
connection.setReadTimeout(0);
connection.setUseCaches(false);
connection.setDefaultUseCaches(false);
connection.setChunkedStreamingMode(0);
if (method.equals("POST")) {
byte[] bits = data.getBytes();
connection.addRequestProperty("Content-Length", "" + bits.length);
connection.setDoOutput(true);
dumpHeaders(connection.getRequestProperties());
postOut = connection.getOutputStream();
if (postOut != null)
{
postOut.write(bits, 0, bits.length);
postOut.flush();
postOut.close();
postOut = null;
}
} else {
dumpHeaders(connection.getRequestProperties());
}
int httpStatus = connection.getResponseCode();
if (httpStatus / 100 > 3) {
Log.d("TEST", readResponse(connection.getErrorStream(), connection));
} else {
Log.d("TEST", readResponse(connection.getInputStream(), connection));
}
String finalUrl = connection.getURL().toExternalForm();
Log.d("TEST", "HTTP Status: " + httpStatus + ", URL: " + finalUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
if (connection.getErrorStream() != null) {
Log.d("TEST", readResponse(connection.getErrorStream(), connection));
} else {
Log.d("TEST", e.getMessage());
}
}
if (connection != null) {
connection.disconnect();
}
I'm currently using twitter fabric framework and trying to retrieve the list of my own account tweets. I tried searching online to no avail. The example in the document shows how to display a tweet based on tweetID. I do not want that. I do understand that REST client makes a http connection with the supplied variables and to retrieve the JSON results back to parse and etc.
This are my current codes which upon successful login it will display another activity which i want my tweets to be shown here.
public void success(Result<TwitterSession> result) {
// Do something with result, which provides a TwitterSession for making API calls
TwitterSession session = Twitter.getSessionManager().getActiveSession();
TwitterAuthToken authToken = session.getAuthToken();
token = authToken.token;
secret = authToken.secret;
Log.i("token",token);
Log.i("secret",secret);
successNewPage();
}
I have also passed the token and secret key over to the next activity using intent
public void successNewPage(){
Intent intent = new Intent(this, LoginSuccess.class);
intent.putExtra("token",token);
intent.putExtra("secret", secret);
startActivity(intent);
}
On the new activity class, i followed their documentation and came out with this,
TwitterAuthConfig authConfig = new TwitterAuthConfig("consumerKey", "consumerSecret");
Fabric.with(this, new TwitterCore(authConfig), new TweetUi());
TwitterCore.getInstance().logInGuest(new Callback() {
public void success(Result appSessionResult) {
//Do the rest API HERE
Bundle extras = getIntent().getExtras();
String bearerToken = extras.getString("token");
try {
fetchTimelineTweet(bearerToken);
} catch (IOException e) {
e.printStackTrace();
}
}
public void failure(TwitterException e) {
Toast.makeText(getApplicationContext(), "Failure =)",
Toast.LENGTH_LONG).show();
}
});
}
And the retrieve of tweets would be:
// Fetches the first tweet from a given user's timeline
private static String fetchTimelineTweet(String endPointUrl)
throws IOException {
HttpsURLConnection connection = null;
try {
URL url = new URL(endPointUrl);
connection = (HttpsURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("GET");
connection.setRequestProperty("Host", "api.twitter.com");
connection.setRequestProperty("User-Agent", "anyApplication");
connection.setRequestProperty("Authorization", "Bearer " + endPointUrl);
connection.setUseCaches(false);
String res = readResponse(connection);
Log.i("Response", res);
return new String();
} catch (MalformedURLException e) {
throw new IOException("Invalid endpoint URL specified.", e);
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
What i get in my log is:
380-380/com.example.john.fabric W/System.errīš java.io.IOException: Invalid endpoint URL specified.
Is my url wrong? Or is the token which I set in the endpointURL wrong too?
Any advice would be greatly appreciated. Thanks!
That should be the case, the message was thrown by the fetchTimelineTweet function. That should be caused by this line : URL url = new URL(endPointUrl); which tells that the endPointUrl causes MalformedURLException
EDIT :
According to the Twitter Dev Page, you should put this as endpointURL : https://dev.twitter.com/rest/reference/get/statuses/user_timeline and pass the user screenname as parameter.
EDIT 2 :
I think your code should be like this :
private static String fetchTimelineTweet(String endPointUrl, String token) // this line
throws IOException {
HttpsURLConnection connection = null;
try {
URL url = new URL(endPointUrl);
connection = (HttpsURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("GET");
connection.setRequestProperty("Host", "api.twitter.com");
connection.setRequestProperty("User-Agent", "anyApplication");
connection.setRequestProperty("Authorization", "Bearer " + token); // this line
connection.setUseCaches(false);
String res = readResponse(connection);
Log.i("Response", res);
return new String();
} catch (MalformedURLException e) {
throw new IOException("Invalid endpoint URL specified.", e);
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
I'm currently trying to send an http request from an android app to google-app-engine, this request should be received by the server who will use the parameters passed in the URL to add a new item to the datastore.
I wrote this code:
private class AsyncConnection extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
try {
// creating the url
URL url = new URL(params[0]);
// opening the connection
URLConnection connection;
connection = url.openConnection();
// get data about the connection
HttpURLConnection httpConnection = (HttpURLConnection) connection;
int responseCode = httpConnection.getResponseCode();
// connection was properly established
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream input = httpConnection.getInputStream();
return input.toString();
} else {
Log.d("CONNECTION", "connection not HTTP_OK");
}
} catch (MalformedURLException e) {
Log.d("SMARTGAN", "MalformedURLException" ,e);
} catch (IOException e) {
Log.d("SMARTGAN", "IOException" ,e);
} catch (Exception e) {
Log.d("SMARTGAN", "Exception" ,e);
} finally { }
return null;
}
}
but when I try to execute it I don't see any new item in the datastore.
The URL itself and the code on the server are fine, when I tried and sent the URL using it worked. I don't see any error message of "connection not ok" message in the log.
Mostly probably could be with hostname, have tried this solution How to make http post from android to google app engine server?
Also refer to https://developers.google.com/appengine/docs/java/tools/devserver#Command_Line_Arguments