HttpUrlConnection sometimes gives EOF exception - java

I am using HttpUrlConnection and using POST method to get some data from web server. Sometimes, I get the response and at times I get EOFexception
These are the solutions are I have already tried :
1) System.setProperty("http.keepAlive", "false");
2) if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13) {
connection.setRequestProperty("Connection", "close");
}
Below is my code from AsyncTask class;
CODE :
#Override
protected JSONObject doInBackground(KeyValuePair... keyValuePairs) {
JSONObject jsonResponse = new JSONObject();
HttpURLConnection connection = null;
// check if is Internet is available before making a network call
if (isInternetAvailable()) {
try {
jsonResponse = new JSONObject();
URL url = new URL(urlStr);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setUseCaches(false);
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("charset", "UTF-8");
if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13) {
connection.setRequestProperty("Connection", "close");
}
// setting post params
StringBuilder builder = new StringBuilder();
for (int i = 0; i < keyValuePairs.length; i++) {
builder.append(URLEncoder.encode(keyValuePairs[i].getKey(), "UTF-8") + "=" + URLEncoder.encode(keyValuePairs[i].getValue(), "UTF-8") + "&");
GeneralUtils.print("key : " + keyValuePairs[i].getKey() + ", value : " + keyValuePairs[i].getValue());
}
String postData = builder.toString();
postData = postData.substring(0, postData.length() - 1);
GeneralUtils.print("postData " + postData);
byte[] postDataByteArr = postData.getBytes();
connection.setFixedLengthStreamingMode(postDataByteArr.length);
connection.setConnectTimeout(20000);
DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
dataOutputStream.writeBytes(postData);
dataOutputStream.flush();
dataOutputStream.close();
GeneralUtils.print("respCode " + connection.getResponseCode());
// if connection was not successful
if (connection.getResponseCode() != 200) {
jsonResponse.put("status", "Failure");
jsonResponse.put("message", "Something went wrong. Please Try Again");
} else {
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = reader.readLine()) != null) {
sb.append(line);
}
reader.close();
String response = sb.toString();
GeneralUtils.print("NetworkCall Server response " + response);
jsonResponse = new JSONObject(response);
}
} catch (JSONException e) {
GeneralUtils.print("NetworkCall.JSONEx 162 " + e);
} catch (MalformedURLException e) {
GeneralUtils.print("NetworkCall.MalformedURLEx " + e);
} catch (IOException e) {
try {
jsonResponse.put("status", "No Internet Connection");
jsonResponse.put("message", "Please check your Internet connection and try again");
} catch (JSONException e1) {
GeneralUtils.print("NetworkCall.JSONEx " + e);
}
} finally {
connection.disconnect();
}
} else {
// if Internet is not available
try {
jsonResponse.put("status", "No Internet Connection");
jsonResponse.put("message", "Please check your Internet connection and try again");
} catch (JSONException e) {
e.printStackTrace();
}
}
return jsonResponse;
}
Many many thanks in advance!

As of now I am following a workaround posted here
which essentially dictates trying to connect N number of times to bypass the EOF exception issue.
In my case, when I catch EOFException, I call the doInBackground again depending upon the reconnectCount;
CODE :
catch (IOException e) {
try {
if (reConnectCount <= 10) {
reConnectCount++;
jsonResponse = doInBackground(keyValuePairs);
} else {
jsonResponse.put("status", "No Internet Connection");
jsonResponse.put("message", "Please check your Internet connection and try again");
}
} catch (JSONException e1) {
GeneralUtils.print("NetworkCall.JSONEx " + e);
}
}
Where jsonResponse essentially holds server response in JSON form. So, whenever doInBackground is successfully executed (i.e. does not get Caught and returns jsonResponse), we overwrite the calling doInBackground's jsonResponse object.

Related

Android HttpURLConnection: HTTP response always 403

