首页 > 技术文章 > 文件的上传和下载---以图片为例

lwj-0923 2017-08-18 10:43 原文

上传

创建JSP页面,添加form表单

注意点:1.表单需要使用“post”请求

    2.表单的默认属性enctype="application/x-www-form-urlencoded"

    3.上传文件的表单enctype需要设置为 multipart/form-data

    4.当表单设置为multipart/form-data时,我们request.getParameter()将失效,我们不能再通过该方法获取请求参数。

<form action="${pageContext.request.contextPath }/FileUpLoadServlet" method="post" enctype="multipart/form-data">
	User:<input type="text" name="name" /><br/>
	<input type="file" name="photo"/><br/>
	<input type="file" name="photo1"/><br/>
	<input type="file" name="photo2"/>
	<input type="submit" value="提交">
</form>

 

导包:一般情况下使用commons-fileupload-1.3.1.jar这个工具来解析多部件请求
           fileupload 依赖 commons-io 所以我们要是Filtupload需要同时导入io包

          

 

核心类:
  DiskFileItemFactory
    - 工厂类,用于构建一个解析器实例。
                   
  ServletFileUpload
    - 解析器类,通过该类实例来解析request中的请求信息。
                   
  FileItem
    - 工具会将我们请求中每一个部件,都封装为一个FileItem对象,处理文件上传时,只需要调用该对象的方法

  具体代码:

//1.创建一个工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//2.创建ServletFileUpload对象,通过这个对象完成上传功能
ServletFileUpload fileUpload = new ServletFileUpload(factory);
//用fileUpload这个对象解析request请求
List<FileItem> fileList = fileUpload.parseRequest(request);

 fileList的方法:

类型 方法 详解
boolean isFormField() 当前表单项是否是一个普通表单项,true是普通表单项, false是文件表单项
String getContentType() 返回的是文件的类型,是MIME值
String getFieldName() 获取表单项的name属性值
String getName() 获取上传的文件的名字
long getSize() 获取文件的大小
String getString(String encoding) 获取表单项的value属性值,需要接受一个编码作为参数。
void write(File file)  将表单项中的内容写入到磁盘中

 

 

 

 

 

 

 

 

 

部分方法代码书写

long size = item.getSize();
String contentType = item.getContentType();//文件类型
String name = item.getName();//图片实际名
String fieldName = item.getFieldName();//属性名

System.out.println(size+" "+contentType+" "+name+" "+fieldName);

 

 完整代码

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.创建一个工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//2.创建ServletFileUpload对象,通过这个对象完成上传功能
ServletFileUpload fileUpload = new ServletFileUpload(factory);
//用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{
             //代表上传的文件
             long size = item.getSize();
             String contentType = item.getContentType();//文件类型
             String name = item.getName();//图片实际名
             String fieldName = item.getFieldName();//属性名
             System.out.println(size+" "+contentType+" "+name+" "+fieldName);

             item.write(new File("C:\\Users\\LWJJJJJ\\Desktop\\123.jpg"));
       }//MIME类---总类型/具体类型
   }
} catch (Exception e) {
       // TODO Auto-generated catch block
      e.printStackTrace();
    }
}

 

 细节问题:

  1.部分浏览器会将文件的完整路径作为文件名发送。也就是说路径会产生问题

     但是一般浏览器,如火狐、谷歌、IE7以上都不会,IE6会

     像这类文件名我们需要截取一下字符串,只获取名字这部分,而不需要获取路径部分的信息。

if(name.contains("\\")){
     //如果包含则截取字符串
     name = name.substring(name.lastIndexOf("\\")+1);
   //一定要+1,不然会多了一个/ }

  2.上传的文件有可能出现重名,后上传的文件会将先上传的文件覆盖

     解决方法:给文件加一个唯一标识符--UUID

String prefix = UUID.randomUUID().toString();
prefix.replace("-", "");
String fielName=prefix+"_"+name;

   3.有些情况需要限制上传文件的大小

fileUpload.setFileSizeMax(1024*17600);//限制单个文件的大小
fileUpload.setSizeMax(1024*20000);//限制文件的总大小

//会分别抛出异常
catch(SizeLimitExceededException e){
     System.out.println("总图片过大");
}catch(FileSizeLimitExceededException e){
     System.out.println("单张图片过大");
}

 

   4.当用户上传一个空的文件,依然会将文件保存到硬盘上

     解决方法:在保存文件应该先对文件的大小进行判断,如果size为0,则不处理

long size = item.getSize();
//如果不存在,就继续,不必创造文件
if(size==0){
	continue;
}

 

 


 下载

 

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	ServletContext servletContext = request.getServletContext();
	String filename = "风吹麦浪.mp3";
	String path = servletContext.getRealPath("/WEB-INF/"+filename);
	File file = new File(path);
	//创建输入流
	InputStream in = new FileInputStream(file);
	//告诉浏览器文件的类型,需要设置一个MIME值
	//用servletContext.getMimeType()直接获取path的MIME值
	String type = servletContext.getMimeType(path);
		
	response.setContentType(type);
	filename = new String(filename.getBytes("gbk"),"iso8859-1");
	//下载文件信息
	response.setHeader("Content-Disposition", "attachment;filename="+filename);
	//输出流,到浏览器上
	ServletOutputStream out = response.getOutputStream();
	IOUtils.copy(in, out);
	in.close();
}

 

推荐阅读