文件上传简单案例(后台Servlet处理)

文件上传注意:

1、必须要设置<input type="file" > 文件表单输入项的name属性,
   否则浏览器将不会发送上传文件的数据。

2、必须把form的enctype属值设为multipart/form-data.method ,属性设置为post提交方式。
   设置该值后,浏览器在上传文件时,将把文件数据附带在http请求消息体中,
   并使用MIME协议对上传的文件进行描述,以方便接收方对上传数据进行解析和处理。

3,使用Commons-fileupload组件实现文件上传,需要导入该组件相应的支撑jar包:
  Commons-fileupload和commons-io。commons-io不属于文件上传组件的开发jar文件,
  但Commons-fileupload 组件从1.1 版本开始,它工作时需要commons-io包的支持。

点击下载JAR包

DiskFileItemFactory 是创建 FileItem 对象的工厂,这个工厂类常用方法:


//构造函数
public DiskFileItemFactory(int sizeThreshold, java.io.File repository) 

//设置内存缓冲区的大小,默认值为10K。当上传文件大于缓冲区大小时,
//fileupload组件将使用临时文件缓存上传文件。
public void setSizeThreshold(int sizeThreshold) 

//指定临时文件目录,默认值为System.getProperty("java.io.tmpdir")
public void setRepository(java.io.File repository) 

ServletFileUpload 负责处理上传的文件数据,并将表单中每个输入项封装成一个 FileItem 对象中。
它常用方法有:

//判断上传表单是否为multipart/form-data类型,返回true表示是文件上传项
boolean isMultipartContent(HttpServletRequest?request) 

//解析request对象,并把表单中的每一个输入项包装成一个fileItem 对象,
//并返回一个保存了所有FileItem的list集合。
List parseRequest(HttpServletRequest request)

//设置上传文件的最大值
setFileSizeMax(long?fileSizeMax) 

//设置上传文件总量的最大值
setSizeMax(long sizeMax) 

//设置编码格式
setHeaderEncoding(java.lang.String encoding) 

setProgressListener(ProgressListener pListener)

实现步骤:

1、创建DiskFileItemFactory对象,设置缓冲区大小和临时文件目录

2、使用DiskFileItemFactory 对象创建ServletFileUpload对象,
    并设置上传文件的大小限制。

3、调用ServletFileUpload.parseRequest方法解析request对象,
    得到一个保存了所有上传内容的List对象。

4、对list进行迭代,每迭代一个FileItem对象,调用其isFormField方法判断是否是上传文件
    当为普通表单字段,则调用getFieldName、getString方法得到字段名和字段值
    当为上传文件,则调用getInputStream方法得到数据输入流,从而读取上传数据。

常见问题:

1,中文文件乱码问题
文件名中文乱码问题,可调用ServletUpLoader的setHeaderEncoding方法,
或者设置request的setCharacterEncoding属性 

2,临时文件的删除问题
由于文件大小超出DiskFileItemFactory.setSizeThreshold方法设置的内存缓冲区的大小时,
Commons-fileupload组件将使用临时文件保存上传数据,因此在程序结束时,
务必调用FileItem.delete方法删除临时文件。
Delete方法的调用必须位于流关闭之后,否则会出现文件占用,而导致删除失败的情况。

3,文件存放位置
1)为保证服务器安全,上传文件应保存在应用程序的WEB-INF目录下,
  或者不受WEB服务器管理的目录。

2)为防止多用户上传相同文件名的文件,而导致文件覆盖的情况发生,
  文件上传程序应保证上传文件具有唯一文件名。

3)为防止单个目录下文件过多,影响文件读写速度,处理上传文件的程序应根据可能的文件上传总量,
  选择合适的目录结构生成算法,将上传文件分散存储。

上传文件的处理细节:
1,ProgressListener显示上传进度(字节为单位)

2,以KB为单位显示上传进度

下面开始吧!

1,前端案例代码如下(需要引入jquery):