public static class GetTitleTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
try {
String youtubeUrl = urls[0];
if (youtubeUrl != null) {
URL url = new URL("http://www.youtube.com/oembed?url=" + youtubeUrl + "&format=json");
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
connection = (HttpURLConnection) url.openConnection();
connection.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:221.0) Gecko/20100101 Firefox/31.0");
connection.connect();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
Log.d(TAG, "HTTP response code is " + connection.getResponseCode());
return null;
}
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line+"\n");
Log.d("Response: ", "> " + line);
}
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String title) {
Log.v(TAG, "onPostExecute: " + title);
super.onPostExecute(title);
// ...
}
}
Input for example: https://www.youtube.com/watch?v=hT_nvWreIhg
This always returns null. The HTTP response code is 403. That is why I tried adding a user agent, but it didn't help.
Is there any way to fix this? I would like to get the video title without using the YouTube API.
I tried fetching it with curl. Your URL uses http instead of https://..., change it to https://www.youtube.com/oembed?url=.
Trying to fetch the URL when it starts with just http resulted in a 403 status for me. But https was successful.
URL url = new URL("http://www.youtube.com/oembed?url=" + youtubeUrl + "&format=json");
Should be changed to:
URL url = new URL("https://www.youtube.com/oembed?url=" + youtubeUrl + "&format=json");
The server does not agree to fulfil the request (error code 403). This is probably due to the protocol. Try using HttpsURLConnection instead of HttpURLConnection.

getInputStream freezes and never finishes

