1 文件上传
1.1 实现文件上传条件
1)表单的提交方式必须是POST方式。(才有content-type属性)
2)有文件上传表单,表单中有的选择文件的标签
3)把表单设置为enctype=”multipart/form-data”,提交的数据不再是key-value对,而是字节数据
1 2 3 4
| <form action="${pageContext.request.contextPath }/UploadDemo1" method="post" enctype="multipart/form-data"> 请选择文件: <input type="file" name="img"/><br/> <input type="submit" value="上传" /> </form>
|
1.2 手动解析上传文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
public class UploadDemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { InputStream in = request.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String startTag = br.readLine(); String line = br.readLine(); String fileName = line.substring(line.lastIndexOf("filename=\"")+10, line.lastIndexOf("\"") ); System.out.println("文件名:"+fileName); br.readLine(); br.readLine(); String str = null; BufferedWriter bw = new BufferedWriter(new FileWriter("E:/files/"+fileName)); while((str=br.readLine())!=null){ if((startTag+"--").equals(str)){ break; } bw.write(str); bw.newLine(); bw.flush(); } bw.close(); br.close(); }
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }
}
|
2 工具实现文件上传
2.1 commons-fileupload组件
是Apache组织旗下的开源的文件上传的组件。使用非常简单易用。
2.2 核心的API
DiskFileItemFactory类: 用于创建上传对象,设置文件缓存区大小,设置文件缓存目录。
ServletFileUpload类: 用于在Servlet程序中实现文件上传
List list = parseRequest(request): 用于解析请求数据,提取和封装文件信息。
FileItem类: 封装一个文件的所有相关的信息javabean。包含文件名称,文件大小,文件类型, 文件数据内容。
2.3 开发步骤
1)导入commoms-fileuload的jar包
commons-fileupload-1.2.2.jar 核心包
commons-io-2.1.jar 辅助包
2)编写程序
3 实现单文件上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
DiskFileItemFactory factory = new DiskFileItemFactory(10*1024,new File("e:/temp/")); ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding("utf-8"); try { List<FileItem> list = upload.parseRequest(request); FileItem file = list.get(0); String fileName = file.getName(); long fileSize = file.getSize(); String contentType = file.getContentType(); InputStream in = file.getInputStream();
FileUtils.copyInputStreamToFile(in, new File("e:/files/"+fileName));
file.delete(); System.out.println("文件名:"+fileName); System.out.println("文件大小:"+fileSize); System.out.println("文件类型:"+contentType); System.out.println("文件数据内容:"+in); } catch (FileUploadException e) { e.printStackTrace(); }
|
4 实现多文件上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| DiskFileItemFactory factory = new DiskFileItemFactory(10*1024, new File("e:/temp/")); ServletFileUpload upload = new ServletFileUpload(factory); upload.setHeaderEncoding("utf-8"); try { List<FileItem> list = upload.parseRequest(request); if(list!=null){ List<UploadFile> ufList = new ArrayList<UploadFile>(); for(FileItem file: list){ String fileName = file.getName(); long fileSize = file.getSize(); String contentType = file.getContentType(); UploadFile uf = new UploadFile(); uf.setFileName(fileName); uf.setFileSize(fileSize); uf.setFileType(contentType); ufList.add(uf); FileUtils.copyInputStreamToFile(file.getInputStream(), new File("e:/files/"+fileName)); file.delete(); } request.setAttribute("ufList", ufList); request.getRequestDispatcher("/success.jsp").forward(request, response); } } catch (FileUploadException e) { e.printStackTrace(); }
|
5 动态选择多文件上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| <html> <head> <title>使用组件实现动态多文件上传</title> </head> <body> <form action="${pageContext.request.contextPath }/UploadDemo3" method="post" enctype="multipart/form-data" name="uploadForm"> <table border="1" width="400px"> <tbody> <tr id="1"> <td> 请选择文件: </td> <td> <input type="file" name="file"/><input type="button" value="删除" οnclick="delItem(1)"/> </td> </tr> </tbody> <tr> <td colspan="2"><input type="button" value="添加" οnclick="addIten()"/></td> </tr> <tr> <td colspan="2"><input type="button" value="上传" οnclick="checkSunbit()"/></td> </tr> </table> </form> <script type="text/javascript"> var id = 2; function addIten(){ var trNode = document.createElement("tr"); trNode.setAttribute("id", id); var tdNode1 = document.createElement("td"); tdNode1.innerHTML = "请选择文件:"; var tdNode2 = document.createElement("td"); var input1 = document.createElement("input"); input1.setAttribute("type", "file"); input1.setAttribute("name", "file"); var input2 = document.createElement("input"); input2.setAttribute("type", "button"); input2.setAttribute("value", "删除"); input2.setAttribute("onclick", "delItem("+id+")"); tdNode2.appendChild(input1); tdNode2.appendChild(input2); trNode.appendChild(tdNode1); trNode.appendChild(tdNode2); var tbodyNode = document.getElementsByTagName("tbody")[0]; tbodyNode.appendChild(trNode); id++; } function delItem(id){ if(id>1){ var trNode = document.getElementById(id); var tbodyNode = document.getElementsByTagName("tbody")[0]; tbodyNode.removeChild(trNode); id--; } } function checkSunbit(){ var fileList = document.getElementsByName("file"); for(var i=0;i<fileList.length;i++){ if(fileList[i].value==null || fileList[i].value==""){ alert("请选择第"+(i+1)+"个文件"); return; } } var form = document.forms['uploadForm']; form.submit(); } </script> </body> </html>
|
6 文件上传的细节
6.1 限制文件类型
1 2 3 4 5 6 7
| String contentType = file.getContentType(); System.out.println(contentType); if(!contentType.toLowerCase().matches("image/[a-z]*")){ throw new FileTypeErrorException("文件类型不符合条件!"); }
|
6.2 限制上传文件大小
ServletFileUpload类:
setFileSizeMax:设置单个文件的最大容量。
setSizeMax : 设置所有文件的最大容量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| try { List<FileItem> list = upload.parseRequest(request); if(list!=null){ for(FileItem file : list){
String contentType = file.getContentType(); System.out.println(contentType); if(!contentType.toLowerCase().matches("image/[a-z]*")){ throw new FileTypeErrorException("文件类型不符合条件!"); } FileUtils.copyInputStreamToFile(file.getInputStream(), new File("e:/files/"+file.getName())); file.delete(); } } } catch (FileTypeErrorException e) { request.setAttribute("message", e.getMessage()); request.getRequestDispatcher("/05.upload.jsp").forward(request, response); return; } catch (FileSizeLimitExceededException e) { request.setAttribute("message", "单个文件不能超过1M"); request.getRequestDispatcher("/05.upload.jsp").forward(request, response); return; } catch (SizeLimitExceededException e) { request.setAttribute("message", "所有文件不能超过5M"); request.getRequestDispatcher("/05.upload.jsp").forward(request, response); return; } catch (FileUploadException e) { e.printStackTrace(); }
|
6.3 查看文件上传的进度
ServletFileUpload类:
setProgressListener(进度监听器):设置文件上传的监听器
6.4 处理文件名重复问题
1 2 3 4 5 6 7 8 9 10
|
String fileName = file.getName(); String supfix = fileName.substring(fileName.lastIndexOf(".")); fileName = UUID.randomUUID().toString()+supfix;
|
6.5 把同一个目录的文件打散到不同的目录下
假如所有文件都放在同一个目录下,不方便管理。
6.6 得到普通文本控件内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| if(file.isFormField()){
String fieldName = file.getFieldName(); if("info1".equals(fieldName)){ String info1 = file.getString("utf-8"); System.out.println("描述1:"+info1); } if("info2".equals(fieldName)){ String info2 = file.getString("utf-8"); System.out.println("描述2:"+info2); }
|
7 文件下载
7.1 普通文件下载
使用超链接。缺点:1)暴露文件的路径2)扩展型和安全性不好
7.2 使用servlet程序下载(推荐)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| String path = this.getServletContext().getRealPath("/upload/9/1/图片1.png"); File file = new File(path); FileInputStream in = new FileInputStream(file);
String fileName = file.getName(); fileName = URLEncoder.encode(fileName, "utf-8"); String userAgent = request.getHeader("user-agent"); String filefix = null; if(userAgent.contains("Trident")){ filefix = "filename="+fileName; }else if(userAgent.contains("Firefox")){ filefix = "filename*="+fileName; }else{ filefix = "filename="+fileName; } response.setHeader("Content-Disposition", "attachment;"+filefix); byte[] buf = new byte[1024]; int len = 0; while( (len=in.read(buf))!=-1 ){ response.getOutputStream().write(buf, 0, len); } in.close();
|
本作品采用知识共享署名 4.0 中国大陆许可协议进行许可,欢迎转载,但转载请注明来自御前提笔小书童,并保持转载后文章内容的完整。本人保留所有版权相关权利。
本文链接:https://royalscholar.cn/2017/03/15/Java文件上传与下载/