首页 > 编程语言 >javaweb之文件上传总结

javaweb之文件上传总结

时间:2022-12-14 15:32:59浏览次数:89  
标签:总结 文件 java javaweb 编码 String 上传 FileItem


一。文件上传:
是指允许客户将本地文件,上传到服务器端 
常见的应用:上传照片、上传新闻图片、上传附件 
文件上传编程基本步骤:
 1、在用户页面中添加上传输入项 (客户端页面操作)也就是编写一个jsp页面里面编写一个表单提交
 <from action="跳转路径" method="post" enctype="multipart/from-data">
 <input type="file" name="fileUpload"/>
 <input type ="submit" value="上传"/>
 </from>
 注意事项:
 1) 必须为文件上传input 提供name属性,否则文件上传内容不会被表单提交 
 2) 表单的提交是post (get提交数据在url地址上显示,有长度限制) 
 3) 设置enctype=multipart 使得文件上传编码 ----- MIME编码格式
常用文件上传API : 
 1) JSP独立开发年代 jsp-smartupload ---- JSP Model1 
 jspSmartUpload是一个可免费使用的全功能的文件上传下载组件,适于嵌入执行上传下载操作的JSP文件中。
 2) JSP+Servlet 开发web应用 Apache commons-fileupload ---- JSP Model2
 FileUpload 是 Apache commons下面的一个子项目,用来实现Java环境下面的文件上传功能,与常见的SmartUpload齐名。
 3) Servlet3.0规范中提供对文件上传的支持 
Apache commons-fileupload 的使用:
 1) 去 ​​​http://commons.apache.org/fileupload/​​​ 下载fileupload jar包
 同时下载 commons-fileupload 和  commons-io 两个包  -------- 因为fileupload依赖io包 
 2) 将jar包导入 web 工程WEB-INF/lib下 
 3) 编写步骤:
 步骤一:获得DiskFileItemFactory 文件项工厂
 步骤二:通过工厂获得文件上传请求核心解析类 ServletFileUpload构造函数中传入工厂示例对象 
 步骤三:使用ServletFileUpload对request进行解析  ---- 获得很多个FileItem
 步骤四:对每个FileItem进行操作 判断FileItem是不是个文件上传项FileItem.isFormField()
   返回boolean true代表不是一个文件上传项 false代表是一个文件上传项
 --------文件上传项是指获得的input标签type是不是一个上传文件的标签
 代表普通字段FileItem 
 getFieldName();  ---- 获得表单项name属性
 getString(); ----- 获得表单项value

 代表文件上传FileItem
 getInputStream() --- 获得文件内容输入流
 getName() ------ 获得上传文件名称(注意:IE6版本获得的是文件的全路径需要进行切割去到文件名)
  int index = 取到的文件全路径.lastIndexOf("\\");找到最后一个\出现的位置
  if (index != -1)
  {
   filename = 取到的文件全路径.substring(index + 1);// 获得真实文件名
  }
二、commons-fileupload 核心API分析:
1、DiskFileItemFactory 磁盘文件项工厂类 
public DiskFileItemFactory(int sizeThreshold, java.io.File repository)  构造工厂时,指定内存缓冲区大小和临时文件存放位置
public void setSizeThreshold(int sizeThreshold) 设置内存缓冲区大小,默认10K
public void setRepository(java.io.File repository)设置临时文件存放位置,默认System.getProperty("java.io.tmpdir").
什么是内存缓冲区: 上传文件时,上传文件的内容优先保存在内存缓冲区中,当上传文件大小超过缓冲区大小时,就会在服务器端产生临时文件 
什么是临时文件: 保存超过了内存缓冲区大小上传文件而产生临时文件 
产生的临时文件可以通过 FileItem的delete方法删除

2、ServletFileUpload 文件上传核心类 
static boolean  isMultipartContent(javax.servlet.http.HttpServletRequest request)  判断request的编码方式是否为multipart/form-data
java.util.List  parseRequest(javax.servlet.http.HttpServletRequest request) 解析request,将请求体每个部分封装FileItem对象,返回List<FileItem>
void setFileSizeMax(long fileSizeMax) 设置单个文件上传大小
void setSizeMax(long sizeMax) 设置总文件上传大小 
void setHeaderEncoding(java.lang.String encoding)  设置编码集 解决上传文件名乱码 ***** 
void setProgressListener(ProgressListener pListener) 
设置文件上传监听器(用来监控文件上传进度)上传时间、剩余大小、速度、剩余时间 
3、FileItem 表示文件上传表单中 每个数据部分 
boolean isFormField()  判断该数据项是否为文件上传项,true 不是文件上传 false 是文件上传
if(fileItem.isFormField()){
   // 不是上传项
   java.lang.String getFieldName()  获得普通表单项name属性
   java.lang.String getString() / java.lang.String getString(java.lang.String encoding) 获得普通表单项value属性 传入编码集用来解决输入value乱码
}else{
   // 是上传项
   java.lang.String getName() 获得上传文件名 (注意IE6存在路径)
   java.io.InputStream  getInputStream() 获得上传文件内容输入流
   // 上传文件
   void delete()  删除临时文件(删除时,必须要管理输入输出流)
}
注意事项:因为文件上传表单采用编码方式multipart/form-data 与传统url编码不同,所有getParameter 方法不能使用 setCharacterEncoding 无法解决输入项乱码问题
对于出现的乱码问题的几个针对解决:
1.使用get方式提交中文时 
<a href="/day21/downloadList?path=D:\TTPmusic\何晟铭\何晟铭 - 爱的供养.mp3">何晟铭 - 爱的供养.mp3</a><br/>
问题:IE6 提交后,服务器经过get乱码处理获得乱码 
原因:IE6对中文直接进行 get提交时,进行URL编码 ---- 编码发生问题 
解决:手动对get提交中文进行编码  ----- URLEncoder 
2.如果下载文件是中文名,设置 response.setHeader("Content-Disposition", "attachment;filename=" + filename); 出现附件名乱码
不同浏览器处理下载附件名乱码处理方式不同 ,例如 IE使用URL编码 、fireFox使用BASE64编码 
通过USER-AGENT 请求头信息字段,判断来访者浏览器类型 
注意:火狐浏览器在使用MimeUtility 进行Base64编码时存在问题 ,如果字符串中没有中文,无法进行编码 
解决:采用手动BASE64 编码 
BASE64Encoder base64Encoder = new BASE64Encoder();
filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";

