File upload and download
File upload and download are very common functions. Many systems or software often use file upload and download.
For example:
QQ avatar is uploaded.
The mailbox also has the function of uploading and downloading attachments.
Upload of approved attachment materials in OA system.
File upload
- To have a form tag, method=post request
- The value of the encType attribute of the form tag must be a multipart / form data value
- Use input type=file in the form tag to add the uploaded file
- Write server code (Servlet program) to receive and process the uploaded data.
Enctype = multipart / form data indicates the submitted data, which is spliced in the form of multiple segments (one data segment for each form item), and then sent to the server in the form of binary stream
commons-fileupload.jar common API introduction
commons-fileupload.jar needs to rely on Commons io Jar package, so we need to introduce both packages.
commons-fileupload.jar and Commons io In the jar package, what are the commonly used classes?
-
The ServletFileUpload class is used to parse the uploaded data.
-
FileItem class, representing each form item.
-
boolean ServletFileUpload.isMultipartContent(HttpServletRequest request);
-
Judge whether the currently uploaded data format is multi segment format.
-
public List< FileItem > parseRequest(HttpServletRequest request)
-
Analyze uploaded data
-
boolean FileItem.isFormField()
-
Judge whether the current form item is an ordinary form item. Or the type of file uploaded.
-
true indicates a common type of form item
-
false indicates the type of file uploaded
-
String FileItem.getFieldName()
-
Gets the value of the name attribute of the form item
-
String FileItem.getString()
-
Gets the value of the current form item.
-
String FileItem.getName();
-
Get the uploaded file name
-
void FileItem.write( file );
-
Write the uploaded file to the hard disk location pointed to by the parameter file.
Use of fileupload class library
Form for uploading files:
<form action="http://localhost:8080/05_EL_JSTL/upload" method="post" enctype="multipart/form-data"> user name:<input type="text" name="username"><br> head portrait:<input type="file" name="phtot"><br> <input type="submit" value="upload"> </form>
Code for parsing uploaded data:
public class UploadServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1. Judge whether the uploaded data is multi segment, and the multi segment data is the file uploaded if(ServletFileUpload.isMultipartContent(request)){ //2. Create FileItemFactory factory implementation class FileItemFactory dfif = new DiskFileItemFactory(); //3. Create a tool class ServletFileUpload class for parsing uploaded data ServletFileUpload sfu = new ServletFileUpload(dfif); //4. Parse the uploaded data to get each form item FileItem try { List<FileItem> list = sfu.parseRequest(request); //5. Cycle to judge whether each form item is a common type or an uploaded file for (FileItem fileItem : list) { if(fileItem.isFormField()){ //Normal form System.out.println("Of form items name Attribute value:"+fileItem.getFieldName()); //UTF-8 solves garbled code System.out.println("Of form items value Attribute value:"+fileItem.getString("UTF-8")); }else{ System.out.println("Uploaded name Attribute value:"+fileItem.getFieldName()); System.out.println("Uploaded file name:"+fileItem.getName()); try { fileItem.write(new File("E:\\"+fileItem.getName())); } catch (Exception e) { e.printStackTrace(); } } } } catch (FileUploadException e) { e.printStackTrace(); } } } }
File download
Common API descriptions downloaded:
- response.getOutputStream();
- servletContext.getResourceAsStream();
- servletContext.getMimeType();
- response.setContentType();
response.setHeader("Content-Disposition", "attachment; fileName=1.jpg");
This response header tells the browser. This needs to be downloaded. Attachment refers to an attachment, that is, a downloaded file. fileName = is followed by the name of the downloaded file.
After completing the above two steps, there is no problem downloading the file. But if the file we want to download is Chinese name. You will find that the download is not correct
The correct Chinese name is displayed because the response header cannot contain Chinese characters, but only ASCII code.
public class DownLoadServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1. Get the file name to download String downLoadFileName = "test.png"; //2. Read the content to be downloaded, which can be read through the servletContext object ServletContext servletContext = getServletContext(); //3. Get the file type to download String mimeType = servletContext.getMimeType("/file/"+downLoadFileName); System.out.println("type:"+mimeType); //4. Set the response header to tell the client the returned data type response.setContentType(mimeType); //5. Tell the client that the data received is for downloading (if not set, it will be displayed directly) //The corresponding header of content disposition indicates how to handle the received data //Attachment means attachment //fileName indicates the file name of the specified download response.setHeader("Content-Disposition","attachment; fileName=test.png"); // /The slash is resolved by the server to indicate that the address is http://ip:port/ Project name / web Directory mapped to code InputStream resourceAsStream = servletContext.getResourceAsStream("/file/"+downLoadFileName); //6. Obtain the corresponding output stream OutputStream outputStream = response.getOutputStream(); //7. Read all data in the input stream, copy it to the output stream and output it to the client IOUtils.copy(resourceAsStream, outputStream); } }
Attachment Chinese name garbled code solution
Scheme I
URLEncoder
// UTF-8 encoding the Chinese name. String str = "attachment; fileName=" + URLEncoder.encode("chinese.jpg", "UTF-8"); // Then set the encoded string into the response header response.setHeader("Content-Disposition", str);
Scheme II
At this time, the request header content disposition: attachment; Filename = Chinese name
The code becomes: content disposition: attachment; filename==? charset? B? xxxxx?=
=?charset?B?xxxxx?= Now let's explain this paragraph. =? Indicates the beginning of the encoded content charset B Represents a character set, B express BASE64 code xxxx Represents the file name BASE64 Encoded content ?= Indicates the end of the encoded content
BASE64Encoder:
// After BASE64 encoding using the following format String str = "attachment; fileName=" + "=?utf-8?B?" + new BASE64Encoder().encode("chinese.jpg".getBytes("utf-8")) + "?="; // Set to response header response.setHeader("Content-Disposition", str);
Select different codes according to different browsers
We only need to judge what browser it is by judging the browser information carried by the user agent in the request header.
String ua = request.getHeader("User-Agent"); // Determine whether it is Firefox if (ua.contains("Firefox")) { // After BASE64 encoding using the following format String str = "attachment; fileName=" + "=?utf-8?B?" + new BASE64Encoder().encode("chinese.jpg".getBytes("utf-8")) + "?="; // Set to response header response.setHeader("Content-Disposition", str); } else { // UTF-8 encoding the Chinese name. String str = "attachment; fileName=" + URLEncoder.encode("chinese.jpg", "UTF-8"); // Then set the encoded string into the response header response.setHeader("Content-Disposition", str); }