Complete file name does not appear while downloading via servlet - java

I have a servlet where I have written code to download a file.
The part of code is as follows :
response.setContentType((mimetype != null) ? mimetype
: "application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename="
+ fileName);
OutputStream os = response.getOutputStream();
try {
//here getFileByte is a method for getting
byte bytes[] = getFileByte(filePath);
os.write(bytes);
}
The above works fine but the only problem is that when the filename contains more than one word then it downloads the file with the first word.
For example:- Filename is "Step by Step.pdf" then the downloaded file
will be "Step.pdf".
I even tried to print the filename before giving it to setHeader method and it was correct. Don't have any clue how to resolve this.Could anyone please check what am I doing wrong here and how to correct this bug?

If your file has spaces in it, it should be enclosed in double quotes:
Content-disposition: attachement; filename="file with spaces.whatever"
Note that double quotes will work equally well for filenames without spaces, so you might as well use them all the time

Have you try to encode your filename ? For exemple, replacing spaces by "%20" character sequence ?

Related

Java OutputStream produces wrong directory path and characters

i'm using OutputStream to create a pdf file for download as follow:
byte[] infoFile = info.getBytes();
String infoName = info.getFileName();
String contentType = info.getContentType();
response.setContentType(contentType);
response.setHeader("Content-disposition", "attachment;filename=\"" + infoName + "\"");
response.setContentLength(infoFile.length);
// till now no problem, the file name is ok
OutputStream out = response.getOutputStream();
out.write(infoFile);
//here, as soon as the previous line is executed a file is generated with wrong characters
// ex. D:__Profiles__User__Downloads__infoFile.pdf
Here the file produced is something like "D:__Profiles__User__Downloads__infoFile.pdf"
while i expect the file "D:\Profiles\User\Downloads\infoFile.pdf"
What's wrong?
What's wrong?
Your expectation that the filename in a Content-disposition header should have path information.
From RFC 6266 section 4.3
Recipients MUST NOT be able to write into any location other than
one to which they are specifically entitled. To illustrate the
problem, consider the consequences of being able to overwrite
well-known system locations (such as "/etc/passwd"). One strategy
to achieve this is to never trust folder name information in the
filename parameter, for instance by stripping all but the last
path segment and only considering the actual filename (where 'path
segments' are the components of the field value delimited by the
path separator characters "" and "/").
And similarly in the Mozilla docs
The filename is always optional and must not be used blindly by the application: path information should be stripped, and conversion to the server file system rules should be done.
Basically you should only be specifying infoFile.pdf. It's up to the user which directory that file is saved in.

Coded path from getResource() doesn't work

I'm trying to get this folder
File imagesOrg = new File(getClass().getResource("/stock").getPath());
I've printed it out in console with
System.out.println(imagesOrg.getAbsolutePath());
and there is a space within my path so it was changed to %20 and because of that the rest of my code doesn't work which is:
for(final File child : imagesOrg.listFiles()) {
System.out.println(child.getName());
}
If I put the whole path in new File with a space instead of %20 it works fine is there an easy solution to this?
I recommand URL decoder.
You can use like this..
String result = java.net.URLDecoder.decode(url, "UTF-8");

Read file with whitespace in its path using Java

I am trying to open files with FileInputStream that have whitespaces in their names.
For example:
String fileName = "This is my file.txt";
String path = "/home/myUsername/folder/";
String filePath = path + filename;
f = new BufferedInputStream(new FileInputStream(filePath));
The result is that a FileNotFoundException is being thrown.
I tried to hardcode the filePath to "/home/myUserName/folder/This\\ is\\ my\\ file.txt" just to see if i should escape whitespace characters and it did not seem to work.
Any suggestions on this matter?
EDIT: Just to be on the same page with everyone viewing this question...opening a file without whitespace in its name works, one that has whitespaces fails. Permissions are not the issue here nor the folder separator.
File name with space works just fine
Here is my code
File f = new File("/Windows/F/Programming/Projects/NetBeans/TestApplications/database prop.properties");
System.out.println(f.exists());
try
{
FileInputStream stream = new FileInputStream(f);
}
catch (FileNotFoundException ex)
{
System.out.println(ex.getMessage());
}
f.exists() returns true always without any problem
Looks like you have a problem rather with the file separator than the whitespace in your file names. Have you tried using
System.getProperty("file.separator")
instead of your '/' in the path variable?
No, you do not need to escape whitespaces.
If the code throws FileNotFoundException, then the file doesn't exist (or, perhaps, you lack requisite permissions to access it).
If permissions are fine, and you think that the file exists, make sure that it's called what you think it's called. In particular, make sure that the file name does not contain any non-printable characters, inadvertent leading or trailing whitespaces etc. For this, ls -b might be helpful.
Normally whitespace in path should't matter. Just make sure when you're passing path from external source (like command line), that it doesn't contain whitespace at the end:
File file = new File(path.trim());
In case you want to have path without spaces, you can convert it to URI and then back to path
try {
URI u = new URI(path.trim().replaceAll("\\u0020", "%20"));
File file = new File(u.getPath());
} catch (URISyntaxException ex) {
Exceptions.printStackTrace(ex);
}

