007_Java Web中基于fileupload组件的文件上传

来源:互联网 发布:ubuntu 232 编辑:程序博客网 时间:2024/06/02 04:33

input

  • 如果在表单中使用表单元素 ,浏览器在解析表单时,会自动生成一个输入框和一个按钮,输入框可供用户填写本地文件的文件名和路径名,按钮可以让浏览器打开一个文件选择框供用户选择文件:
    这里写图片描述

enctype

  • 当表单需要上传文件时,需指定表单 enctype 的值为 multipart/form-data
  • 在 form 元素的语法中,enctype 属性指定将数据发送到服务器时浏览器使用的编码类型。
  • enctype 属性取值:
    • application/x-www-form-urlencoded:表单 enctype 属性的默认值。这种编码方案使用有限的字符集,当使用了非字母和数字时,必须用”%HH”代替(H 代表十六进制数字)。对于大容量的二进制数据或包含非 ASCII 字符的文本来说,这种编码不能满足要求。
    • multipart/form-data:form 设定了enctype=“multipart/form-data”属性后,表示表单以二进制传输数据
      accept

accept

  • 表示可以选择的文件MIME类型,多个MIME类型用英文逗号分开,常用的MIME类型见下表。
后缀名 MIME名称 col 3 is right-aligned col 2 is centered zebra stripes are neat *.3gpp audio/3gpp, video/3gpp *.ac3 audio/ac3 *.asf allpication/vnd.ms-asf *.au audio/basic *.css text/css *.csv text/csv *.doc application/msword *.dot application/msword *.dtd application/xml-dtd *.dwg image/vnd.dwg *.dxf image/vnd.dxf *.gif image/gif *.htm text/html *.html text/html *.jp2 image/jp2 *.jpe image/jpeg *.jpeg image/jpeg *.jpg image/jpeg *.js text/javascript, application/javascript *.json application/json *.mp2 audio/mpeg, video/mpeg *.mp3 audio/mpeg *.mp4 audio/mp4, video/mp4 *.mpeg video/mpeg *.mpg video/mpeg *.mpp application/vnd.ms-project *.ogg application/ogg, audio/ogg *.pdf application/pdf *.png image/png *.pot application/vnd.ms-powerpoint *.pps application/vnd.ms-powerpoint *.ppt application/vnd.ms-powerpoint *.rtf application/rtf, text/rtf *.svf image/vnd.svf *.tif image/tiff *.tiff image/tiff *.txt text/plain *.wdb application/vnd.ms-works *.wps application/vnd.ms-works *.xhtml application/xhtml+xml *.xlc application/vnd.ms-excel *.xlm application/vnd.ms-excel *.xls application/vnd.ms-excel *.xlt application/vnd.ms-excel *.xlw application/vnd.ms-excel text/xml, application/xml *.zip aplication/zip *.xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

multiple

  • multiple:是否可以选择多个文件,多个文件时其value值为第一个文件的虚拟路径。

Commons-fileupload 组件

  • Commons-fileupload 组件是 Apache 开源代码组织用来处理表单文件上传的一个子项目,该组件性能优异,可以支持任意大小的文件的上传
  • Commons-fileupload 组件从 1.1 版本开始依赖 Apache 的另一个项目:commons-io

Commons-fileupload 组件上传的基本原理

  • FileUpload组件将页面提交的所有元素(普通form表单域,如text和文件域file)都看作一样的FileItem,这样上传页面提交的 request请求也就是一个FileItem的有序组合,FileUpload组件可以解析该request,并返回一个一个的FileItem。而对每一个FileItem,FileUpload组件可以判断出它是普通form表单域还是文件file域,从而根据不同的类型,采取不同的操作。如果是表单域,就读出其值,如果是文件域,就保存文件到服务器硬盘上或者内存中。

Commons-fileupload 组件API

  • 在 Commons-fileupload 组件中,主要用到以下三个接口和类:
    这里写图片描述

  • ServletFileUpload 负责处理上传的文件数据,并将每部分的数据封装到 FileItem 对象中。

  • DiskFileItemFactory 是创建 FileItem 对象的工厂,在这个工厂类中可以配置内存缓冲区大小和存放临时文件的目录。
  • ServletFileUpload 在接收上传文件数据时,会将内容保存到内存缓存区中,如果文件内容超过了 DiskFileItemFactory 指定的缓冲区的大小,那么文件将被保存到磁盘上,存储为 DiskFileItemFactory 指定目录中的临时文件。等文件数据都接收完毕后,ServletUpload 在从文件中将数据写入到上传文件目录下的文件中

