编程语言
首页 > 编程语言> > JavaWeb 文件的上传、下载

JavaWeb 文件的上传、下载

作者:互联网

 

文件上传

表单

<form action="HandlerServlet" method="post" enctype="multipart/form-data">
请选择要上传的文件:<input type="file" name="uploadFile" accept="*/*" multiple /><br />
<button type="submit">上传</button>
</form>

指定<form>的method="post", enctype="multipart/form-data"。

accept指定文件类型,有多种类型时逗号分隔,multiple指定可以选择多个文件。

 

 

传统处理方式

ServletInputStream inputStream = request.getInputStream();

选择的文件是放在请求消息体中的。获取的输入流中包含了上传的所有文件,如果单个上传还好处理,如果同时上传多个,不好从中分离出单个文件的数据,且自己写代码获取文件名很麻烦。

 

 

 

Commons-FileUpload

Commons-FileUpload是Apache的开源组件,提供了一套处理上传文件的API。

 

使用FileUpload需要2个jar包:

 

FileUpload组件主要的接口、类:

 

 

DiskFileItemFactory类的常用方法

 

 

 

JVM的内存是有限的,比如用户上传一个1G的文件,直接保存在JVM内存中,实打实地占用服务器内存,这绝对不行。

临界值指定文件大小,小于临界值的文件直接存储在JVM内存中,大于临界值的文件,以临时文件(.tmp)的形式保存在缓存目录中。默认为10240,默认单位Byte,即10KB。

缓存目录可以指定为磁盘上的某一个文件夹,以File形式指定,不指定时默认使用系统的临时文件夹。

 

 

 

ServletFileUpload类的常用方法

 

以上几个setter()方法均有对应的getter()方法。

 

 

注意:是封装每一个请求参数,不是只封装上传的文件,所以有些FileItem保存的是普通的请求字段。

 

 

FileItem接口常用的方法

 

 

 

 

Servlet处理上传文件示例

 1 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 2         response.setContentType("text/html;charset=utf-8");
 3 
 4         //创建FileItemFactory对象
 5         DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
 6         File tempFolder=new File("E:/tempFolder");   //Java中的File即指文件,又指文件夹
 7         if (!tempFolder.exists()){  //不存在就新建
 8             tempFolder.mkdir();
 9         }
10         //指定缓存目录
11         diskFileItemFactory.setRepository(tempFolder);  
12 
13         //创建ServletFileUpload对象
14         ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
15         //指定编码字符集
16         servletFileUpload.setHeaderEncoding("utf-8");
17 
18         try {
19             //获取List<FileItem>
20             List<FileItem> fileItems = servletFileUpload.parseRequest(request);
21             for (FileItem fileItem:fileItems){
22                 if(!fileItem.isFormField()){  //是上传文件
23                     //使用UUID创建唯一的文件名
24                     String fileName= UUID.randomUUID().toString()+"_"+fileItem.getName();
25                     String path="C:/Users/chy/Desktop/upload/"+fileName;
26                     fileItem.write(new File(path));  //写到服务器磁盘上。写完会自动删除临时文件。
27                 }
28             }
29 
30         } catch (FileUploadException e) {
31             e.printStackTrace();
32         } catch (Exception e) {
33             e.printStackTrace();
34         }
35 
36 
37     }

 

 

 

 

 

文件下载

最简单的方式:使用<a>标签直接链接到文件地址。

<a href="http://www.xxx.com/resource/特斯拉.mp4">下载xxx</a>

有2个问题:

 

 

解决方式:

(1)链接到Servlet,并传递文件名。

<a href="downloadServlet?fileName=特斯拉.mp4">下载xxx</a>

 

(2)Servlet

 1 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 2         request.setCharacterEncoding("utf-8");
 3         response.setContentType("text/html;charset=utf-8");
 4 
 5         String fileName = request.getParameter("fileName");
 6         //对文件名进行iso8859-1编码
 7         String browerFileName=new String(fileName.getBytes("utf-8"),"iso8859-1");
 8 
 9         //指定浏览器行为为下载
10         response.addHeader("Content-Type","application/octet-stream");
11         //指定下载文件名。注意这两个都是addHeader(),不是setHeader()
12         response.addHeader("Content-Disposition","attachment;filename="+browerFileName);
13 
14         InputStream is = getServletContext().getResourceAsStream("resource/"+fileName);  //换路径时只需修改此句中的路径,不用修改每个<a>
15         ServletOutputStream os= response.getOutputStream();
16         byte[] buffer = new byte[1024];
17         int len;
18         while ((len=is.read(buffer))!= -1){  //注意是-1,不是0
19             os.write(buffer);
20         }
21 
22     }

 

红字是为了解决下载文件名中文乱码。

因为我们使用的是utf-8字符集,而chrome这些浏览器默认使用 iso8859-1 字符集。要转换一下,这样浏览器在设置下载文件名时才能识别文件名中的中文。

 

 

其实 <a href="downloadServlet?fileName=特斯拉.mp4">下载xxx</a> ,url中的中文也要转换一下,一个中文字符转换为%xxxx的形式(%后面跟着4个十六进制数)。

<a href="downloadServlet?fileName=<%=URLEncoder.encode("特斯拉.mp4","utf-8")%>">下载</a>

String  URLEncoder.encode(String  str, String  charset)    //静态方法,返回编码后的字符串

当然,不转换也行,都能正确识别。

 

标签:文件,缓存,封装,String,FileItem,上传,下载,JavaWeb
来源: https://www.cnblogs.com/chy18883701161/p/11417710.html