Java Web----File Upload

Source: Internet
Author: User
Tags save file

1 File upload requirements for the page

    • You must use a form, not a hyperlink;
    • The method of the form must be a post, not a get;
    • The enctype of the form must be multipart/form-data;
    • Add a File form field to the form, that is, <input type= "file" .../>

  <body>     <form action= "<c:url value= '/uploadservlet01 '/>" method= "post" enctype= "multipart/ Form-data ">     name: <input type=" text "name=" username "><br/>     photos: <input type=" file "Name=" Phone "><br/>          <input type=" Submit "value=" Submission "/>     </form>  </body>

2 Comparison of File upload form and normal text form differences

See the difference between "File upload form" and "Plain text form" with HttpWatch.

File Upload form enctype= "Multipart/form-data", representing the multi-part form data;

Normal text forms can not set the Enctype property:

    • When method= "POST", the default value of Enctype is application/x-www-form-urlencoded, which means using the URL encoding body;
    • When method= "Get", the default value of Enctype is null, there is no body, so there is no need to enctype.

Specific different can grab the package view

3 File upload requirements for Servlets

First, we must be certain that the data of the file upload form is also encapsulated in the request object.

the Request.getparameter (String) method gets the specified form field character content, but the file upload form is no longer a character content, but a byte content, so it is invalidated.

You can then use the request's getInputStream () method to get the ServletInputStream object, which is a subclass of InputStream, This ServletInputStream object corresponds to the body part of the entire form (starting with the first divider, to the end), which illustrates the data that we need to parse the stream. Of course parsing it is a very troublesome thing, and Apache has helped us to provide the tools to parse it: commons-fileupload.

Package Com.cug.upload;import Java.io.ioexception;import Javax.servlet.servletexception;import Javax.servlet.servletinputstream;import Javax.servlet.http.httpservlet;import Javax.servlet.http.httpservletrequest;import Javax.servlet.http.httpservletresponse;import Org.apache.commons.io.ioutils;public class UploadServlet01 extends httpservlet{@Overrideprotected void DoPost ( HttpServletRequest req, HttpServletResponse resp) throws Servletexception, IOException {req.setcharacterencoding (" Utf-8 "); Resp.setcontenttype (" Text/html;charset=utf-8 "); ServletInputStream in = Req.getinputstream (); String s = ioutils.tostring (in); System.out.println (s);}}

4 Commons-fileupload

Why use FileUpload:

There are more requirements to upload files, you need to remember:

    • Must be a post form;
    • The enctype of the form must be multipart/form-data;
    • Add a File form field to the form, that is, <input type= "file" .../>

Requirements for Servlets:

    • You can no longer use Request.getparameter () to obtain form data;
    • You can use Request.getinputstream () to get all the form data, not the data for a single form item;
    • This means that we do not use fileupload, we need to Request.getinputstream () of the content to parse!!!

4.1 fileupload Overview

FileUpload is an upload component provided by Apache's Commons component. Its main job is to help us resolve request.getinputstream ().

The jar packages required by the FileUpload component are:

    • Commons-fileupload.jar, core pack;
    • Commons-io.jar, dependent packages.

4.2 FileUpload Simple Application

The core classes of FileUpload are: Diskfileitemfactory, Servletfileupload, Fileitem.

The steps for using the FileUpload component are as follows:

    • Create a factory Class Diskfileitemfactory object: Diskfileitemfactoryfactory = new Diskfileitemfactory ()
    • To create a parser object using the factory: servletfileupload fileUpload = new Servletfileupload (Factory)
    • To parse the request object with a parser: List<fileitem>list = fileupload.parserequest (Request)

Introduce Fileitem class, it is the final result we want. A Fileitem object corresponds to a single Form item (form field). There are file fields and normal fields in a form, you can use the Isformfield () method of the Fileitem class to determine whether a form field is normal, or a file field if it is not a normal field.

    • String getName (): Gets the file name of the file field;
    • String getString (): Gets the contents of the field, if it is a file field, then gets the contents of the file, of course, the uploaded file must be a text file;
    • String getfieldname (): Gets the field name, for example: <inputtype= "text" name= "username"/>, and returns username;
    • String getContentType (): Gets the type of uploaded file, for example: Text/plain.
    • int GetSize (): Gets the size of the uploaded file;
    • Boolean Isformfield (): Determines whether the current form field is a normal text fields, or False if the description is a file field;
    • InputStream getInputStream (): Gets the input stream corresponding to the uploaded file;
    • VOID write: Saves the uploaded file to the specified file.

