File upload and download is a common problem in web development, these days in a project and use the file download, before also fragmented notes, today to do a finishing. The file upload still needs to be tested further, here first to say the file download.
First, the file download processing process
The file download process is actually very clear, namely:
1, according to the file name or file path location files, the specific strategy according to their own needs, in short, the system can find the full path of the file.
2. Get the input stream and get the input stream from the target file.
3. Get the output stream and get the output stream from the response.
4. Read the file from the input stream and output the file through the output stream. This is the real download execution process.
5. Close IO stream.
The main process is this, and also some of the necessary property settings, such as the more important contenttype type of set file.
Second, not wordy, on the code
I do it with SPRINGMVC, but its practical and other, the main need HttpServletResponse object and valid target file.
1. Front Code
/* * Download uploaded file */function downloadfromupload (fileName) {window.location.href = path + "/download?dir=upload&filename= "+encodeuri (encodeURI (FileName));} /* * Normal download */function download (fileName) {window.location.href = path + "/download?dir=download&filename=" +encodeuri (encodeURI (FileName));}
2. Controller code
/** * file Download (download from upload path) * * @param request * @param response * @throws IOException * * @ResponseB Ody@requestmapping (value = "/download") public void DownloadFile (HttpServletRequest request,httpservletresponse Response, Filemodel model) throws Exception {String fileName = Urldecoder.decode (Model.getfilename (), "UTF-8");/* * Limit only U Files in the pload and download folders can be downloaded */string folderName = "Download"; Stringutils.isempty (Model.getdir ()) && Model.getdir (). Equals ("Upload")) {folderName = "upload";} else { FolderName = "Download";} String Fileabsolutepath = Request.getsession (). Getservletcontext (). Getrealpath ("/") + "/web-inf/" + folderName + "/" + FileName; Filetools.downloadfile (Request, response, Fileabsolutepath); Log.warn ("User id:" + (Integer) (Request.getsession ().) GetAttribute ("UserId")) + ", User name:" + (String) (Request.getsession (). getattribute ("username")) + ", downloaded file:" + Fileabsolutepath);}
The download logic here is that the foreground only needs to request/download, and give the filename parameters. In order to avoid Chinese garbled characters, the foreground file name is used as the parameter, the JS encodeURI () is converted into Unicode code, then the background decoding is translated into Chinese. In addition, due to the particularity of the project, the files I want to download here may be in upload and download two folders, so there is a part of the judgment logic. In addition, I have encapsulated the file name and the requested folder name in Filemodel.
3, download the logic implementation. There is no service, and the static method is implemented directly.
/** * Specify download name when downloading file * * @param request * HttpServletRequest * @param * response * HttpServletResponse * @param filePath * File full path * @param filename * Specifies the file name displayed when the client downloads * @throws IOException */public static Voi D downloadFile (httpservletrequest request,httpservletresponse Response, String FilePath, String fileName) throws IOException {Bufferedinputstream bis = null; Bufferedoutputstream BOS = Null;bis = new Bufferedinputstream (new FileInputStream (FilePath)); bos = new Bufferedoutputstream (Response.getoutputstream ()); Long filelength = new File (filePath). Length (); Response.setcharacterencoding ("UTF-8"); Response.setcontenttype ("Multipart/form-data");/* * Solve the Chinese garbled problem of each browser */string useragent = Request.getheader ("user-agent"); byte[] bytes = Useragent.contains ("MSIE")? Filename.getbytes (): Filename.getbytes ("UTF-8"); Filename.getbytes ("UTF-8") handles Safari's garbled problem filename = new String (bytes, "iso-8859-1"); Each browser basically supports ISO-encoded response.setheader ("Content-disposition", String.Format ("attachment; Filename=\ "%s\", "FileName"), Response.setheader ("Content-length", String.valueof (Filelength)); byte[] buff = new byte [2048];int bytesread;while ( -1! = (bytesread = bis.read (buff, 0, buff.length))) {bos.write (buff, 0, bytesread);} Bis.close (); Bos.close ();} /** * Download file does not specify the download file name * * @param request * HttpServletRequest * @param * response * httpservletrespons E * @param filePath * File full path * @throws ioexception */public static void DownloadFile (HttpServletRequest request, HttpServletResponse response, String FilePath) throws IOException {File File = new file (filePath);d ownloadfile (Request, R Esponse, FilePath, File.getname ());}
An overloaded download method is provided to resolve the need to specify the file name that is sometimes required to be downloaded by the client.
Third, the matters needing attention
1. About MIME type selection
Before the MIME type is not very understanding, found that there are many downloaded source code on the Internet MIME type settings are not the same. That is the sentence
Response.setcontenttype ("Multipart/form-data");
Check it out. One effect of setting the MIME type is to tell the client browser in what format to process the file to be downloaded. The specific corresponding online has a lot of explanations, this class I set up in this format, generally will automatically match the format.
2. Specify the client download file name
Sometimes we may need to specify the file name when the client downloads the file, which is the code
Response.setheader ("Content-disposition", String.Format ("attachment; Filename=\ "%s\", "fileName");
The filename in the, can be customized. The front section generally does not move.
3, the Chinese garbled problem solves
Chinese file garbled is too common, when the project system architecture was just built, it should be unified all the Chinese code, including the editor, the page and the database, recommended UTF-8 encoding. If you use spring, you can also configure spring's character set filter to further avoid Chinese garbled characters.
(1) Client download request process file name garbled
Sometimes we will encounter, the front page display Chinese file name download list is normal, but we found in the background of the request file name garbled, then use the encodeURI mentioned above can be resolved.
(2) file name garbled during client download execution
In the actual test, it is found that in the case of other browsers can be executed, the Chinese file name under IE may appear garbled. On the internet to see such a piece of code, tested, the perfect solution to the different browsers of Chinese garbled problem
/* * Solve the Chinese garbled problem of each browser */string useragent = Request.getheader ("user-agent"); byte[] bytes = Useragent.contains ("MSIE")? Filename.getbytes (): Filename.getbytes ("UTF-8"); Filename.getbytes ("UTF-8") handles Safari's garbled problem filename = new String (bytes, "iso-8859-1"); Each browser basically supports ISO-encoded response.setheader ("Content-disposition", String.Format ("attachment; Filename=\ "%s\", "fileName");
(3) Garbled files on the server
Different servers may have different encoding methods depending on the platform, which should also be noted here. For a specific solution, please refer to an article previously written: Chinese garbled handling during file download
Original works, reproduced please indicate the source.
Java web File download file download implementation and garbled processing