views:

211

answers:

1

Background:

I have a file which I upload, during this process the link of the file is stored in the database and not the actual file, acutal file is stored in the File System, currently am storing it in my local machine.

Goal:

My goal is to upload a file and download a file properly which has special characters in it - #,$,%,@ etc.

Issue:

I am able to upload the file with special character but am not able to download file with special characters. Also I cannot do any changes in the Download Servlet as it is part of the Framework, so all I can work with is the Upload Servlet, so my focus is to upload file with special characters in such a way so that I can download them.

I have tried creating an alias for the filename where in am replacing the special characters with '_' symbol, this approach works fine and am able to download the file but actual name of file is not maintained in here, all special characters in the filename are replaced by '_' symbol and this is not acceptable as user should actual name of the file.

Any suggestions or approach:

Code:

public ModelAndView save(HttpServletRequest request, HttpServletResponse response, Object command, 
                        ModelAndView modelView, BindException errors) throws Exception {

String newFileName = checkForSpecialCharsAndGetNewFileName(file.getOriginalFilename());
System.out.println("alias filename="+ newFileName);
String    url = "f" + (String.valueOf(System.currentTimeMillis())) + "_" + newFileName;
String    fileName = file.getOriginalFilename(); 
System.out.println("FileName "+ fileName);
}

//Code to replace all special characters in the incoming file with '_' symbol. 
private String checkForSpecialCharsAndGetNewFileName (String originalFileName) {
  final String[] splChars = {"#", "+", "$"};
  String newString = originalFileName;
  for (int i=0; i<splChars.length; i++)
    newString = StringUtils.replace(newString, splChars[i], "_");
  return newString;
}

Hope am making some sense here.

Thanks.

+1  A: 

If I am understanding you correctly, you want to encode the filename such that when you upload it, and later download it, you want to be able to find the same file from the file name.

To do this, you can use URLEncoder and URLDecoder classes.

You can do this doing something like the following:

String fileName;
fileName = URLEncoder.encode("My ! String #", "UTF-8");

That will encode it. To get the original file name:

String originalFileName = URLDecoder.decode(fileName, "UTF-8");

You can use the encoded file name to download the file from the service. You can then decode the file name to store it appropriately.

Hope that helps.

aperkins
This is what I was looking at but when as I said I cannot do any modification the download Servlet as it is part of the framework. I am just having a reference to download servlet from my jsp file, so even if am encoding it in the upload servlet than also I cannot decode in download servlet, is there a way I can somehow have decoding logic in the jsp file prior to making call to download servlet ?
Rachel
When you call the download servlet, are you not sending it a file name? If you are, you can encode the file name before you send it. If you are not, how is the servlet getting the file name to download?
aperkins
Rachel
and the attachments.url is being passed by the system you are writing?
aperkins
how can i encode ${attachments.url} to pass actual file name to the servlet if am url decoding it in the first place with the upload servlet ?
Rachel
yes attachments.url is passed as a part of framework.
Rachel
@aperkins: How can I decode a URL in JSP, is that possible and if yes than what approach needs to be taken for it ?
Rachel
I am not completely sure what is going on there - is the html you posted part of the jsp code? Because that html looks like it is being worked using javascript or something similar. If you are generating the value that goes into ${attachments.url} then you could generate that url using, in part, the url encoder.
aperkins
yes, it is the html code that is part of the jsp page. I will check on the approach and post the results.
Rachel
so, I am assuming (not particularly well versed in jsp), that you have code that is referencing the attachments.url - setting the value in there. You should be able to change the value to be encoded or decoded, as appropriate.
aperkins
yes you are correct, jsp page has a href call to download servlet where in it is passing attachments.url as parameter to it and somehow framework is responsible for properly populating the parameters for the download servlet. My question is that if am encoding the special characters in upload servlet than does it make sense to decode it before making call to download servlet or we should decode it once we are making call to download servlet. I hope am able to explain my dilemma clearly.
Rachel
You want to use the encoded url - the encoded version is the version that will be stored out on the server where you will be downloading.
aperkins
Ok. I am getting url information from attachments.java class using `public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } and now I want to encode it and so it should be like public void setUrl(String url) {this.url = URLEncoder.encode(url); },` is this correct way of doing it ?
Rachel
If the URL is unencoded before you pass it in, then yes. Note that the URLEncoder should only be encoding the piece that is the file name - something like the following: public void setUrl(String url) { this.url = urlContext + URLEncoder.encode(fileName); } - i.e. you encode the file name, and append it to the rest of the context
aperkins
If I say my url is something like `f1278962816412_TestDoc.doc` before encoding than what would be urlContext in here ? I am under the impression that public void setUrl(String url) { this.url = URLEncoder.encode(f1278962816412_TestDoc.doc); } would do the work for me. Is this not correct and what does urlContext is referring to in here ?
Rachel
ahh, I see. I thought that the url variable included the internet context - it sounds like it does not in your system (this is very implementation dependent). If this is true, then your example should work just fine.
aperkins
Specifically, I would test it out - and probably log what is going on, so you can see it. That will tell you more about it at this point - there are likely some gotchas or subtle pieces that we are not seeing at this stage.
aperkins
Yes. You are right. I am testing it out on my local box to understand more of but one question I have is that is it somehow possible to do encoding in the JSP itself rather than doing it in the .java class as java class has getter and setters only and also does it make any difference if we do encoding on the jsp page vs java or vice-versa ?
Rachel
I am not particularly familiar with jsp's - my understanding is you can run the code there, but I am not positive at this point. You could do the conversion on the setter of the URL value, but that may have unforseen side effects.
aperkins
I did modified in the java class but now for file name test#attachments.docx, value in database is stored as test%23attachments.docx but when I click the download button it is looking for test%2523attachments.docx for the value and it is not able to find it and so gives cannot find error. Not sure from where am getting extra 25 value in the encoded version when I click the Download button.
Rachel
It sounds like the jsp may already be encoding the url - you could try sending it in unencoded.
aperkins
Rachel
the upload controller is probably already sanitizing - encoding - the file name, and it sounds like the download controller is doing it as well. Beyond that, I am not entirely sure - someone who has more knowledge of the JSP architecture you are using could likely give you a more complete answer.
aperkins
Ok. Thank you Aperkins for all your help and guidance with the matter.
Rachel
+1 for perseverance!
trashgod