三实例:

public class UploadServlet extends HttpServlet{


DiskFileItemFactory factory=new DiskFileItemFactory();

ServletFileUpload upload=new ServletFileUpload(factory);

//判断提交表单的类型是否为multipart/form-data

    if(!upload.isMultipartContent(request))
    {
  return;
}

    try {
List list=upload.parseRequest(request);
Iterator it=list.iterator();

while(it.hasNext()){
  FileItem item=(FileItem)it.next();//每一个item就代表一个表单输出项

String name=item.getFieldName();input的名称

String value= item.getString();input的值
}else{

得到上传文件的名称,并截取
String filename=item.getName();

得到上传文件要写入的目录
String path=this.getServletContext().getRealPath("/upload");
根据目录和文件创建输出流

FileOutputStream out=new FileOutputStream(path+filename);

InputStream in = item.getInputStream();
  byte buffer[] = new byte[1024];
 int len = 0;
while((len=in.read(buffer))>0){
  out.write(buffer,0,len);
    }
in.close();
out.close();
  }
}
} catch (FileUploadException e) 
{
e.printStackTrace();
   }
 }

}

四文件上传注意的细节问题

1.解决上传中文乱码问题 
可以通过upload.setHeaderEncoding("utf-8");

2.上传文件怎么保证服务器的安全?  (上传文件时不安全应用举例Runtime.getRuntime.exec("")可以执行DOS命令) 


解决方案:上传目录要禁止外界直接访问,一般的做法是把上传目录放到服务器的WEB-INF目录下.这个目录服务器是保护的,外界无法访问.


2.上传文件被覆盖的问题

服务器要为每一个上传文件生成一个唯一的文件名.可以使用UUID算法.

3.上传的文件需要打散

4.临时文件的删除

FileItemDelete.删除临时文件一定要在流关闭之后,否则会出现文件占用,而导致删除失败.

5.多文件上传问题:
主要是javascript编码,在页面动态添加文件上传项.

6.监听上传进度:

自己写一个监听器progressListener




标签:总结,文件,java,javaweb,编码,String,上传,FileItem
From: https://blog.51cto.com/u_15912341/5937219

相关文章

  • IPv6改造为什么这么难?IPv6改造方案难点总结-中科三方
      据统计,截至2019年6月,我国IPv6活跃用户数仅为1.3亿,而到2020年底,这个数字需超过5亿。目前网上最早关于IPv4地址枯竭的新闻可追溯到2004年,来源京华时报。     ......
  • 个人学期期末总结和对王建民老师的评价
    JavaWeb学习期末总结:这个学期是来到学校本部的第一个学期,也是专业分流后来到软件工程专业继续学习的第一个学期。这是一个全新的学期,什么都是新的,我满怀期待,满怀热情地加入......
  • 现代软件工程个人总结
    软件工程课程总结这个学期主要学习的内容是Android、Python爬虫、Python flask框架,完成了一个简单的家庭记账本app,完成了一个简单的体温登记app,完成结对作业(中国疫情数......
  • MySQL 面试题总结
    MySQL的面试知识点总结Q1:MySQL的逻辑架构了解吗?第一层是服务器层,主要提供连接处理、授权认证、安全等功能。第二层实现了MySQL核心服务功能,包括查询解析、分析、优......
  • 画流程图总结
    画流程图是程序员必备的专业技能,下面是我总结的平时画流程图的一些心得体会,有不足和不标准不妥的地方请指正!首先先认识流程图有哪些常用的框框:注意:1标准的开始必须用:而不是......
  • SiteFactory支持Word一键上传
    ​图片的复制无非有两种方法,一种是图片直接上传到服务器,另外一种转换成二进制流的base64码目前限chrome浏览器使用首先以um-editor的二进制流保存为例:打开umeditor.js,......
  • 使用redis做消息队列mq的总结
    总结目前使用redis做消息队列的的方式有3中,list,    publish/subscribe,    streamlist做mq的总结使用方法1.生产者可以lpush写入消息,消费者可以rpop读取......
  • basic-paxos、 multi-paxos、 raft 、redis的raft 一致性算法总结
    阅读本篇博客前,希望各位对basic-paxos、multi-paxos、raft算法有基本的了解总结basic-paxos算法,也就是经典的paxos算法1)  2PC(2phasecommit,也就是2阶段提交),分为 prep......
  • 上传小程序提示主包超过2M限制
     出现这种提示的时候,优先考虑从以下两个部分修改:1、查看微信开发者工具——详情——本地设置下面的自动压缩文件勾上  2、hbuilderX编辑器里点击运行——运行到小......
  • SiteFactory支持Word上传
    ​ 在之前在工作中遇到在富文本编辑器中粘贴图片不能展示的问题,于是各种网上扒拉,终于找到解决方案,在这里感谢一下知乎中众大神以及TheViper。通过知乎提供的思路找到粘......