The compressed (zipped) folder is invalid Java

I'm trying to zip files from server into a folder using ZipOutputStream.
After archive download it can't be opened after double click. Error "The compressed (zipped) folder is invalid" occures. But if I open it from context menu - > 7zip -> open file it works normal. What can be reason of the problem?
sourceFileName="./file.txt"'
sourceFile = new File(sourceFileName);
try {
// set the content type and the filename
responce.setContentType("application/zip");
response.addHeader("Content-Disposition", "attachment; filename=" + sourceFileName + ".zip");
responce.setContentLength((int) sourceFile.length());
// get a ZipOutputStream, so we can zip our files together
ZipOutputStream outZip = new ZipOutputStream((responce.getOutputStream());
// Add ZIP entry to output stream.
outZip.putNextEntry(new ZipEntry(sourceFile.getName()));
int length = 0;
byte[] bbuf = new byte[(int) sourceFile.length()];
DataInputStream in = new DataInputStream(new FileInputStream(sourceFile));
while ((in != null) && ((length = in.read(bbuf)) != -1)) {
outZip.write(bbuf, 0, length);
}
outZip.closeEntry();
in.close();
outZip.flush();
outZip.close();
7Zip can open a wide variety of zip formats, and is relatively tolerant of oddities. Windows double-click requires a relatively specific format and is far less tolerant.
You need to look up the zip format and then look at your file (and "good" ones) with a hex editor (such as Hex Editor Neo), to see what may be wrong.
(One possibility is that you're using the wrong compression algorithm. And there are several other variations to consider as well, particularly whether or not you generate a "directory".)
It could be that a close is missing. It could be that the path encoding in the zip cannot be handled by Windows. It might be that Windows has difficulty with the directory structure, or that a path name contains a (back)slash. So it is detective work, trying different files. If you immediately stream the zip to the HTTP response, then finish has to be called i.o. close.
After the code being posted:
The problem is the setContentLength giving the original file size. But when given, it should give the compressed size.
DataInputStream is not needed, and one should here do a readFully.
responce.setContentType("application/zip");
response.addHeader("Content-Disposition", "attachment; filename=file.zip");
//Path sourcePath = sourceFile.toPath();
Path sourcePath = Paths.get(sourceFileName);
ZipOutputStream outZip = new ZipOutputStream((responce.getOutputStream(),
StandardCharsets.UTF-8);
outZip.putNextEntry(new ZipEntry(sourcePath.getFileName().toString()));
Files.copy(sourcePath, outZip);
outZip.closeEntry();
Either finish or closethe zip at the end.
outZip.finish();
//outZip.close();
in.close();
I am not sure (about the best code style) whether to close the response output stream already oneself.
But when not closing finish() must be called, flush() will not suffice, as at the end data is written to the zip.
For file names with for instance Cyrillic letters, it would be best to add a Unicode charset like UTF-8. In fact let UTF-8 be the Esperanto standard world-wide.
A last note: if only one file one could use GZipOutputstream for file.txt.gz or query the browser's capabilities (request parameters) and deliver it compressed as file.txt.

Download servlet issue with ie 6

I need to write a download servlet in java to download a file from the web server. I am setting the response parameters as follows:
resp.setContentType( (mimetype != null) ? mimetype : "application/octet-stream");
resp.setContentLength( (int)f.length() );
resp.setHeader( "Content-Disposition",
"attachment; filename=\"" + filename + "\"" );
The code seems to work fine with firefox, chrome and IE7 but with IE6 its adding "[1]" in the middle of the filename. E.g. test[1]_check.txt (instead of test_check.txt). There are no duplicate copies of the file on client side and I'm unable to understand where I'm going wrong. Is there an issue with my response parameters?
Thanks in advance
I think i understand the problem...In creating the filename of the file to be downloaded it is a concatenation of 2 strings such as : test.pdf_check.txt.
Firefox and Chrome download using the same name but IE6 inserts [1] just before the first extension it encounters (.pdf) so I get test[1].pdf_check.txt.
I removed the first extension and it seems to be working fine.
check the Temp folder:
C:\Documents and Settings\YourUserName\Local Settings\Temp
maybe there's a copy of the file from previous downloads
I don't think the problem is in setHeader(). What about the code determining the value of filename? Maybe the value is concatenated?

Categories

Resources