<form name="form" id="form" action="${pageContext.request.contextPath }/fileServlet.do" 
    method="post" enctype="multipart/form-data"> 
        用户名:<input type="text" name="userName"><br/>
        文件:  <input type="file" name="file_img"><br/>
        文件:  <input type="file" name="file_img2"><br/>
        <input type="button" id="tijiao"   value="提交">
 </form>
 <progress></progress>


 //这里展示异步处理,如果是同步处理,
 //则直接<input type="submit" value="提交"> 
 //submit按钮提交,不需要写下面js代码

<script type="text/javascript" src="jquery-1.8.2.min.js"></script>
    <script type="text/javascript">
        $(function(){
            $('#tijiao').click(function(){
                var formData = new FormData($('form')[0]);//得到第一个表单
                $.ajax({
                    url: '${pageContext.request.contextPath }/fileServlet.do',//请求路径
                    type: 'POST',//提交方法
                    xhr: function(){//custom xhr
                        myXhr = $.ajaxSettings.xhr();
                        if(myXhr.upload){ // 检查上传属性是否存在
                            myXhr.upload.addEventListener('progress',function(e){//上传进度调用方法
                                if(e.lengthComputable){
                                     //e.loaded 上传大小, e.total总大小
                                     //上传进度使用progress元素展示
                                    $('progress').attr({value:e.loaded,max:e.total});
                                }
                            }, false); //处理上传进度
                        }
                        return myXhr;
                    },beforeSend:function(){//发送前调用的方法

                    },error:function(){//成功调用的方法

                    },success: function(data){//失败调用的方法
                        alert(data);
                    },data:formData,// Form表单数据

                    //设置jQuery不处理数据或担心的内容类型
                    cache: false,
                    contentType: false,
                    processData: false
                });
            });
        })
    </script>

2,后台请求处理,这里以Servlet为例,如果使用的是其它的框架也是一样的处理

package cn.itcast.servlet;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
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.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;


public class FileServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String flag="失败";
        try {
            // 1. 文件上传工厂
            FileItemFactory factory = new DiskFileItemFactory();
            // 2. 创建文件上传核心工具类
            ServletFileUpload upload = new ServletFileUpload(factory);

            // 一、设置单个文件允许的最大的大小:30M
            upload.setFileSizeMax(30*1024*1024);

            // 二、设置文件上传表单允许的总大小:80M
            upload.setSizeMax(80*1024*1024);

            // 三、 设置上传表单文件名的编码
            // 相当于:request.setCharacterEncoding("UTF-8");
            upload.setHeaderEncoding("UTF-8");

            // 判断: 当前表单是否为文件上传表单,返回true 表示是
            if (upload.isMultipartContent(request)){

                // 把请求数据转换为一个个FileItem对象,再用集合封装
                List<FileItem> list = upload.parseRequest(request);

                for (FileItem item : list){// 遍历:得到每一个数据

                    if (item.isFormField()){//为true是普通文本数据

                        String fieldName = item.getFieldName(); // 表单元素名称
                        String content = item.getString();      // 表单元素名称, 对应的数据
                        //item.getString("UTF-8"); //指定编码
                        System.out.println(fieldName + " " + content);

                    } else {//否则是文件,上传文件(文件流)

                        *//******** 文件上传 ***********//*
                        String fieldName = item.getFieldName(); // 表单元素名称
                        String name = item.getName();           // 文件名              
                        String content = item.getString();      // 表单元素名称, 对应的数据
                        String type = item.getContentType();    // 文件类型
                        InputStream in = item.getInputStream(); // 上传文件流
                        String id = UUID.randomUUID().toString();//得到UUID唯一标记,-处理上传文件名重名问题
                        name = id + "#" + name;//拼接文件名                  
                        String basePath = "E:/项目空间/day23_demo/WebRoot/upload";//设置上传目录
                        File file = new File(basePath,name);//创建要上传的文件对象

                        item.write(file);//上传,写入
                        item.delete(); //删除组件运行时产生的临时文件
                    }
                }
                flag="成功";
            }
             request.setCharacterEncoding("UTF-8");//设置写回编码
             response.getWriter().print(flag);//将结果返回到前端页面

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }

}
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值