I am sending a post request to a server. After a successful request, the response sends pdf data to the client for download. I am trying to generate the pdf file with the response and save it to the Android device. I have successfully created the request, the empty pdf file, and I have even received a successful response. Although, when I call .getInputStream() it returns a "-1". As a result, the while loop exits with the error java.lang.ArrayIndexOutOfBoundsException: length=4096; regionStart=0; regionLength=-1.
I understand why I am receiving this error, but I do not know how to get the data response.
protected Boolean doInBackground(String... params) {
Log.d("LOGOUT", "CREATING REQUEST");
boolean successful = false;
HttpURLConnection connection = null;
URL downloadURL = null;
InputStream inputStream = null;
PrintWriter out= null;
FileOutputStream fileOutputStream = null;
File file = null;
int totalsize;
try {
downloadURL = new URL("http://exampleurl.com");
connection = (HttpURLConnection) downloadURL.openConnection();
connection.setDoOutput(true);
String data = "param=" + URLEncoder.encode(params[0], "UTF-8") + "&submit=" + URLEncoder.encode("Submit", "UTF-8");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length", "" + data.length());
String sdCard = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
file = new File(sdCard + File.separator + "test.pdf");
fileOutputStream = new FileOutputStream(file);
out = new PrintWriter(connection.getOutputStream());
out.write(data);
out.close();
inputStream = connection.getInputStream();
int read;
byte[] buffer = new byte[1024];
while ((read = inputStream.read(buffer)) != -1) ; {
Log.d("LOGOUT", "BUFFER: " + read);
// **The LOGOUT message reads "BUFFER: -1" within Logcat**
fileOutputStream.write(buffer, 0, read);
}
successful = true;
} catch (MalformedURLException e) {
Log.d("LOGOUT", "ERROR: " + e);
} catch (UnsupportedEncodingException e) {
Log.d("LOGOUT", "ERROR: " + e);
} catch (FileNotFoundException e) {
Log.d("LOGOUT", "ERROR: " + e);
} catch (IOException e) {
Log.d("LOGOUT", "ERROR: " + e);
} finally {
if (inputStream != null) {
try {
Log.d("LOGOUT", "CLOSING INPUTSTREAM");
inputStream.close();
} catch (IOException e) {
Log.d("LOGOUT", "ERROR: " + e);
}
if (fileOutputStream != null) {
try {
fileOutputStream.close();
Log.d("LOGOUT", "CLOSING FILEOUTPUTSTREAM");
} catch (IOException e) {
Log.d("LOGOUT", "ERROR: " + e);
}
}
}
if (connection != null) {
Log.d("LOGOUT", "CLOSING CONNECTION");
connection.disconnect();
}
}
return successful;
}
I am receiving the correct response headers. I have listed them below...
Connection:Keep-Alive
Content-Disposition:attachment; filename=examplefilename.pdf
Content-Type:application/pdf
Date:Wed, 21 Oct 2015 13:59:45 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.2.22
Transfer-Encoding:chunked
Vary:User-Agent
X-Powered-By:PHP/5.3.29
I know for a fact I am sending/receiving a successful request/response, but I am unable to download the pdf data. Finally, I do not have control over the server. I am interacting with a third party application.
What am I doing wrong to accomplish the task? If not that, does anyone have any idea on where I could look to solve the problem? Any guidance is appreciated.
Related
I have express js server as API. I need to send POST request to that server and my website needs to download PDF file to the client computer.
Here is my express server code:
const pdf = await generatePDF(data.originURL, data.url, data.pageOrientation); //pdf generation
// send pdf to client
res.writeHead(200, {
'Content-Type': 'application/pdf',
'Content-Disposition': 'attachment; filename=file.pdf',
'Content-Length': pdf.length
});
res.end(pdf);
In my website I have commandButton which call the action for POST request;
What I'm a doing wrong, I'm not getting any downloaded file in my website?
Method for making POST request:
public void makeRequest() {
HttpURLConnection connection = null;
try {
String imageExportServer = "url....";
URL url = new URL(imageExportServer);
connection = (HttpURLConnection)url.openConnection();
Stopwatch stopwatch = Stopwatch.createStarted();
try {
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
try (OutputStream stream = connection.getOutputStream()) {
JsonObject configJson = new JsonObject();
configJson.addProperty("originURL", "url");
configJson.addProperty("url", "url...");
configJson.addProperty("pageOrientation", "someText");
stream.write(Builder().create().toJson(configJson).getBytes());
}
int responseCode = connection.getResponseCode();
if (responseCode != 200) {
//log.warn("Error response: ", responseCode);
}
String fileName = "";
String disposition = connection.getHeaderField("Content-Disposition");
String contentType = connection.getContentType();
int contentLength = connection.getContentLength();
System.out.println("Content-Type = " + contentType);
System.out.println("Content-Disposition = " + disposition);
System.out.println("Content-Length = " + contentLength);
System.out.println("fileName = " + fileName);
// opens input stream from the HTTP connection
InputStream inputStream = connection.getInputStream();
// opens an output stream to save into file
FileOutputStream outputStream = new FileOutputStream("neki.pdf");
int bytesRead = -1;
byte[] buffer = new byte[contentLength];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
FileOutputStream fos = new FileOutputStream("neki.pdf");
fos.write(buffer);
fos.close();
System.out.println("File downloaded");
}
} catch (IOException e) {
//log.warn(e.getMessage(), e);
} finally {
//log.info("Exporting chart of type '%s' took %sms.", "tyoe", stopwatch.elapsed(TimeUnit.MILLISECONDS));
}
} catch (IOException e) {
//log.warn(e.getMessage(), e);
} finally {
if (connection != null) {
try {
connection.disconnect();
} catch (Exception e) {
//log.warn(e.getMessage(), e);
}
}
}
}
I'm show data from database but is not work.
That is get me the Exception : FileNotFound but the path is well.
But when I put the URL from the browser it works normally
There is my code :
#Override
protected String doInBackground(String... parametro)
{
try
{
URL url = new URL(urlMostrarClientes);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
InputStream inputStream = connection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuffer buffer = new StringBuffer();
String linha = "";
while ((linha = bufferedReader.readLine()) != null)
{
buffer.append(linha + "\n");
}
inputStream.close();
bufferedReader.close();
progressDialog.dismiss();
return buffer.toString().trim();
} catch (MalformedURLException e)
{
e.printStackTrace();
progressDialog.dismiss();
Log.v("vampiro","ERRO : " + e.toString());
} catch (ProtocolException e)
{
e.printStackTrace();
progressDialog.dismiss();
Log.v("vampiro","ERRO : " + e.toString());
} catch (IOException e) {
e.printStackTrace();
progressDialog.dismiss();
Log.v("vampiro","ERRO : " + e.toString());
}
return "ERRO";
}
Three ways of solving problem :
file:///yourFilePath
Paths.get(yourPath).toUri().toURL() //java nio way
File(“path_to_file”).toURI().toURL();
//java io way
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
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.
I am trying to get an Audio file through http get from a secure restful service, I have successfully receive and parse text XML service but a bit confused that how to do with Audio file.
code to call the secure restful service with XML response
String callWebService(String serviceURL) {
// http get client
HttpClient client = getClient();
HttpGet getRequest = new HttpGet();
try {
// construct a URI object
getRequest.setURI(new URI(serviceURL));
} catch (URISyntaxException e) {
Log.e("URISyntaxException", e.toString());
}
// buffer reader to read the response
BufferedReader in = null;
// the service response
HttpResponse response = null;
try {
// execute the request
response = client.execute(getRequest);
} catch (ClientProtocolException e) {
Log.e("ClientProtocolException", e.toString());
} catch (IOException e) {
Log.e("IO exception", e.toString());
}
try {
in = new BufferedReader(new InputStreamReader(response.getEntity()
.getContent()));
} catch (IllegalStateException e) {
Log.e("IllegalStateException", e.toString());
} catch (IOException e) {
Log.e("IO exception", e.toString());
}
StringBuffer buff = new StringBuffer("");
String line = "";
try {
while ((line = in.readLine()) != null) {
buff.append(line);
}
} catch (IOException e) {
Log.e("IO exception", e.toString());
return e.getMessage();
}
try {
in.close();
} catch (IOException e) {
Log.e("IO exception", e.toString());
}
// response, need to be parsed
return buff.toString();
}
may this one help you..
public static void downloadFile(String fileURL, String fileName) {
try {
// fileURL=fileURL.replaceAll("amp;", "");
Log.e(fileURL, fileName);
String RootDir = Environment.getExternalStorageDirectory()
.toString();
File RootFile = new File(RootDir);
new File(RootDir + Commons.dataPath).mkdirs();
File file = new File(RootFile + Commons.dataPath + fileName);
if (file.exists()) {
file.delete();
}
file.createNewFile();
URL u = new URL(fileURL);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
FileOutputStream f = new FileOutputStream(new File(
"mnt/sdcard"+Commons.dataPath + fileName));
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = in.read(buffer)) > 0) {
f.write(buffer, 0, len1);
}
f.close();
} catch (Exception e) {
e.printStackTrace();
}
}