测试代码

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html>    <head>        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">        <title>Insert title here</title>    </head>    <body>        <%--        基于Apache组件的文件上传:            1.导入                commons-fileupload-1.2.1.jar                commons-io-2.0.jar            2. 其它设置与type="file"一致            3. 在servlet中使用这两个jar包进行操作                3.1.基本思想:                    3.1.1.可以解析请求,得到一个FileItem对象组成的List                    3.1.2.所有的请求斗会封装成一个FileItem对象(文本/文件/……)                    3.1.3.调用FileItem的isFormField()方法,判断是表单域还是别的(false:表示是一个文件)                    3.1.4.根据类型获取信息                3.2.具体操作                    3.2.1.得到List<FileItem>                        3.2.1.1.简单得到                            // Create a factory for disk-based file items                            FileItemFactory factory = new DiskFileItemFactory();                            // Create a new file upload handler                            ServletFileUpload upload = new ServletFileUpload(factory);                            // Parse the request                            List /* FileItem */ items = upload.parseRequest(request);                                   3.2.1.2.复杂得到(可以设置文件的一些限制和其它属性)                            // Create a factory for disk-based file items                            DiskFileItemFactory factory = new DiskFileItemFactory();                            //设置内存中最多可以存放的上传文件的大小, 若超出则把文件写到一个临时文件夹中. 以 byte 为单位                            factory.setSizeThreshold(yourMaxMemorySize);                            //设置那个临时文件夹                            factory.setRepository(yourTempDirectory);                            // Create a new file upload handler                            ServletFileUpload upload = new ServletFileUpload(factory);                            //设置上传文件的总的大小.。也可以设置单个文件的大小.(setFileSizeMax)                            upload.setSizeMax(yourMaxRequestSize);                            // Parse the request                            List /* FileItem */ items = upload.parseRequest(request);                           3.2.2.处理信息                      --%>        <form action="uploadServlet" method="post"  enctype= "multipart/form-data" >            <!-- type="file":表示是一个用户文件上传的input标签 -->            文件上传:<input type="file" name="file" />            <br />            信息:<input type="text" name="text" />            <br />            <input type="submit" value="提交" />        </form>         </body></html>
package top.itcourse.servlet;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.util.List;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileUploadException;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;public class UploadServlet extends HttpServlet {    private static final long serialVersionUID = 1L;    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        request.setCharacterEncoding("utf-8");        //1.得到List<FileItem>            //1.1.创建工厂        DiskFileItemFactory factory = new DiskFileItemFactory();            //1.2.通过工厂设置JVM处理文件大小限制(单位是bytes),当超过这个大小的时候,文件会被写到临时目录下(不然是在内存中处理的)        factory.setSizeThreshold(1024 * 500);       //500k            //1.3.设置临时目录        factory.setRepository(new File("/Volumes/Player/FileDire"));            //1.4.创建ServletFileUpload,把工厂对象传进去        ServletFileUpload upload = new ServletFileUpload(factory);            //1.5.通过ServletFileUpload设置可以上传的文件的总大小(单位bytes),区别开DiskFileItemFactory的setSizeThreshold        upload.setSizeMax(1024 * 1024 * 500);            //1.6.获得List,调用parseRequest方法        List<FileItem> parseRequest = null;        OutputStream os = null;        InputStream is = null;        try {            parseRequest  = upload.parseRequest(request);        //2.遍历所有的FileItem,确认类型            for (FileItem fileItem : parseRequest) {                //3.类型为普通表单,打印                if( fileItem.isFormField() ) {                    System.out.println("------------------------------------普通表单---------------------------------------");                    //3.1.获取普通表单的名字(用的是getFieldName,获取表单的name)                    String name = fileItem.getFieldName();                    //3.2.获得这个FileItem的值                    String value = fileItem.getString();                    System.out.println(name + " : " + new String(value.getBytes("iso-8859-1"),"utf-8"));                    System.out.println("---------------------------------------------------------------------------");                //4.类型为文件类型(非普通表单),保存在指定位置                } else {                    System.out.println("------------------------------------文件---------------------------------------");                    //input中的name                    String fieldName = fileItem.getFieldName();                    //文件名                    String fileName = fileItem.getName();                    //                    String contentType = fileItem.getContentType();                    //文件大小,单位bytes                    long sizeBytes = fileItem.getSize();                    System.out.println("fieldName : " + fieldName);                    System.out.println("fileName : " + fileName);                    System.out.println("contentType : " + contentType);                    //获取文件流,存在相应的目录下                    is = fileItem.getInputStream();                    byte[] bytes = new byte[1024];                    int pos;                    os = new FileOutputStream(new File("/Volumes/Player/FileDire/Download/" + fileName));                    while( (pos = is.read(bytes)) != -1 ) {                        os.write(bytes, 0, pos);                    }                    System.out.println("文件上传完毕~~");                    System.out.println("---------------------------------------------------------------------------");                }            }        } catch (FileUploadException e) {            e.printStackTrace();        } finally {            if( os != null ) {                os.close();            }            if( is != null ) {                is.close();            }        }    }}

效果及完整源码下载

效果及完整源码下载:点击这里

欢迎加入QQ交流群:451826376

更多信息

原创粉丝点击