分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 软件开发

使用fileupload实现文件上传(1)

发布时间:2023-09-06 02:12责任编辑:董明明关键词:upload文件上传

一. fileupload组件工作原理

先来张图片, 帮助大家理解

fileupload核心API

1. DiskFileItemFactory
构造器
1) DiskFileItemFactory() // 使用默认配置
2) DiskFileItemFactory(int sizeThreshold, File repository)
  sizeThreshold 内存缓冲区, 不能设置太大, 否则会导致JVM崩溃
  repository 临时文件目录

2. ServletFileUpload
1) isMutipartContent(request) // 判断上传表单是否为multipart/form-data类型 true/false
2) parseRequest(request) // 解析request, 返回值为List<FileItem>类型
3) setFileSizeMax(long) // 上传文件单个最大值
4) setSizeMax(long) // 上传文件总量最大值
5) setHeaderEncoding(String) // 设置编码格式
6) setProgressListener(ProgressListener) // 设置监听器, 可以用于制作进度条

二. 使用fileupload实现文件上传

1. 编写JSP

 1 <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 <html> 3 <head> 4 ????<title>演示文件上传</title> 5 </head> 6 <body> 7 ????<form action="${pageContext.request.contextPath}/servlet/FileUpload1" method="post" enctype="multipart/form-data"> 8 ????????用户名: <input type="text" name="username"/><br/> 9 ????????文件1: <input type="file" name="file1"/><br/>10 ????????文件2: <input type="file" name="file2"/><br/>11 ????????<input type="submit"/>12 ????</form>13 </body>14 </html>

要点:

1) 表单包含file类型输入项时, enctype属性必须设置为multipart/form-data

2) input:file必须指定name属性

3) 表单提交方式为post, 因为get请求无法携带大量数据

4) 若表单的提交方式为multipart/form-data, 那么在Servlet就无法使用getParameter方法获取表单数据, 可以通过获取客户机提交数据的输入流来获取所有上传数据, 然后进行解析.

1 // 获取客户机提交数据的输入流2 request.getInputStream();

5) 解析数据难度较大, 一般不自己编写程序, 可以使用开源项目解析数据

2. 编写Servlet

 1 public class FileUpload1 extends HttpServlet { 2 ????@Override 3 ????protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 4 ?5 ????????InputStream in = null; 6 ????????OutputStream out = null; 7 ?8 ????????try { 9 ????????????// 使用默认配置创建解析器工厂10 ????????????DiskFileItemFactory factory = new DiskFileItemFactory();11 ????????????// 获取解析器12 ????????????ServletFileUpload upload = new ServletFileUpload(factory);13 ????????????// 上传表单是否为multipart/form-data类型14 ????????????if (!upload.isMultipartContent(request)) {15 ????????????????return;16 ????????????}17 ????????????// 解析request的输入流18 ????????????List<FileItem> fileItemList = upload.parseRequest(request);19 ????????????// 迭代list集合20 ????????????for (FileItem fileItem : fileItemList) {21 ????????????????if (fileItem.isFormField()) {22 ????????????????????// 普通字段23 ????????????????????String name = fileItem.getFieldName();24 ????????????????????String value = fileItem.getString();25 ????????????????????System.out.println(name + "=" + value);26 ????????????????} else {27 ????????????????????// 上传文件28 ????????????????????// 获取上传文件名29 ????????????????????String fileName = fileItem.getName();30 ????????????????????fileName = fileName.substring(fileName.lastIndexOf("\\")+1);31 ????????????????????// 获取输入流32 ????????????????????in = fileItem.getInputStream();33 34 ????????????????????// 获取上传文件目录35 ????????????????????String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");36 ????????????????????// 上传文件名若不存在, 则先创建37 ????????????????????File savePathDir = new File(savePath);38 ????????????????????if (!savePathDir.exists()) {39 ????????????????????????savePathDir.mkdir();40 ????????????????????}41 42 ????????????????????// 获取输出流43 ????????????????????out = new FileOutputStream(savePath + "\\" + fileName);44 ????????????????????int len = 0;45 ????????????????????byte[] buffer = new byte[1024];46 ????????????????????while((len=in.read(buffer)) > 0) {47 ????????????????????????out.write(buffer, 0, len);48 ????????????????????}49 ????????????????}50 ????????????}51 ????????} catch (Exception e) {52 ????????????e.printStackTrace();53 ????????} finally {54 ????????????if (in != null) {55 ????????????????in.close();56 ????????????}57 ????????????if (out != null) {58 ????????????????out.close();59 ????????????}60 ????????}61 62 ????}63 64 ????@Override65 ????protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {66 ????????doGet(req, resp);67 ????}68 }

1) 在WEB-INF中创建upload文件夹时. IDEA不会在out目录的WEB-INF中创建upload文件夹, 需要手动创建, 所以上面先检查upload文件夹是否存在

2) 在finally中关闭流时, 应该先检查流是否为null, 否则当上传表单不为multipart/form-data类型时, 执行return后再执行finally, 程序就会出现NPE

3) 记得在web.xml中配置servlet的映射路径

3. 测试

4. 使用浏览器抓包

三. 禁止别人访问上传文件目录

上传文件目录应该放在WEB-INF目录下, 禁止别人访问上传文件目录, 否则黑客可能通过上传脚本, 然后访问该脚本, 对网站发起攻击

举例:

1. 黑客上传一个JSP文件

test.jsp
1 <%2 ????Runtime.getRuntime().exec("shutdown -s -t 200") ?// 执行Windows命令3 %>

2. 通过访问该文件, 关闭服务器

http://localhost:8080/upload/test.jsp

备注:

1) Runtime类  // 调用Windows程序

2) Window命令:

  shutdown -a
  format c:\

四. 待解决的问题

1. 中文文件名乱码问题
2. 上传文件目录, 文件存储个数 -> 使用Hash算法打散
3. 文件覆盖问题 -> 使用UUID作为文件名称

使用fileupload实现文件上传(1)

原文地址:https://www.cnblogs.com/shaohsiung/p/9536901.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved