I'm trying to download a file from an URL, but when my file is saved the name is different than it should be when it contains special characters. Here is the code I'm using
URL url = new URL(fileURL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
int responseCode = httpConn.getResponseCode();
// always check HTTP response code first
if (responseCode == HttpURLConnection.HTTP_OK) {
String fileName = "";
String disposition = httpConn.getHeaderField("Content-Disposition");
String contentType = httpConn.getContentType();
int contentLength = httpConn.getContentLength();
if (disposition != null) {
// extracts file name from header field
int index = disposition.indexOf("filename=");
if (index > 0) {
fileName = disposition.substring(index + 10,
disposition.length() - 1);
}
} else {
// extracts file name from URL
fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1,
fileURL.length());
}
System.out.println("Content-Type = " + contentType);
System.out.println("Content-Disposition = " + disposition);
System.out.println("Content-Length = " + contentLength);
// opens input stream from the HTTP connection
InputStream inputStream = httpConn.getInputStream();
String saveFilePath = saveDir + File.separator + fileName;
// opens an output stream to save into file
FileOutputStream outputStream = new FileOutputStream(saveFilePath);
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
System.out.println("Fichier téléchargé");
} else {
System.out.println("Pas de fichier trouvé à l'URL: " + fileURL + ".
HTTP code retourné par le serveur: " + responseCode);
}
httpConn.disconnect();
}
This is the name in the server "&éù%$£µ#çàè.png" and this is the name I get after download "&éù%$£µ#çà è.png"
What I'am getting wrong?
PS: here is an example of the output of my code
Répertoire de sauvegarde: C:\Data\downloads
Content-Type = image/png
Content-Disposition = attachment; filename="&éù%$£µ#çà è.png"
Content-Length = 2208482
Thanks in advance!
Related
I have FileDownloader class that downloads the file from google drive and than these files can be used by other classes. I need also to extract filename somehow. The problem is that this solution below works good for direct links, but it doesn't work when links are shorten with bit.ly for example...
Could you please advise how I can change the code to get the right file name?
public class FileDownloader {
private static final int BUFFER_SIZE = 4096;
public static void downloadFile(String fileURL, String saveDir)
throws IOException {
URL url = new URL(fileURL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
int responseCode = httpConn.getResponseCode();
// checking HTTP response code first
if (responseCode == HttpURLConnection.HTTP_OK) {
String fileName = "";
String disposition = httpConn.getHeaderField("Content-Disposition");
String contentType = httpConn.getContentType();
int contentLength = httpConn.getContentLength();
if (disposition != null) {
// extracts file name from header field
int index = disposition.indexOf("filename*=UTF-8''");
if (index > 0) {
fileName = disposition.substring(index + 17,
disposition.length());
}
} else {
// extracts file name from URL
fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1,
fileURL.length());
}
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 = httpConn.getInputStream();
String saveFilePath = saveDir + File.separator + fileName;
// opens an output stream to save into file
FileOutputStream outputStream = new FileOutputStream(saveFilePath);
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
System.out.println("File downloaded");
} else {
System.out.println("No file to download. Server replied HTTP code: " + responseCode);
}
httpConn.disconnect();
}
Alternate Code to get File details from any HTTP URL using Java API:
URL url = new URL("http://www.example.com/somepath/filename.extension");
System.out.println(FilenameUtils.getBaseName(url.getPath()));
// filename
System.out.println(FilenameUtils.getName(url.getPath()));
// filename.extension
I want to upload file with other string data to the server in one request using HttpURLConnection (not using MultiPartEntityBuilder)...Currently I can send the file but not the other string data with it !! Here is my current code for sending the file to server :
HttpURLConnection.setFollowRedirects(false);
HttpURLConnection connection = null;
String fileName = sourceFile.getName();
try {
connection = (HttpURLConnection) new URL(FILE_UPLOAD_URL).openConnection();
connection.setRequestMethod("POST");
String boundary = "---------------------------boundary";
String tail = "\r\n--" + boundary + "--\r\n";
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
connection.setRequestProperty("token", sharedpreferences.getString("token", ""));
connection.setRequestProperty("app_version", app_version);
connection.setRequestProperty("api_version", api_version);
connection.setDoOutput(true);
String metadataPart = "--"
+ boundary
+ "\r\n"
+ "Content-Disposition: form-data; name=\"metadata\"\r\n\r\n"
+ ""
+ "\r\n";
String fileHeader1 = "--"
+ boundary
+ "\r\n"
+ "Content-Disposition: form-data; name=\"myFile\"; filename=\""
+ fileName
+ "\"\r\n"
+ "Content-Type: application/octet-stream\r\n"
+ "Content-Transfer-Encoding: binary\r\n";
long fileLength = sourceFile.length() + tail.length();
String fileHeader2 = "Content-length: " + fileLength + "\r\n";
String fileHeader = fileHeader1 + fileHeader2 + "\r\n";
String stringData = metadataPart + fileHeader;
long requestLength = stringData.length() + fileLength;
connection.setRequestProperty("Content-length", "" + requestLength);
connection.setFixedLengthStreamingMode((int) requestLength);
connection.connect();
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeBytes(stringData);
out.flush();
int progress = 0;
int bytesRead;
byte buf[] = new byte[1024];
BufferedInputStream bufInput = new BufferedInputStream(new FileInputStream(sourceFile));
while ((bytesRead = bufInput.read(buf)) != -1) {
// write output
out.write(buf, 0, bytesRead);
out.flush();
progress += bytesRead; // Here progress is total uploaded bytes
publishProgress((int) ((progress * 100) / sourceFile.length())); // sending progress percent to publishProgress
}
// Write closing boundary and close stream
out.writeBytes(tail);
out.flush();
out.close();
// Get server response
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
StringBuilder builder = new StringBuilder();
while ((line = reader.readLine()) != null) {
builder.append(line);
}
} catch (Exception e) {
// Exception
} finally {
if (connection != null) connection.disconnect();
}
return null;
Any help would be appreciated !!Thank you...
I'm using HttpUrlConnection to upload an image to a web server. When I run the app and attempt to upload an image I get a Http response 200 as well as receive the filename and the imageid of the supposed image that has been uploaded, but when i check the server the image was not uploaded. The filename and the id are now part of the list but when I attempt to retrieve the image it returns null.
public String uploadFile(String apiPath, String filePath, String type)
{
String path = "";
String result = "";
switch (type)
{
case "M":
path = "Merchant/" + apiPath;
break;
case "C":
path = "Customer/" + apiPath;
break;
}
Log.i(ApiSecurityManager.class.getSimpleName(), m_token);
String href = "http://tysomapi.fr3dom.net/" + path + "?token=" + m_token;
Log.i(ApiSecurityManager.class.getSimpleName(), href);
try
{
String myIp = getIp();
URL url = new URL(href);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("User-Agent", "java");
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary = " + boundary);
conn.setRequestProperty("X-Forwarded-For", myIp);
conn.setDoOutput(true);
File file = new File(filePath);
DataOutputStream ds = new DataOutputStream(conn.getOutputStream());
ds.writeBytes(twoHyphens + boundary + LINE_FEED);
ds.writeBytes("Content-Disposition: form-data; name=\"image\"; filename=\"" + file.getName() + "\"" + LINE_FEED);
ds.writeBytes("ContentType: image/peg" + LINE_FEED);
ds.writeBytes(twoHyphens + boundary + LINE_FEED);
FileInputStream fStream = new FileInputStream(file);
int bytesAvailable = fStream.available();
int maxBufferSize = 1024;
int bufferSize = Math.min(bytesAvailable, maxBufferSize);
byte[] buffer = new byte[bufferSize];
int bytesRead = fStream.read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
ds.write(buffer, 0, bufferSize);
bytesAvailable = fStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fStream.read(buffer, 0, bufferSize);
}
ds.writeBytes(LINE_FEED);
ds.writeBytes(twoHyphens + boundary + twoHyphens + LINE_FEED);
fStream.close();
ds.flush();
ds.close();
Log.i(getClass().getSimpleName(), "Response Code: " + conn.getResponseCode());
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK)
{
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
while ((output = br.readLine()) != null)
{
result = result + output;
}
conn.disconnect();
}
catch (
MalformedURLException e
)
{
e.printStackTrace();
}
catch (
IOException e
)
{
e.printStackTrace();
}
return result;
}
I was able to fix the problem by using PrintWriter and OutputStream instead of DataOutputStream to pass the headers and the image.
I have following code, it downloads the file, but Adobe says that the file is damage. The file is 74KB big, but I can only download about 27KB. Can you tell me what's wrong. Thanks
#WebServlet("/GetData")
public class GetData extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final int BUFFER_SIZE = 4096;
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
String typ = ".pdf";
int totalBytesRead = 0;
String sep = File.separator;
String saveDir = "C:" + sep + "downloads";
String link ="/g02pepe/portal?token=9059829732446568452&action_16502593.mainContent_root_cntXYZ_cntShow_actShowFirstRow::km_XXXXXXX-XXXX::=&frontletId=XXXXX";
String adress = "https://XXXXXXX.XXXX.de/g02pepe/entry?rzid=XC&rzbk=0032&trackid=piwikad277d23c35b4990";
String together = adress + link;
String username = "XXXXXXXXX";
String password = "XXXXXXXXX";
String authString = username + ":" + password;
System.out.println("Auth string: " + authString);
byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
String authStringEnc = new String(authEncBytes);
try {
URL url = new URL(adress);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0");
connection.setRequestProperty("Authorization", "Basic " + authStringEnc);
connection.addRequestProperty("Referer", together);
System.out.println("Connected to " + together);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.connect();
int responseCode = connection.getResponseCode();
// always check HTTP response code first
if (responseCode == HttpURLConnection.HTTP_OK) {
String fileName = "";
String disposition = connection.getHeaderField("Content-Disposition");
String contentType = connection.getContentType();
int contentLength = connection.getContentLength();
if (disposition != null) {
// extracts file name from header field
int index = disposition.indexOf("filename=");
if (index > 0) {
fileName = disposition.substring(index + 10,
disposition.length() - 1);
}
} else {
// extracts file name from URL
fileName = adress.substring(adress.lastIndexOf("/") + 1,
adress.length());
}
System.out.println("Content-Type = " + contentType);
System.out.println("Content-Disposition = " + disposition);
System.out.println("Content-Length = " + contentLength);
System.out.println("fileName = " + fileName);
InputStream in = connection.getInputStream();
String saveFilePath = saveDir + File.separator + "Entgeltinformationen" + typ;
// opens an output stream to save into file
FileOutputStream outputStream = new FileOutputStream(saveFilePath);
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = in.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
}
System.out.println("Total Bytes read " + totalBytesRead);
outputStream.close();
in.close();
System.out.println("File downloaded");
} else {
System.out
.println("No file to download. Server replied HTTP code: "
+ responseCode);
}
connection.disconnect();
out.println("Download done!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
The file which i want to download is PDF.
I am trying to upload a file to a server with following code, the upload works, but the payload is added to the file, you can see it for example uploading a text file:
private Integer doFileUpload(final String urlServer) {
HttpURLConnection connection = null;
DataOutputStream outputStream = null;
FileInputStream fileInputStream = null;
final String pathToOurFile = mFileInfo.getProviderPath();
final String lineEnd = "\r\n";
final String twoHyphens = "--";
final String boundary = "*****";
int fileLength;
int bytesToRead, bufferSize;
final long fileSize;
byte[] buffer;
final int maxBufferSize = 1 * 1024 * 1024;
try {
final File file = new File(pathToOurFile);
fileInputStream = new FileInputStream(file);
final URL url = new URL(urlServer);
connection = (HttpURLConnection) url.openConnection();
final String[] payload = { twoHyphens + boundary + lineEnd,
"Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + pathToOurFile + "\"" + lineEnd, lineEnd, lineEnd,
twoHyphens + boundary + twoHyphens + lineEnd };
int payloadLength = 0;
for (final String string : payload) {
payloadLength += string.getBytes("UTF-8").length;
}
Logger.d(AsyncEgnyteUploadFile.LOGGING_TAG, "payload length: " + payloadLength);
fileLength = (int) file.length();
Logger.d(AsyncEgnyteUploadFile.LOGGING_TAG, "bytes: " + fileLength);
connection.setFixedLengthStreamingMode(fileLength + payloadLength);
fileSize = fileLength;
// Allow Inputs & Outputs
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setReadTimeout(5000);
connection.setConnectTimeout(5000);
connection.setRequestProperty("Authorization", "Bearer " + mToken);
// Enable POST method
connection.setRequestMethod(HttpPost.METHOD_NAME);
connection.setRequestProperty("Connection", "close");
// This header doesn't count to the number of bytes being sent.
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
connection.connect();
outputStream = new DataOutputStream(connection.getOutputStream());
outputStream.writeBytes(payload[0]);
outputStream.writeBytes(payload[1]);
outputStream.writeBytes(payload[2]);
bufferSize = Math.min(fileLength, maxBufferSize);
buffer = new byte[bufferSize];
long totalBytesRead = 0;
long lastProgressTime = 0;
// Read file
bytesToRead = fileInputStream.read(buffer, 0, bufferSize);
boolean stopUploading = (FileState.UPLOADING != mFileInfo.getState() || isCancelled());
while (bytesToRead > 0 && !stopUploading)
{
outputStream.write(buffer);
totalBytesRead += bytesToRead;
Logger.d(AsyncEgnyteUploadFile.LOGGING_TAG, "bytes written: " + totalBytesRead);
final long now = System.currentTimeMillis();
bufferSize = (int) Math.min(fileLength - totalBytesRead, maxBufferSize);
buffer = new byte[bufferSize];
bytesToRead = fileInputStream.read(buffer, 0, bufferSize);
}
outputStream.writeBytes(payload[3]);
outputStream.writeBytes(payload[4]);
// Responses from the server (code and message)
final int serverResponseCode = connection.getResponseCode();
if (serverResponseCode == HttpStatus.SC_OK || serverResponseCode == HttpStatus.SC_CREATED) {
mAlreadyUploaded = true;
return JBError.JBERR_SUCCESS;
} else {
Log.e(AsyncEgnyteUploadFile.LOGGING_TAG, "error code: " + serverResponseCode);
return serverResponseCode;
}
} catch (final SocketTimeoutException e) {
..
} catch (final UnknownHostException e) {
..
} catch (final SocketException e) {
..
} catch (final IOException e) {
..
} catch (final Exception ex) {
..
} finally {
closeAll(connection, fileInputStream, outputStream);
}
}
Uploading a text file with only 12345 inside with this code results in following:
--*****
Content-Disposition: form-data; name="uploadedfile";filename="/storage/emulated/0/Download/3.txt"
12345
--*****--
What am I doing wrong?
You copy code is wrong. This is how to copy between streams in Java:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
Notes:
You must check all reads for end of stream.
You must use the read count in the write() method.
You don't need a new buffer per read, and you don't need a buffer the size of the file. This will work with any buffer size greater than zero. I usually use 8192.
I suspect that your server is not designed / configured to handle "multi-part" uploads.
It certainly looks like it is treating this as a plain upload ... and I cannot see anything wring with the multi-part encapsulation.
(EJP is correct, but that is not what is causing your problem here. Your example shows that all of the characters were sent ...)