Im reading a simple text file from my website using HttpURLConnection, and when it calls getInputStream it freezes and never finishes, the getResponseCode returns 200. It was working at first every time then it stopped working.
I have search for a solution all over the internet and none work. I think it maybe ddos protection on the web server, or something on there end blocking it.
public static String getLatestInfo(String urlString){
URL url = null;
HttpURLConnection connection = null;
/*InputStream inputStream = null;
InputStreamReader isr = null;
BufferedReader in = null;*/
try {
url = new URL(urlString);
connection = (HttpURLConnection) url.openConnection();
//connection.setRequestMethod("GET");
//connection.setDoOutput(true);
connection.setConnectTimeout(5000); // 5 seconds connectTimeout
connection.setReadTimeout(5000); // 5 seconds socketTimeout
connection.setRequestProperty("Connection", "close");
connection.setRequestProperty("Content-Type", "text/xml");
connection.setRequestProperty("Accept", "text/xml");
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2");
connection.connect();
if (connection.getResponseCode() == 200) {
try(InputStream inputStream = connection.getInputStream())
{
try(InputStreamReader isr = new InputStreamReader(inputStream, "UTF-8")) {
try(BufferedReader in = new BufferedReader(isr))
{
String line;
String config = "";
while ((line = in.readLine()) != null) {
config = config + line + "\n";
}
return config;
}
}
}
/*inputStream = connection.getInputStream();
isr = new InputStreamReader(inputStream, "UTF-8");
in = new BufferedReader(isr);
String line;
String config = "";
while ((line = in.readLine()) != null) {
config = config + line + "\n";
}
return config;*/
}
}
catch (SocketTimeoutException e)
{
System.out.println("Timeout: " + e.getMessage());
}
catch (MalformedURLException e) {
System.out.println("Malformed URL: " + e.getMessage());
}
catch (IOException e) {
System.out.println("I/O Error: " + e.getMessage());
try {
System.out.println(connection.getResponseCode());
} catch (IOException e1) {
e1.printStackTrace();
}
}
finally {
if (connection != null) connection.disconnect();
/*try {
if (inputStream != null) inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (in != null) in.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (isr != null) isr.close();
} catch (IOException e) {
e.printStackTrace();
}*/
}
return null;}
I started simple and have added all the suggestion that should've fix it.. it gets response code 200 and then freezes on connection.getInputStream()
There were multiple things wrong in my code:
Some streams for file reading wasn't closed.
I was using FileInputStream/FileOutputStream and it was making it freeze. This explains it. Even though it shows a work around, but it still would make it freeze.
The main problem i was using SwingUtilities.invokeLater(new Runnable ()... and it was freeze and random points.
Fixing all the above factors and it solved my problem.

Statement in Catch isn't executed [duplicate]

This question already has answers here:
How to print to the console in Android Studio?
(8 answers)
Closed 5 years ago.
I need to fetch login details from my web service to authenticate login in my app. Below is the code which does the job.
try {
//Apache Libraries and namevaluepair has been deprecated since APK 21(?). Using HttpURLConnection instead.
URL url = new URL(wsURL + authenticate);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
OutputStream os = connection.getOutputStream();
os.write(postParam.getBytes());
os.flush();
os.close();
// Fetching the response code for debugging purposes.
int responseCode = connection.getResponseCode();
Log.d(TAG, "POST Response Code: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
//Adding every responseCode in the inputLine.
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
Log.d(TAG, "HTTP Response: " + response.toString());
//TODO: Check login logic again
//Sets Authentication flag
if (!response.toString().contains("Authentication Failed!")) {
authFlag = true;
Log.i(TAG, "Authentication Completed: Logged in Successfully!");
try {
JSONObject jsonObject = new JSONObject(response.toString());
JSONArray jsonArray = jsonObject.getJSONArray("rows");
JSONObject beanObject = jsonArray.getJSONObject(0);
userBean = new UserBean(username, beanObject.getString("User_FullName"), beanObject.getInt("UserType_Code"));
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
Log.e(TAG, "Error!!! Abort!!!");
}
connection.disconnect();
} catch (MalformedURLException e) {
System.out.println("URLConnection Exception: " + e);
} catch (IOException e) {
System.out.println("IOStream Exception: " + e);
}
return postParam;
}
Issue I'm facing is I don't see anything related to it in my logcat but on debugging I find that the control goes to
} catch (MalformedURLException e) {
but System.out.println("URLConnection Exception: " + e); is never executed. I'm novice at Android dev so there might be something which I can't see. Please help.
EDIT - I first tried with Log.e but it didn't work so I put System.out.println which didn't work either.
You should not use System.out,
instead use logging functions like logcat for debugging.
In this example, considering that the catch catches an error, you should use:
private static final String TAG = "MyActivity";
...
catch (MalformedURLException e) {
Log.e(TAG, "URLConnection Exception: " + e.getMessage());
} catch (IOException e) {
Log.e(TAG, "IO error: " + e.getMessage());
}
Here is an explanation of how to use them properly.
If you can't see logcat, go there.
just try
Log.e("tag","Exception: " + e);
and you can find it in android monitor

Android HttpURLConnection with json string

I want to call the following URL:
http://192.168.0.196:8080/openapi/localuser/set?{"syskey":"1234","usrname":"256","usrpwd":"556"}
Use this address to add a new user to the database. To do this I use HttpURLConnection in my AsyncTask class
try {
URL myUrl = new URL(params[0]);
HttpURLConnection conn = (HttpURLConnection) myUrl.openConnection();
conn.setReadTimeout(10000 );
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
// Starts the query
conn.connect();
int response = conn.getResponseCode();
Log.d("lab", "The response is: " + response);
statusMap.put("addUser", Integer.toString(response));
Log.d("lab", "URL: " + params[0]);
}catch (Exception e){
Log.d("lab", "Error2: " + e.getMessage());
}
params[0] = http://192.168.0.196:8080/openapi/localuser/set?{"syskey":"1234","usrname":"256","usrpwd":"556"}
Unfortunately, this call is not working. I do not get the error.
catch returns null
Try like this way. You need to add few line in your code.
public JSONObject makeHttpRequest(String requestURL, JSONObject register) {
try {
url = new URL(requestURL);
connection = (HttpURLConnection) url.openConnection();
connection.setReadTimeout(150000);
connection.setConnectTimeout(150000);
connection.setAllowUserInteraction(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
connection.setFixedLengthStreamingMode(register.toString().getBytes().length);
connection.setDoInput(true);
connection.setDoOutput(true);
OutputStreamWriter outputStream = new OutputStreamWriter(connection.getOutputStream());
outputStream.write(register.toString());
outputStream.flush();
Log.e("URL", connection.getURL().toString());
Log.e("JSONObject", register.toString());
} catch (Exception e) {
Log.e("MAIN Exception", e.toString());
}
try {
int statuscode = connection.getResponseCode();
if (statuscode == HttpURLConnection.HTTP_OK) {
is = connection.getInputStream();
} else {
}
} catch (IOException e) {
Log.e("IOException", e.toString());
}
try {
rd = new BufferedReader(new InputStreamReader(is));
response = new StringBuffer();
while ((line = rd.readLine()) != null) {
response.append(line);
response.append('\n');
}
Log.e("Response", response.toString() + " ");
rd.close();
} catch (IOException e) {
Log.e("BUFFER_READER", e.toString());
} catch (NullPointerException e) {
Log.e("NullPointerException", e.toString());
} finally {
connection.disconnect();
}
try {
return new JSONObject(response.toString());
} catch (JSONException e) {
Log.e("JSONException", e.toString());
}
return null;
}
Also You are using localHost you must have emulator which can connect to localhost. Unless it will not going to work on any device.
try this :
private String post(String url) throws JSONException {
JSONObject json = new JSONObject();
try {
String query = "";
String EQ = ":";
String AMP = "&";
for (NameValuePair param : parameters) {
query = json.put(param.getName(), param.getValue()) + ",";
}
// url+= "?" + query;
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
if (parameters != null) {
StringEntity se = new StringEntity(query.toString());
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,
"application/json"));
post.setEntity(se);
Log.d("POSTQuery", url + parameters);
}
HttpResponse response = client.execute(post);
StatusLine statusLine = response.getStatusLine();
Log.d("Status Code", "" + statusLine.getStatusCode());
if (statusLine.getStatusCode() == 200) {
return StringifyResponse(response);
}
Log.d("POSTQuery", url);
// Log.d("response", response.toString());
return StringifyResponse(response);
} catch (ClientProtocolException e) {
} catch (IOException e) {
Log.d("response", e.toString());
return "IOException";
}
return null;
}
You need to format all url querystring and then use outputwriter to flush the data :
// Create data variable for sent values to server
String data = URLEncoder.encode("syskey", "UTF-8")
+ "=" + URLEncoder.encode("1234", "UTF-8");
data += "&" + URLEncoder.encode("usrname", "UTF-8") + "="
+ URLEncoder.encode("256", "UTF-8");
data += "&" + URLEncoder.encode("usrpwd", "UTF-8")
+ "=" + URLEncoder.encode("556", "UTF-8");
and then flush the data:
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write( data );
wr.flush();
Link here :
http://androidexample.com/How_To_Make_HTTP_POST_Request_To_Server_-_Android_Example/index.php?view=article_discription&aid=64&aaid=89

my android application get connection time out while the browser still can use

code:
public static String openUrl(String url, String method,
RequestParam params) throws NuageException {
HttpURLConnection conn = null;
String response = "";
String decodParam = params.decod();
if (method.equals(GET))
{
url = url + "?" + decodParam;
// Log.v(LOG_TAG, "GET:" + url);
}
try {
Log.v("开始请求:", String.valueOf(System.currentTimeMillis()));
conn = (HttpURLConnection) new URL(url).openConnection();
conn.setReadTimeout(READTIMEOUT);
conn.setConnectTimeout(CONNECTTIMEOUT);
conn.setUseCaches(false);
conn.setRequestProperty("Connection", "Keep-Alive");
if (method.equals(POST)) {
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.getOutputStream().write(decodParam.getBytes("UTF-8"));
// Log.v(LOG_TAG, "POST:" + url + " " + decodParam);
}
InputStream is = null;
conn.connect();
int responseCode = conn.getResponseCode();
if (responseCode == 200 || responseCode == 201
|| responseCode == 202) {
is = conn.getInputStream();
} else {
is = conn.getErrorStream();
}
response = read(is);
Log.v("请求结束:", String.valueOf(System.currentTimeMillis()));
Log.v(LOG_TAG, "response:" + response);
checkResponse(response);
} catch (MalformedURLException e) {
throw new NuageException(e);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().equals(
"Received authentication challenge is null"))
throw new NuageException(new NuageError(
NuageError.ERROR_SESSIONKEY_INVALID, "", "", ""));
e.printStackTrace();
throw new NuageException(e);
} catch (NuageException e) {
throw e;
} finally {
if (conn != null) {
conn.disconnect();
}
}
return response;
}
sometimes i get java.net.SocketTimeoutException: Connection timed out while the browser still work.
anyone can help to improve my code?

Categories