4.3 Simple Upload Example

<form action= "${pagecontext.request.contextpath}/fileuploadservlet" method= "post" enctype= "Multipart/form-data ">    user name: <input type=" text "name=" username "/><br/>    file 1:<input type=" file "name=" File1 "/ ><br/>    <input type= "Submit" value= "Submission"/>    </form>

public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, IOException {// Because you want to print with response, set its encoding response.setcontenttype ("Text/html;charset=utf-8");//Create factory diskfileitemfactory dfif = new Diskfileitemfactory ();//Use factory to create parser object Servletfileupload fileUpload = new Servletfileupload (DFIF); try {// Use the parser object to parse the request, get the Fileitem list list<fileitem> lists = Fileupload.parserequest (request);//traverse all the form items for (fileitem Fileitem:list) {//If the current form item is a normal form item if (Fileitem.isformfield ()) {//Gets the field name of the current form item string fieldName = Fileitem.getfieldname () ///If the field name of the current form item is Usernameif (Fieldname.equals ("username")) {//Prints the contents of the current form item, that is, what the user entered in the Username form Item Response.getwriter () . Print ("Username:" + fileitem.getstring () + "<br/>");}} else {//If the current form item is not a normal form item, the description is the file field string name = Fileitem.getname ();//Gets the name of the uploaded file//If the uploaded file name is empty, then no upload file is specified if (name = = NULL | | Name.isempty ()) {continue;} Get the real path, corresponding to the ${project directory}/uploads, of course, this directory must exist string savepath = This.getservletcontext (). Getrealpath ("/uploads");// Through the uploads directory andThe file name to create the files object File File = new file (savepath, name);//Save the uploaded file to the specified location fileitem.write (file);//Print the name of the uploaded file Response.getwriter ( ). Print ("Upload filename:" + name + "<br/>");//print Upload file size response.getwriter (). Print ("Upload file Size:" + fileitem.getsize () + "< Br/> ");//print Upload file Type Response.getwriter (). Print (" Upload file type: "+ fileitem.getcontenttype () +" <br/> ");}}} catch (Exception e) {throw new Servletexception (e);}}
5 Details of File upload

5.1 Put the uploaded files in the Web-inf directory

If the user uploaded files are not stored in the Web-inf directory, then users can directly access the uploaded files through the browser, which is very dangerous.

If the user uploads a a.jsp file, and then the user accesses the a.jsp file through a browser, the content in the a.jsp is executed, if the A.JSP has the following statement:runtime.getruntime (). EXEC (" Shutdown–s–t 1 "); then you will ...

Usually we will create a uploads directory under the Web-inf directory to hold the uploaded file, and finding this directory in the servlet requires using the ServletContext Getrealpath (String) method. For example, in my Upload1 project, there are the following statements:

Servletcontextservletcontext = This.getservletcontext ();

String savepath= Servletcontext.getrealpath ("/web-inf/uploads");

Where Savepath is: F:\tomcat6_1\webapps\upload1\WEB-INF\uploads.

5.2 File name (full path, file name)

Using a different browser test, where IE6 will return the full path of the uploaded file, do not know what IE6 is doing, this has brought us a lot of trouble, is to deal with this problem.

It is also very simple to deal with this problem, whether or not it is the full path, we are going to intercept the last "\ \" After the content is OK.

String name = File1fileitem.getname (), int lastIndex = name.lastindexof ("\ \");//Gets the position of the last "\" if (lastIndex! =-1) {//Note, If it is not the full path, there will be no "\" presence. Name = name.substring (LastIndex + 1);//Gets the file name}response.getwriter (). print (name);
5.3 Chinese garbled problem

the upload file name contains Chinese :

When the name of the uploaded person contains Chinese, the encoding needs to be set, and the Commons-fileupload component provides us with two ways to set the encoding:

    • Request.setcharacterencoding (String): This is the way we are most familiar with;
    • Fileupload.setheaderencdoing (String): This method has a higher priority than the previous one.

The file content of the uploaded file contains Chinese:

Usually we don't need to worry about uploading files, because we will save the uploaded files to the hard drive! In other words, what the file is like, to the server side or what it looks like!

But if you have the need to display the uploaded file content in the console, you can use Fileitem.getstring ("Utf-8") to process the encoding.

The text file contents and normal form item contents use the Fileitem class's GetString ("Utf-8") to process the encoding.


5.4 Uploading files with the same name problem (file rename)

Usually we will save the user uploaded files to the uploads directory, but if the user uploaded the same name file? This can occur when the overlay is in effect. The way to deal with this problem is to use the UUID to generate a unique name, and then use the original name of the "_" Connection file to upload.

For example, a user uploads a file that is "my one inch photo. jpg", after being processed, the filename is called: "891b3881395f4175b969256a3f7b6e10_ my one inch photo. jpg", this method does not cause the file to lose the extension, and because of the uniqueness of the UUID, The uploaded file has the same name, but there is no problem with the same name on the server side.

public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, IOException { Request.setcharacterencoding ("Utf-8");D iskfileitemfactory dfif = new Diskfileitemfactory (); Servletfileupload fileUpload = new Servletfileupload (DFIF); try {list<fileitem> List = fileupload.parserequest ( request);//Gets the second form item because the first form item is username, and the second is the file form item Fileitem Fileitem = List.get (1); String name = Fileitem.getname ();//Gets the file name//If the client is using IE6, it needs to get the file name from the full path int lastIndex = Name.lastindexof ("\ \"); if ( LastIndex! =-1) {name = name.substring (LastIndex + 1);} Gets the saved directory of the uploaded file string savepath = This.getservletcontext (). Getrealpath ("/web-inf/uploads"); String uuid = Commonutils.uuid ();//generate uuidstring filename = uuid + "_" + name;//new file name is UUID + underscore + original name//create file object, the following will upload files Save to the path specified by this file//savepath, that is, the upload file of the Save directory//filename, the file name files = "New File" (Savepath, filename);//Save the file Fileitem.write ( file);} catch (Exception e) {throw new Servletexception (e);}}

5.5 A directory cannot hold too many files (the directory is scattered)

Here we use the hash algorithm to break up:

    • Get the file name of Hashcode:int Hcode = Name.hashcode ();;
    • Gets the low 4 bits of the Hcode, and then converts the 16 characters into a binary character;
    • Gets the 5~8 bit of the Hcode, and then converts it to 16 binary characters;
    • Generate a catalog chain using these two 16-character characters. For example, a low 4-bit character is "5"

The advantage of this algorithm is that up to 16 directories are generated in the uploads directory, and each directory is regenerated to a maximum of 16 directories, or 256 directories, and all uploaded files are placed in these 256 directories. If you have a maximum of 1000 files per directory, you can save 256,000 files altogether.

For example, the upload file name is called: New text document. txt, then the hash code for "new text document. txt" is obtained, and then the low 4 bits of the hash code are obtained, and the 5~8 bit. If the low 4 bit is: 9,5~8 bit is 1, then the file save path is uploads/9/1/.

int hcode = Name.hashcode ();//Get the hashcode//of the file name to get Hcode low 4 bits and convert to 16 strings string dir1 = Integer.tohexstring (Hcode & 0xF );//Gets the low 5~8 bit of the hcode and converts it to a 16 binary string dir2 = integer.tohexstring (Hcode >>> 4 & 0xF);// Connect to the file save directory as full path Savepath = Savepath + "/" + Dir1 + "/" + dir2;//because this path may not exist, so create a file object, creating a directory chain, and make sure that the directory has a new file (save Path). Mkdirs ();
5.6 The size limit of individual files uploaded

Limit the size of the uploaded file is very simple, servletfileupload class of Setfilesizemax (long) on it. The parameter is the maximum number of bytes to upload the file, such as Servletfileupload.setfilesizemax (1024*10) for a maximum of 10KB.

Once the uploaded file exceeds the upper limit, a Fileuploadbase.filesizelimitexceededexception exception is thrown. We can get this exception in the servlet and then output the "uploaded file out of bounds" to the page.

public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, IOException { Request.setcharacterencoding ("Utf-8");D iskfileitemfactory dfif = new Diskfileitemfactory (); Servletfileupload fileUpload = new Servletfileupload (DFIF);//Set the maximum upload of a single file to 10kbfileupload.setfilesizemax (1024 * 10); Try {list<fileitem> list = fileupload.parserequest (request);//Gets the second form item because the first form item is a username, The second one is the file form item Fileitem Fileitem = List.get (1); String name = Fileitem.getname ();//Gets the file name//If the client is using IE6, it needs to get the file name from the full path int lastIndex = Name.lastindexof ("\ \"); if ( LastIndex! =-1) {name = name.substring (LastIndex + 1);} Gets the saved directory of the uploaded file string savepath = This.getservletcontext (). Getrealpath ("/web-inf/uploads"); String uuid = Commonutils.uuid ();//generate uuidstring filename = uuid + "_" + name;//new file name is UUID + underscore + original name int hcode = Name.ha Shcode ();//Get the hashcode//of the file name to get Hcode low 4 bits and convert to 16 strings string dir1 = Integer.tohexstring (Hcode & 0xF);//Get Hcode low 5~ 8-bit, and converted to 16 string dir2 = Integer.tohexstRing (Hcode >>> 4 & 0xF);//Connect to file save directory as full path Savepath = Savepath + "/" + Dir1 + "/" + dir2;//because this path may not exist, so create file Object, and then create a directory chain to make sure that the directory already exists with the new file (Savepath) before it is saved. Mkdirs ();//Create file object, the following will save the upload file to the file specified by the path//savepath, that is, upload files to save directory// FileName, file name, files = new file (savepath, filename),//Save fileitem.write (files);} catch (Exception e) {//To determine whether the type of exception thrown is fileuploadbase.filesizelimitexceededexception//if yes, the description exceeds the limit when uploading the file. if (e instanceof fileuploadbase.filesizelimitexceededexception) {//Save error message in Request Request.setattribute ("msg", "Upload failed!") Uploaded files are out of 10kb! ");//forward to the index.jsp page! In the index.jsp page, you need to use ${msg} to display the error message Request.getrequestdispatcher ("/index.jsp"). Forward (request, response); return;} throw new Servletexception (e);} }
5.7 Total size limit for uploaded files

Sometimes we need to limit the size of a request. That is, the maximum number of bytes for this request (sum of all the table items)! It is also very simple to implement this function, just call the Setsizemax (long) method of the Servletfileupload class.

For example Fileupload.setsizemax (1024 * 10), which shows the upper limit for the entire request is 10KB. The Parserequest () method of the Servletfileupload class throws a Fileuploadbase.sizelimitexceededexception exception when the request size exceeds 10KB.


5.8 Cache Size vs Temp directory
public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, IOException { Request.setcharacterencoding ("Utf-8"); <strong>diskfileitemfactory dfif = new Diskfileitemfactory (1024*20, new File ("F:\\temp")); </strong>servletfileupload fileUpload = new Servletfileupload (DFIF); try {List<fileitem > list = fileupload.parserequest (request); Fileitem Fileitem = list.get (1); String name = Fileitem.getname (); String Savepath = This.getservletcontext (). Getrealpath ("/web-inf/uploads");//Save File Fileitem.write (path (Savepath, name));} catch (Exception e) {throw new Servletexception (e);}} Private file path (string savepath, string filename) {//Gets the file name from the full path int lastIndex = Filename.lastindexof ("\ \"); if ( LastIndex! =-1) {filename = filename.substring (lastIndex + 1);} Generate a first level, two level directory int hcode = Filename.hashcode () by file name; String Dir1 = integer.tohexstring (Hcode & 0xF); String Dir2 = integer.tohexstring (Hcode >>> 4 & 0xF) Savepath = Savepath + "/" + Dir1 + "/" + dir2;//Create directory new file (Savepath). Mkdirs ();//Add UUID prefix to file name string uuid = Commonutils.uuid (); filename = uuid + " _ "+ filename;//Create file completion path return new file (Savepath, filename);}


Java Web----File Upload

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.