Uploading and downloading files is very common during development. Here is a brief summary:
1. Conditions that must be met for file upload:
a. The method of the page form must be post because the data transmitted by get is too small
b. The enctype of the page form must be of multipart/form-data type
c. The form provides details of uploading input field code: In the client form:<form enctype="multipart/form-data"/>
(If this property is not available, the file path read by the server will vary depending on the browser)
Server ServletInputStream is=request.getInputStream(); obtains the request body content in a stream for further analysis.
2. Details of uploading files:
(1) Why set the form type to: multipart/form-data. It is to set the value passed by this form that is not the key=value. What is passed is bytecode.
The correspondence between the form and the request:
As shown above, you can see that after setting the form type to: multipart/form-data, the file you selected is initialized into binary in the HTTP request body, as shown in the above picture under a random string under the cookie.
But note that there are two special lines of characters in the file bytecode divided by the identification file (i.e. a string of random strings), namely the first line of content file header and a line of blank lines. The third line after that is the binary file content.
Therefore, when the server accepts files uploaded by the client, when obtaining the file binary in the HTTP request parameters, the first three lines must be removed.
3. Manually parse the uploaded txt file:
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * If the type of a form is post and the enctype is multipart/form-date * then all data is passed to the server in binary mode. * So req.getParameter("xxx") is always null. * You can only get data through req.getInputStream() and get the data of the text* * @author wangxi * */public class UpServlet extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); String txt = req.getParameter("txt");//The return is null System.err.println("txt is :"+txt); System.err.println("========================================="); InputStream in = req.getInputStream();// byte[] b= new byte[1024];// int len = 0;// while((len=in.read(b))!=-1){// String s = new String(b,0,len);// System.err.print(s);// } BufferedReader br = new BufferedReader(new InputStreamReader(in)); String firstLine = br.readLine();//Read the first line, and the first line is a delimited symbol, that is, a random string String fileName = br.readLine();//The second line of file information, and intercept the file name from it fileName = fileName.substring(fileName.lastIndexOf("//")+1);// xxxx.txt" fileName = fileName.substring(0,fileName.length()-1); br.readLine(); br.readLine(); String data = null; //Get the running path of the current project String projectPath = getServletContext().getRealPath("/up"); PrintWriter out = new PrintWriter(projectPath+"/"+fileName); while((data=br.readLine())!=null){ if(data.equals(firstLine+"--")){ break; } out.println(data); } out.close(); }} 4. Use apache-fileupload to process file uploads:
Framework: refers to encapsulating the business that users often process in a code. Make it easy for users to call.
The (frame) component that currently uploads the file:
Apache―-fileupload-
Orialiy COS 2008() -
Jsp-smart-upload 200M.
Upload the file using fileupload:
Requires importing third-party packages:
Apache-fileupload.jar file uploads the core package.
Apache-commons-io.jar This package is a dependency package for fileupload. It's also a toolkit.
Core category:
DiskFileItemFactory Sets disk space and saves temporary files. Just a class.
ServletFileUpload - The core class for file uploads, which receives requests and parses reqeust.
ServletfileUpload.parseRequest(requdest) - List<FileItem>
Note: A FileItem is the beginning of a logo: --------243243242342 To -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Step 1: Import the package:
Step 2: Write a servlet to complete the doPost method
/** * Two parameters constructed by DiskFileItemFactory* The first parameter: sizeThreadHold - Sets how many bytes of data to save in the cache (memory), the default is 10K * If a file is not greater than 10K, you can just use memory to save it directly into a file. * If a file is greater than 10K, you need to save the file to a temporary directory first. * The second parameter File refers to the temporary directory location* */public class Up2Servlet extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTf-8"); //Get the path of the project String path = getServletContext().getRealPath("/up"); //The first step declares the diskfileitemfactory factory class, which is used to set a temporary directory on the disk, DiskFileItemFactory disk = new DiskFileItemFactory(1024*10,new File("/home/wang/")); //The second step: declare ServletFileUpoload and receive the above temporary directory ServletFileUpload up = new ServletFileUpload(disk); //The third step: parse request try { List<FileItem> list = up.parseRequest(req); //If only one file FileItem file = list.get(0); //Get the file name with path String fileName = file.getName(); fileName = fileName.substring(fileName.lastIndexOf("//")+1); //Get the file type String fileType = file.getContentType(); //Get the file's bytecode InputStream in = file.getInputStream(); //Declare the output byte stream OutputStream out = new FileOutputStream(path+"/"+fileName); //File copy byte[] b = new byte[1024]; int len = 0; while((len=in.read(b))!=-1){ out.write(b,0,len); } out.close(); long size = file.getInputStream().available(); //Delete the uploaded temporary file file.delete(); //Show data resp.setContentType("text/html;charset=UTf-8"); PrintWriter op = resp.getWriter(); op.print("File uploaded successfully<br/>File name:"+fileName); op.print("<br/>File type:"+fileType); op.print("<br/>File size (bytes)"+size); } catch (Exception e) { e.printStackTrace(); } }}5. Use this framework to upload multiple files:
Step 1: Modify the form of the page to multiple input types="file"
<form action="<c:url value='/Up3Servlet'//>" method="post" enctype="multipart/form-data"> File1: <input type="file" name="txt"><br/> File2: <input type="file" name="txt"><br/> <input type="submit"/> </form>
Step 2: traverse list
public class Up3Servlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); String path = getServletContext().getRealPath("/up"); //Declare disk DiskFileItemFactory disk = new DiskFileItemFactory(); disk.setSizeThreshold(1024*1024); disk.setRepository(new File("d:/a")); //Declare the servlet that parses the request ServletFileUpload up = new ServletFileUpload(disk); try{ //Resolve request List<FileItem> list = up.parseRequest(request); //Declare a list<map> encapsulate the data of the uploaded file List<Map<String,String>> ups = new ArrayList<Map<String,String>>(); for(FileItem file:list){ Map<String,String> mm = new HashMap<String, String>(); //Get the file name String fileName = file.getName(); fileName = fileName.substring(fileName.lastIndexOf("//")+1); String fileType = file.getContentType(); InputStream in = file.getInputStream(); int size = in.available(); //Use the tool class FileUtils.copyInputStreamToFile(in,new File(path+"/"+fileName)); mm.put("fileName",fileName); mm.put("fileType",fileType); mm.put("size","+size); ups.add(mm); file.delete(); } request.setAttribute("ups",ups); //Forward request.getRequestDispatcher("/jsps/show.jsp").forward(request, response); }catch(Exception e){ e.printStackTrace(); } }}The above is the common method of uploading files. Now let's take a look at the other search APIs of fileupload.
Determine whether a fileItem is a file (type=file) object or a text(type=text|checkbox|radio) object:
boolean isFormField() If it is text|checkbox|radio|select, the value is true.
6. Process pictures with description information
public class UpDescServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8");//You can get the Chinese file name String path = getServletContext().getRealPath("/up"); DiskFileItemFactory disk = new DiskFileItemFactory(); disk.setRepository(new File("d:/a")); try{ ServletFileUpload up = new ServletFileUpload(disk); List<FileItem> list = up.parseRequest(request); for(FileItem file:list){ //Step 1: Determine whether it is an ordinary form item if(file.isFormField()){ String fileName = file.getFieldName();//<input type="text" name="desc">=desc String value = file.getString("UTF-8");//By default, read data in ISO, System.err.println(fileName+"="+value); }else{//Indicates that it is a file String fileName = file.getName(); fileName = fileName.substring(fileName.lastIndexOf("//")+1); file.write(new File(path+"/"+fileName)); System.err.println("File name is:"+fileName); System.err.println("File size is:"+file.getSize()); file.delete(); } } }catch(Exception e){ e.printStackTrace(); } }} 7. Improved performance of file upload
When parsing the request to get the FileItem collection, use:
FileItemIterator it= up.getItemIterator(request);
Compared to use
List<FileItem> list = up.parseRequest(request);
Much better performance.
Sample code:
public class FastServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); String path = getServletContext().getRealPath("/up"); DiskFileItemFactory disk = new DiskFileItemFactory(); disk.setRepository(new File("d:/a")); try{ ServletFileUpload up = new ServletFileUpload(disk); //The following is the iterator mode FileItemIterator it= up.getItemIterator(request); while(it.hasNext()){ FileItemStream item = it.next(); String fileName = item.getName(); fileName=fileName.substring(fileName.lastIndexOf("//")+1); InputStream in = item.openStream(); FileUtils.copyInputStreamToFile(in,new File(path+"/"+fileName)); } }catch(Exception e){ e.printStackTrace(); } }} 8. Download file
It can be either get or post.
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); String name = req.getParameter("name"); //Step 1: Set the response type resp.setContentType("application/force-download"); //The second reading file String path = getServletContext().getRealPath("/up/"+name); InputStream in = new FileInputStream(path); //Set the response header//Usert url encoding of the file name name = URLEncoder.encode(name, "UTF-8"); resp.setHeader("Content-Disposition","attachment;filename="+name); resp.setContentLength(in.available()); //Step 3: Start the file copy OutputStream out = resp.getOutputStream(); byte[] b = new byte[1024]; int len = 0; while((len=in.read(b))!=-1){ out.write(b,0,len); } out.close(); in.close(); }When using J2EE popular frameworkIt is easier to use the internal encapsulation of the framework to complete upload and download:
Struts2 is uploaded.
When using Struts2 for development, it is not difficult to find that the commons-fileupload-1.3.1.jar package is present in the imported jar package. Through the above learning, we can already use it to upload and download files. But Struts2 is undergoing further encapsulation.
view
<form action="fileUpload.action" method="post" enctype="multipart/form-data"> username: <input type="text" name="username"><br> file: <input type="file" name="file"><br> <input type="submit" value="submit"> </form>
Controller
public class FileUploadAction extends ActionSupport{ private String username; //Note that file does not refer to the file itself uploaded by the front-end jsp, but the file uploaded to store private File file file under the temporary folder; //The name of the file submitted//struts will automatically intercept the name of the last file and inject it into this property private String fileFileName; //Getter and setter are saved at this time to save space @Override public String execute() throws Exception { //Save the path to uploaded file String root = ServletActionContext.getServletContext().getRealPath("/upload"); //Get temporary file input stream InputStream is = new FileInputStream(file); //Output file OutputStream os = new FileOutputStream(new File(root, fileFileName)); //Print out the file name of the uploaded file System.out.println("fileFileName: " + fileFileName); // Because file is a file stored in a temporary folder, we can print out its file name and file path to see if it is the same as the previous fileFileName System.out.println("file: " + file.getName()); System.out.println("file: " + file.getPath()); byte[] buffer = new byte[1024]; int length = 0; while(-1 != (length = is.read(buffer, 0, buffer.length))) { os.write(buffer); } os.close(); is.close(); return SUCCESS; }}First of all, we need to be clear that the file here does not really refer to the file uploaded by jsp. When the file is uploaded, struts2 will first look for the storage location specified by struts.multipart.saveDir (this is in default.properties) (default is empty). We can specify this temporary storage location in struts2 of our project.
<constant name="struts.multipart.saveDir" value="/repository"/>
If struts.multipart.saveDir is not set, the address specified by javax.servlet.context.tempdir will be used by default. The value of javax.servlet.context.tempdir is determined by the server. For example: If the context of my web project is abc and the server uses Tomcat, then savePath should be %TOMCAT_HOME%/work/Catalina/localhost/abc_. The name of the temporary file is similar to upload__1a156008_1373a8615dd__8000_00000001.tmp. The temporary file name may be different each time, but it is roughly in this style. And if you use Servers in Eclipse to configure Tomcat and start, then the %TOMCAT_HOME% in the above address will not be the actual Tomcat root directory in the system, but will be the address specified by Eclipse. For example, my local address is as follows: /home/wang/EclipseJavaCode/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/work/Catalina/localhost/abc/upload__1a156008_1373a8615dd__8000_00000001.tmp.
Struts2 is finished downloading.
Download the struts2 file more simply, just define an input stream and write the file into the input stream. The key configuration is still to configure it in the struts.xml configuration file:
public class FileDownloadAction extends ActionSupport{ //The path to download the file on the server private String path; //The file name of the file to download private String downloadFileName; //Write getter and setter public InputStream getDownloadFile() { return ServletActionContext.getServletContext().getResourceAsStream(path); } @Override public String execute() throws Exception { //The current action is setDownloadFileName(xxx); return SUCCESS; }}The action just defines an input stream downloadFile and then provides it with a getter method. Next, let's take a look at the configuration file of struts.xml:
<action name="fileDownload"> <result name="download" type="stream"> <param name="contentDisposition">attachment;fileName="${downloadFileName}"</param> <param name="inputName">downloadFile</param> </result> </action>There are several places where we need to pay attention to the struts.xml configuration file. First, the type must be defined as stream type_, telling action this is the result of file download. The result element generally has a param sub-element. This is used to set the parameters when downloading the file. The inputName attribute is to obtain the file input stream in the action. The name must be the same as the input stream attribute in the action. Then the contentDisposition attribute. This attribute is generally used to specify how we want to process the downloaded file. If the value is attachment, a download box will pop up, allowing the user to choose whether to download. If this value is not set, the browser will first check whether to open the downloaded file. If it can, it will directly open the downloaded file (of course it is not what we need). Another value is filename, which is the file download name prompted by the file when downloading. After configuring this information, we can implement the file download function.
SpringMVC completes upload:
The view is exactly the same as the struts2 example. This is not written.
Controller:
@Controller@RequestMapping(value="fileOperate")public class FileOperateAction { @RequestMapping(value="upload") public String upload(HttpServletRequest request,@RequestParam("file") MultipartFile photoFile){ //The path to upload file save String dir = request.getSession().getServletContext().getRealPath("/")+"upload"; //The original file name String fileName = photoFile.getOriginalFilename(); //Get the file extension String extName = fileName.substring(fileName.lastIndexOf(".")); //Prevent file name conflicts, slightly modify the name fileName = fileName.substring(0,fileName.lastIndexOf("."))) + System.nanoTime() + extName; FileUtils.writeByteArrayToFile(new File(dir,fileName),photoFile.getBytes()); return "success"; } }SpringMVC complete download:
@RequestMapping("/download") public String download(String fileName, HttpServletRequest request, HttpServletResponse response) { response.setCharacterEncoding("utf-8"); response.setContentType("multipart/form-data"); response.setHeader("Content-Disposition", "attachment;fileName=" + fileName); try { InputStream inputStream = new FileInputStream(new File(path of the file); OutputStream os = response.getOutputStream(); byte[] b = new byte[2048]; int length; while ((length = inputStream.read(b)) > 0) { os.write(b, 0, length); } // It is mainly closed here. os.close(); inputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // Be careful when returning the value, otherwise the following error will appear! //java+getOutputStream() has already been called for this response return null; }The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.