I am having trouble getting my app to open a connection to the URL that is a JSON file online. I followed guidelines how out to get the inBackground thread to fetch the URL, though when I call .connect() on that URL it seems to return out of the inBackground function because I tested just having a String that would be modified and displayed as a Toast, and modifying the String right after httpConn.connect() caused no change at all. I made sure my permissions were right in the manifest, but perhaps there is something small I am overlooking.
protected String doInBackground(URL... urls){
InputStream in = null;
String result = "test";
int responseCode = -1;
try {
URL url = urls[0];
URLConnection urlConn = url.openConnection();
if (!(urlConn instanceof HttpURLConnection)) {
throw new IOException("URL is not an Http URL");
}
HttpURLConnection httpConn = (HttpURLConnection) urlConn;
httpConn.setRequestMethod("GET");
httpConn.setDoInput(true);
result = "get here";
httpConn.connect();
result = "don't get here";
responseCode = httpConn.getResponseCode();
if(responseCode == HttpURLConnection.HTTP_OK){
in = httpConn.getInputStream();
}
httpConn.disconnect();
result = readIt(in, 10);
return result;
}
catch (Throwable t){
t.printStackTrace();
}
return result;
}
Any ideas of what is causing there not to be any connection or how to test if I am simply overlooking or not completely understanding this? I can additional code if needed. Thank you
As I am getting ,You want to connect to a web url which returns json response .Am I right ? If yes then you need to visit this link for complete solution .
Related
I am kind of new in android development and I am having a weird issue.
The following code is supposed to work:
URL url = new URL("http://127.0.0.1/test.html");
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
int code = connection.getResponseCode();
System.out.println("code: "+code);
The problem is, after I do the connection.connect(); nothing happens, even if I add a textX.setText() after the connect, I am not able to do any action.
Any idea what might be the issue?
This is my whole method, all I am trying to do is get some text from the API, which says "OK" actually, but I am not able to make it work.
public void conn (View view)
{
TextView text2 = (TextView)findViewById(R.id.text2);
text2.setText("connecting...");
String output="";
//All working until here
URL url;
HttpURLConnection urlConnection = null;
try {
output="about to connect";
text2.setText(output);
url = new URL("http://127.0.0.1:4444/localweb/api/api.php");
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
InputStream in = urlConnection.getInputStream();
text2.append("\nabout to get code");
int code = connection.getResponseCode();
text2.setText(Integer.toString(code));
//urlConnection = (HttpURLConnection) url.openConnection();
//urlConnection.connect();
//output=urlConnection.getResponseMessage();
//text2.setText(output);
InputStreamReader isw = new InputStreamReader(in);
int data = isw.read();
while (data != -1) {
char current = (char) data;
data = isw.read();
System.out.print(current);
output=output+current;
}
//text2.setText(output);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
}
There wasn't something 'wrong' with the http client code, the issue is that you cannot launch the httpurlclient from the parent thread as I was trying to do, it must be executed in the background through an AsyncTask, after moving all the httpurlconnection stuff into an additional async function now I am able to get all the web details I needed.
I'm trying to have my android app execute code where it opens a URL connection to a local php file that returns database entries in JSON format, but it's not connecting, after commenting out the other lines I can see that it throws an exception at the lines:
connection = (HttpURLConnection) url.openConnection();
connection.connect();
Heres the screen shot of android code and the error log, the returned expected json file in windows and the php file:
link
Can you change your
URL url = new URL(getListUrl);
into
URL url = new URL("http://www.google.com");
and check the incoming data.
and the following is a working example.
try {
URL url = new URL("http://www.google.com");
URLConnection urlConn = url.openConnection();
if (!(urlConn instanceof HttpURLConnection)) {
throw new IOException("URL Exception");
}
HttpURLConnection httpConn = (HttpURLConnection) urlConn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
resCode = httpConn.getResponseCode();
if (resCode == HttpURLConnection.HTTP_OK) {
in = httpConn.getInputStream();
}
}
catch (MalformedURLException e) {
e.printStackTrace();
}
My argument is if this code works for remote urls, it should work with localhost as well.
Hi it must be that you are using wrong local ip address in android files
it should be 10.0.2.2 not 127.0.0.1
First tell me are you testing on emulator or device
if emulator then where you define file path it should be
http://10.0.2.2/request_entries.php
just like in code
httpclient=new DefaultHttpClient();
httppost= new HttpPost("http://10.0.2.2/request_entries.php");
Managed to get the input stream using the URL:
URL url = new URL("http://10.0.2.2/request_entries.php");
result
Thanks a bunch guys :)
I have a server using mongodb, mongoose and node.js.
I have implemented some GET and POST methods.
Inside a HTML website, I can post data to the server within an XMLHttpRequest as follows inside javascript:
function postPlantType(base64){
var httpPost = new XMLHttpRequest(),
path = "http://...", // real URL taken out here
header = ('Content-Type','application/json'),
data = JSON.stringify({image:base64});
httpPost.onreadystatechange = function(err) {
if (httpPost.readyState == 4 && httpPost.status == 201){
console.log(httpPost.responseText);
} else {
console.log(err);
}
};
path = "http://..." // real URL taken out here
httpPost.open("POST", path, true);
httpPost.send(data);
}
this works fine. Now I want to create an Android app, making use of such a POST request, but my Code is not working successfully. Here is my Code:
private class PostNewPlantTask extends AsyncTask<String, Integer, String> {
String responseString = "";
int response;
InputStream is = null;
protected String doInBackground(String... urls){
DataOutputStream wr=null;
try {
URL url = new URL(urls[0]); // urls[0] is the url of the http request "http://www..."
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
String json = "{\"image\":\"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYE...\"}";
Log.d("json", json.toString());
conn.setRequestProperty("Content-length", json.getBytes().length + "");
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setAllowUserInteraction(false);
OutputStream os = conn.getOutputStream();
os.write( json.getBytes("UTF-8"));
os.close();
// Starts the query
conn.connect();
response = conn.getResponseCode();
if (response >= 200 && response <=399){
is = conn.getInputStream();
} else {
is = conn.getErrorStream();
}
// Convert the InputStream into a string
String contentAsString = readIt(is, 200);
responseString = contentAsString;
conn.disconnect();
} catch (Exception e) {
responseString = "error occured: "+e;
} finally {
if (is != null){
try { is.close();} catch (Exception e) {Log.d("HTTP POST planttypes","Exception occured at closing InputStream: "+e);}
}
}
Log.d("HTTP POST plants", "The response is: " + response + responseString);
return responseString;
}
protected void onPostExecute(String result){
// TODO: nothing(?)
// give user feedback(?)
}
}
NOTE: If I change the json String to invalid json content e.g. deleting the last "}", The response of the server is
400 "code":"InvalidContent","message":"Invalid JSON: Unexpected end of input"
So I assume the entire json string must be correct, if its unchanged.
I am hardcoding the base64encoded image String here instead of encode a real image, because of testing issues. You can see the image at this jsfiddle.
If I see it correctly, its the exact same request as done from my javascript, but I get 500 internal server error.
However, in order to get more information, here is the server function, that is called for that request url:
function postNewPlantType(req, res, next){
var json = JSON.parse(req.body);
newPlantTypeData = {
image:json.image
};
var imageBuffer = decodeBase64Image(json.image);
newPlantType = new Planttype(newPlantTypeData);
newPlantType.save(function(err){
if (err) return next(new restify.InvalidArgumentError(JSON.stringify(err.errors)));
var fileName = cfg.imageFolder + "" + newPlantType._id + '.jpeg';
fs.writeFile(fileName, imageBuffer.data, function(error){
if (error) log.debug(error);
log.debug("PlantType-ImageFile successfully created on server.");
});
res.send(201, newPlantType);
log.debug("PlantType successfully saved in database.");
});
}
What I am wondering about is, the javascript request is working, but the android request is not. So I assume there must be a mistake in my android code. Can you help me and explain, what the error is and what I have to change?
You probably need to encode it properly:
conn.connect();
DataOutputStream printout = new DataOutputStream(conn.getOutputStream ());
printout.write(URLEncoder.encode(json.toString(),"UTF-8"));
printout.flush ();
printout.close ();
response = conn.getResponseCode();
...
After lots of days of investigation I finally got a 201 response by changing the line
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
to
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
Well.. I was sending an encoded JSON and not a json itself...
I am trying to hit a web service. it is working fine with android 4.4 or android 5.X. but when i am trying to hit "http://inmotion-prod.cloudapp.net:145/service1.svc/json/GetCustomerUUID" using android 4.1.1 it always returning me 307 status code. but this url is working fine with android 4.4 or 5.x. i also tried to hit other url it is working fine on android 4.1.1.
so please tell me what is the problem
Log.i(TAG, url);
String response = null;
HttpURLConnection conn = null;
try {
URL webServiceUrl = new URL(url);
conn = (HttpURLConnection) webServiceUrl
.openConnection();
Log.i(TAG, "Connection open");
conn.setRequestMethod(GET);
conn.setConnectTimeout(CONNECTION_TIME_OUT);
conn.setRequestProperty(CONTENT_TYPE, contentType);
conn.setRequestProperty(ACCEPT_TYPE, acceptType);
conn.setDoInput(true);
conn.connect();
Log.i(TAG, "Connection Connected");
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK && conn.getInputStream() != null) {
response = StreamUtility.convertStreamToString(conn.getInputStream());
conn.getInputStream().close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();
}
}
return response;
}
Replace your URL address with http://inmotion-prod.cloudapp.net:145/service1.svc/json/GetCustomerUUID/ (pay attention to / at the end). The response code will be 200.
UPDATE:
With your current URL address (http://inmotion-prod.cloudapp.net:145/service1.svc/json/GetCustomerUUID) without / at the end, you can use the following code:
String address = "http://inmotion-prod.cloudapp.net:145/service1.svc/json/GetCustomerUUID";
URL url = new URL(address);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setInstanceFollowRedirects(false);
// if print out (debug or logging), you will see secondURL has / at the end
URL secondURL = new URL(urlConnection.getHeaderField("Location"));
HttpURLConnection urlConnection1 = (HttpURLConnection) secondURL.openConnection();
Then use urlConnection1.getResponseCode()
Hope it helps!
BNK's answer helped, I fixed it like this so that it also works on newer devices (location header was returned as null / empty!)
String headerLocation = httpsUrlConnection.getHeaderField("Location");
logger.debug("Location header: " + headerLocation);
// if the redirect URL ends with a "/" sign, but the original URL does not, it's probably the redirect bug
String originalURL = url.toString();
if (!TextUtils.isEmpty(headerLocation) && headerLocation.endsWith("/") && !originalURL.endsWith("/"))
{
logger.info("Redirect Location differs from original URL, create new connection to: " + headerLocation);
httpsUrlConnection = (HttpsURLConnection) new URL(headerLocation).openConnection();
// optional
httpsUrlConnection.setSSLSocketFactory(sslSocketFactory);
}
I'm using HttpURLConnection to do communication with a backend server and im doing so in an async task in the doInBackground method as you should.
Now I need to be able to follow 302 redirects, but I'm having some problems with this. The issue is that the new location usually will be on another host, however when doing the redirect request it seem not to change the URL to a new host hence I get a 404 error saying the specified path does not exits.
Now I know I could set HtppURLConnection.setFollowRedirect but I need to have more control over the redirects so they should not just be followed blindly. The Redirect behavour should be controlled by the object who called the asynctask (when an asynctask object is created you pass the object who creates it in a parameter called _callback).
Heres's my current code:
protected HttpResponse doInBackground(String... req) {
HttpURLConnection urlConnection = null;
try {
urlConnection = (HttpURLConnection) this._url.openConnection();
urlConnection.setConnectTimeout( (int) this._timeout*1000);
String body = req[0];
// set headers / write information to output stream if request is post
// create the response object
HttpResponse responseObject = null;
try
{
// get status, contenttype, charset...
InputStream in = null;
if (urlConnection.getResponseCode() != -1 && urlConnection.getResponseCode() < 300)
{
in = new BufferedInputStream(urlConnection.getInputStream(), 8192);
}
else
{
in = new BufferedInputStream(urlConnection.getErrorStream(), 8192);
}
responseObject = new HttpResponse(in, status, contentType, charset);
// if redirect
if (status == 302 && this._callback.onRedirect(responseObject) == true)
{
// recall
String url = urlConnection.getHeaderField("location");
Log.v("Async Task", "Redirect location: " + url);
this._url = null;
this._url = new URL(url);
urlConnection.disconnect();
urlConnection = null;
responseObject = this.doInBackground(req);
}
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
// return the response
return responseObject;
}
// catch some other exceptions
finally
{
if (urlConnection != null)
{
urlConnection.disconnect();
} }
}
And as said the problem is that the redirect request seem to change the path of the URL but not the host. The URL object itself seem to contain the right information so I have no idea why this is happening. (I'm getting HTML as response which is an 404 error page that includes the server name of the old server)
Thanks for any help!
Note: HttpResponse is just an object I created for holding the relevant information about the response.
This was caused by the fact that I sent the same headers and did not change the "host" header of the request which caused Apache to be confused it seems.