File upload and download are common problems encountered in web development. In the past few days, file download has been used in a project. I have also taken some notes in a scattered manner before. Today I will organize it. File uploading needs further testing, let’s talk about file download first.
1. File download processing process
The file download process is actually very clear, that is:
1. Locate files based on file name or file path. The specific strategy is mainly based on your own needs. In short, the full path of files that the system can find is required.
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. Turn off the IO stream.
This is the main process, and there are some necessary attribute settings, such as the more important contentType type of the setting file, etc.
2. Don't talk anymore, add the code
I did it with Springmvc, but in fact, the same is true for other things. I mainly need HttpServletResponse object and valid target file.
1. Front desk code
/** Download the 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 the upload path)* * @param request* @param response* @throws IOException*/@ResponseBody@RequestMapping(value = "/download")public void downloadFile(HttpServletRequest request,HttpServletResponse response, FileModel model) throws Exception {String fileName = URLDecoder.decode(model.getFileName(), "UTF-8");/** Restrict only files in the upload and download folders can be downloaded */String folderName = "download";if (!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("UserId:"+ (Integer) (request.getSession().getAttribute("userId"))+ ",Username: "+ (String) (request.getSession().getAttribute("username"))+ ",Downloaded file:" + fileAbsolutePath);}The download logic here is that the front desk only needs to request/download and give the file name parameters. In order to avoid Chinese garbled code, when the foreground file name is used as a parameter, it uses js' encodeURI() to change it into Unicode code, and then decodes it into Chinese. In addition, due to the special nature of the project, the files I want to download here may be in the upload and download folders, so there is a part of the judgment logic here. In addition, I encapsulate both the file name and the requested folder name in FileModel.
3. Download logic implementation.
There is no service here, but it is directly implemented using static methods.
/*** Specify the download name when downloading the file * * @param request* HttpServletRequest* @param response* HttpServletResponse* @param filePath* Full path of the file* @param fileName* Specify the file name displayed when the client downloads* @throws IOException*/public static void 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 scrambled code problems in safari fileName = new String(bytes, "ISO-8859-1"); // All browsers basically support ISO encoding 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();}/*** The download file name is not specified when downloading the file* * @param request* HttpServletRequest* @param response* HttpServletResponse* @param filePath* Full path of the file* @throws IOException*/public static void downloadFile(HttpServletRequest request,HttpServletResponse response, String filePath) throws IOException {File file = new File(filePath);downloadFile(request, response, filePath, file.getName());}Here is an overloaded download method to solve the need to sometimes specify the file name downloaded by the client.
3. Things to note
1. About the choice of MIME type
I didn't know much about MIME types before, but I found that there are many downloaded source codes on the Internet that have different settings. That is this sentence
response.setContentType("multipart/form-data");I checked that one of the functions of setting the MIME type here is to tell the client browser to process the file to be downloaded in in what format. There are many explanations on the specific corresponding website. If this type of class I is set in this format, the format will generally be automatically matched.
2. Specify the client download file name
Sometimes we may need to specify the file name when the client downloads the file, that is, this code
response.setHeader("Content-disposition", String.format("attachment; filename=/"%s/"", fileName));
fileName in it can be customized. The front part should not be moved.
3. Solve the problem of garbled Chinese
It is too common for Chinese files to be garbled. When the project system architecture is first built, all Chinese encodings should be unified, including in the editor, page and database. UTF-8 encoding is recommended. If you are using Spring, you can also configure Spring's character set filter to further avoid Chinese garbled code.
(1) The file name of the client download request process is garbled
Sometimes we encounter it. When the front desk page displays the Chinese file name download list, it is normal, but when we go to the background, we find that the file name in the request is garbled. At this time, we can use the encodeURI mentioned above to solve the problem.
(2) File name garbled when the client downloads and executes
In actual tests, it was found that when other browsers can execute, the Chinese file name under ie may appear garbled. I saw such a piece of code online. After testing, it perfectly solved the problem of Chinese garbled in different browsers.
/** 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 the garbled problem of safari fileName = new String(bytes, "ISO-8859-1"); // All browsers basically support ISO encoding response.setHeader("Content-disposition",String.format("attachment; filename=/"%s/"", fileName));(3) File garbled on the server
Different servers may also be different depending on the platform, so you need to pay attention to it here. For specific solutions, please refer to an article I wrote before: Chinese garbled processing during file downloading.
The above is the Java Web implementation file download and garbled processing method introduced to you by the editor. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support to Wulin.com website!