Servlet文件上传(压缩文件、图片等)

版权声明:转载请标明出处,谢谢合作 https://blog.csdn.net/Rao_Limon/article/details/82823200

上传文件是指把客户端的文件发送到服务器端,当客户端向服务器上传文件时,客户端发送的HTTP请求正文采用“multipart/form-data”数据类型,它表示复杂的包含多个子部分的复合表单。比如,如下HTML代码中,就包含了普通的文本输入框和两个用于指定上传文件的文件域。

<form action="UploadImg" method="post" enctype="multipart/form-data">
    测试参数1:<input type="text" name="TextItem">
    上传文件1:<input type="file" name="fileItem1">
    上传文件2:<input type="file" name="fileItem2">
    上传文件3:<input type="file" name="fileItem3">
    <input type="submit" value="提交">
</form>

当请求正文为"multipart/form-data"数据类型时,Servlet直接从HttpServletRequest对象中解析复合表单的每个字部份仍然是一项非常复杂的工作。为了简化对"multipart/form-data"类型数据的处理过程,Apache提供了两个软件包来实现文件的上传:

(1)、fileupload软件包(commons-fileupload-版本号.jar):负责上传文件的软件包。

(2)、io软件包(commons-io-版本号.jar):负责输入和输出的软件包。

这两个jar包都可以在Apache的官网中下载,网址分别是http://commons.apache.org/fileupload/ 和 http://commons.apache.org/io/ ,Servlet主要利用fileupload软件包的接口和类来实现文件的上传,而fileuoload软件本身依赖io软件包,所以两者缺一不可。

对于一个正文部分为“multipart/form-data”类型的Http请求,fileupload软件包把请求正文包含的复合表单中的每个子部分看作是一个FileItem对象,FileItem对象分为两类。

(1)、formFieId:普通表单域类型,表单中的文本框、单选、复选及提交按钮等常见表单元素

(2)、formFieId:上传文件类型,表单中的文件域就是这种类型。

 

FileItemFactory是创建FileItem对象的工厂,DiskFileItemFactory类和DiskFileItem类分别实现了FileItemFactory接口和FileItem接口。DiskFileItemFactory是创建DiskFileItem对象的工厂,而DiskFileItem类表示基于硬盘的FileItem,它能够把客户端上传的文件数据保存到硬盘上。

(1)、以下程序代码创建了一个DiskFileItemFactory对象,然后设置了在向硬盘写数据时所用的缓冲区大小,以及所使用的零食目录。(fileuoload软件包自身实现中,为了提高向硬盘写数据的效率,尤其是写大容量数据的效率,fileuoload软件包在写数据时会使用缓存,以及向临时目录存放一些临时数据,当然这不一定需要开发人员去设置)

//常见一个基于硬盘的FileItem工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置向硬盘写数据时所用的缓冲区大小,此处为4M
factory.setSizeThreshold(4*1024*1024);
//设置临时目录
factory.setRepository(new File(tempFilePath));

(2)、ServletFileUpload类为文件的上传处理器,它与FileItemFactory关联。以下程序代码创建了一个ServletFileUpload对象,它与一个DiskFileItemFactory对象关联。该类存在setSizeMax()方法用来设置上传文件的最大尺寸。

//创建一个文件上传处理器
ServletFileUpload upload = new ServletFileUpload(factory);
//设置上传文件的最大尺寸,此处为4M
upload.setSizeMax(4*1024*1024);

(3)、创建好了文件处理器之后,ServletFileUpload提供了parseRequest(HttpServletRequest request)方法来解析HttpServletRequest对象中的复合表单数据,它返回包含一组FileItem对象的List集合。代码如下:

public void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
        //常见一个基于硬盘的FileItem工厂
        DiskFileItemFactory factory = new DiskFileItemFactory();

        //创建一个文件上传处理器
        ServletFileUpload upload = new ServletFileUpload(factory);

        //解析复合表单数据,将结果存储到List对象中
        List items = upload.parseRequest(request);
}

(4)、在得到了包含FileItem对象的List集合后,就可以遍历这个集合,判断每个FileItem对象的类型,然后做出相应的处理。

Iterator iter = items.iterator();
while(iter.hasNext()){
    FileItem item = (FileItem)iter.next();
    
    //判断FileItem类型
    if(item.isFormFileId()){    //处理普通的表单域
        //获取参数名
        String name = item.getFieIdName();
        //获取参数值
        String value = item.getString();
    }else{    //处理文件类型
        //注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的
        String filename = item.getName();
        //处理获取到的上传文件的文件名的路径部分,只保留文件名部分,所以从最后一个\符号的下一个字符开始截取字符串。
        filename = filename.substring(filename.lastIndexOf("\\")+1);
	                    
        //获取item中的上传文件的输入流
        InputStream in = item.getInputStream();
	                    
        //创建一个文件输出流
        FileOutputStream out = new FileOutputStream(savePath + "\\" + filename);
	                    
        //创建一个缓冲区
        byte buffer[] = new byte[1024];
        //判断输入流中的数据是否已经读完的标识
        int len = 0;
        //循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
        while((len=in.read(buffer))>0){
            //使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中
            out.write(buffer, 0, len);
        }

        //关闭输入流
        in.close();
        //关闭输出流
        out.close();
        //删除处理文件上传时生成的临时文件
        item.delete();
    }
}

做完上述的所有代码之后,运行服务器访问前段页面,输入内容、上传指定文件

控制台输出语句:

指定目录的文件内容:

猜你喜欢

转载自blog.csdn.net/Rao_Limon/article/details/82823200