[1] 简介 > 将一个客户端的本地的文件发送到服务器中保存。 > 上传文件是通过流的形式将文件发送给服务器。 [2] 表单的设置(文件上传一般利 ...
[1] 简介
> 将一个客户端的本地的文件发送到服务器中保存。
> 上传文件是通过流的形式将文件发送给服务器。
[2] 表单的设置(文件上传一般利用表单)
> 向服务器上传一个文件时,表单要使用post请求。
> 表单的默认属性enctype="application/x-www-form-urlencoded"
- 这个属性的意思是请求体中的内容将会使用URL编码
> 上传文件的表单enctype需要设置为 multipart/form-data
- multipart/form-data表示的是表单是一个多部件的表单
- 如果类型设置为它,则我们的每一个表单项都会作为一个单独的部件发送给服务器。
- 多个部件之间使用类似 -----------------------------7df2d08c0892 分割符来分开
> 当表单设置为multipart/form-data时,我们request.getParameter()将失效,我们不能再通过该方法获取请求参数。
1 <form action="${pageContext.request.contextPath }/FileUploadServlet" method="post" enctype="multipart/form-data">2 用户:<input type="text" name="name">3 <input type="file" name="photo"><br>4 <input type="submit" value="提交">5 </form>
[3] FileUpload
> 我们一般情况下使用commons-fileupload-1.3.1.jar这个工具来解析多部件请求。
> fileupload 依赖 commons-io 所以我们要是Filtupload需要同时导入io包。
> 核心类:
DiskFileItemFactory
- 工厂类,用于构建一个解析器实例。
ServletFileUpload
- 解析器类,通过该类实例来解析request中的请求信息。
FileItem
- 工具会将我们请求中每一个部件,都封装为一个FileItem对象,处理文件上传时,只需要调用该对象的方法
- 方法:
boolean isFormField() --> 当前表单项是否是一个普通表单项,true是普通表单项, false是文件表单项
String getContentType() --> 返回的是文件的类型,是MIME值
String getFieldName() --> 获取表单项的name属性值
String getName() --> 获取上传的文件的名字
long getSize() --> 获取文件的大小
String getString(String encoding) --> 获取表单项的value属性值,需要接受一个编码作为参数。
void write(File file) --> 将表单项中的内容写入到磁盘中
> 使用步骤:
1.获取工厂类实例[DiskFileItemFactory]
2.获取解析器类实例[ServletFileUpload]
3.解析request获取FileItem[parseRequest()]
1 @WebServlet("/FileUploadServlet") 2 public class FileUploadServlet extends HttpServlet { 3 private static final long serialVersionUID = 1L; 4 5 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 6 7 //创建工厂类 8 DiskFileItemFactory factory=new DiskFileItemFactory(); 9 //创建FileUploadServlet对象,通过这个对象完成上传功能10 ServletFileUpload fileUpload=new ServletFileUpload(factory);11 //用这个fileUpload对象解析request请求12 try {13 List<FileItem> fileList = fileUpload.parseRequest(request);14 for(FileItem item:fileList){15 if (item.isFormField()) {16 //代表普通表单项17 String name = item.getFieldName();18 String value = item.getString("UTF8");19 System.out.println(name+":"+value);20 }else {21 //代表上传的文件22 long size = item.getSize();23 String contentType = item.getContentType();24 String name = item.getName();25 String fieldName = item.getFieldName();26 System.out.println(size+":"+contentType+":"+name+":"+fieldName);27 String uuid = UUID.randomUUID().toString();//名字重复,后一章会覆盖前一章28 uuid.replace("-", "");29 item.write(new File("C:\\Users\\kanglu\\Desktop\\"+uuid+"_"+name));30 }//MIME 31 }32 }catch (Exception e) {33 // TODO Auto-generated catch block34 e.printStackTrace();35 }36 }37 }
文件上传基本实现
[4] 细节
第一个问题
> 部分浏览器会将文件的完整路径作为文件名发送。
C:\Users\lilichao\Desktop\day20\图片\蒙娜丽莎.jpg
> 像这类文件名我们需要截取一下字符串,只获取名字这部分,而不需要获取路径部分的信息。
通过如下代码对文件名进行截取字符串的操作:
if(name.contains("\\")){
//如果包含则截取字符串
name = name.substring(name.lastIndexOf("\\")+1);
}
第二个问题
> 上传的文件有可能出现重名,后上传的文件会将先上传的文件覆盖。
> 解决:给文件名加一个唯一的前缀。
唯一标识_fennu.jpg
UUID_fennu.jpg
1 //添加唯一前缀2 String uuid = UUID.randomUUID().toString();//名字重复,后一章会覆盖前一章3 uuid.replace("-", "");
第三个问题
> 有些情况需要限制上传文件的大小。
- 设置单个文件大小为50KB:
fileUpload.setFileSizeMax(1024*50);
- 设置完单个文件大小限制以后,一旦上传的文件超过限制,则会抛出如下异常:
FileSizeLimitExceededException
所有可以对该异常进行捕获,当出现该异常时则设置一个错误消息。
- 设置多个文件的总大小为150KB
fileUpload.setSizeMax(1024*150);
- 当多个文件的大小超出范围时,会抛出如下异常
SizeLimitExceededException
1 //单个文件 2 fileUpload.setFileSizeMax(1024*50); 3 try{ 4 ...... 5 }catch (FileSizeLimitExceededException e) { 6 System.out.println("文件大小超出限制"); 7 } 8 9 //多个文件10 设置插入多个文件11 <input type="file" name="photo"><br>12 <input type="file" name="photo"><br>13 限制大小处理14 fileUpload.setSizeMax(1024*150);15 try{16 ......17 }catch (SizeLimitExceededException e) {18 System.out.println("整体文件大小超出限制");19 }
限制文件大小
第四个问题
> 当用户上传一个空的文件,依然会将文件保存到硬盘上。
> 在保存文件应该先对文件的大小进行判断,如果size为0,则不处理。
1 long size = item.getSize();2 if(size==0){3 System.out.println("文件大小为空");4 continue;5 }//若是多个文件,空文件可能位于首位,所以用continue;6 //若是单个文件,可用break;7 //此处针对上面所写代码,其位于for循环中
[5]上传服务器
上面代码中文件直接传到自己的电脑上,用户不能通过浏览器进行网络访问。
若要能通过浏览器访问,可上传到tomcat服务器位于eclipse的镜像中。(本人使用的是eclipse进行编码)
1 将文件上传到服务器上: 2 1、将links和tc-servlet包复制到eclipse文件目录下; 3 4 2、 //将文件存在tomcat服务器镜像上,获取镜像目录 5 ServletContext servletContext=request.getServletContext(); 6 String realPath = servletContext.getRealPath("/upload");//要存储的具**置 7 File file = new File(realPath); 8 if(!file.exists()){ 9 file.mkdirs();//文件不存在,创建文件(目录)10 //file.isDirectory()表明上传的文件是个目录11 }
通过realPath获取文件所在位置,在浏览器上输入(如图片地址),即可获取
1 localhost:9999/web-upload/upload/168ea717-401b-485c-9d1f-c62cfa50d361_fennu.jpg2 //在浏览器地址栏输入如上地址内容即可查看刚刚上传的文件(以图片为例),3 //localhost:9999为tomcat端口号,web-upload为所写项目名,4 //upload为文件所在位置,5 //168ea717-401b-485c-9d1f-c62cfa50d361_fennu.jpg为图片名6 6//_前内容为随机生成的唯一标识符
完整代码,包含上传服务器:
package com.neuedu.servlet;import java.io.File;import java.io.IOException;import java.util.List;import java.util.UUID;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;@WebServlet("/FileUploadServlet")public class FileUploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //创建工厂类 DiskFileItemFactory factory=new DiskFileItemFactory(); //创建FileUploadServlet对象,通过这个对象完成上传功能 ServletFileUpload fileUpload=new ServletFileUpload(factory); fileUpload.setFileSizeMax(1024*50); //将文件上传到服务器,是能在互联网上访问 ServletContext servletContext=request.getServletContext(); String realPath = servletContext.getRealPath("/upload"); File file = new File(realPath); if(!file.exists()){ file.mkdirs();//文件不存在,创建文件(目录) //file.isDirectory()表明上传的文件是个目录 } //用这个fileUpload对象解析request请求 try { List<FileItem> fileList = fileUpload.parseRequest(request); for(FileItem item:fileList){ if (item.isFormField()) { //代表普通表单项 String name = item.getFieldName(); String value = item.getString("UTF8"); System.out.println(name+":"+value); }else { //代表上传的文件 fileUpload.setFileSizeMax(1024*50); long size = item.getSize(); String contentType = item.getContentType(); String name = item.getName(); String fieldName = item.getFieldName(); if(size==0){ System.out.println("文件大小为空"); continue; } System.out.println(size+":"+contentType+":"+name+":"+fieldName); String uuid = UUID.randomUUID().toString();//名字重复,后一章会覆盖前一章 uuid.replace("-", ""); try { item.write(new File(realPath+"\\"+uuid+"_"+name)); } catch (Exception e) { // TODO: handle exception } }//MIME } }catch (FileSizeLimitExceededException e) { System.out.println("文件大小超出限制"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
原标题:文件上传(java)
关键词:JAVA
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。