java实现文件上传

1.文件上传概述

就是把客户端(浏览器)的文件保存一份到服务器 说白了就是文件的拷贝

2.文件上传要求

2.1浏览器端要求(通用浏览器的要求)

  • 表单提交方式 post
  • 提供文件上传框(组件) input type="file"
  • 表单的entype属性必须为 multipart/form-data(没有这个属性值的话, 文件的内容是提交不过去的)

2.2服务器端要求

要使用request.getInputStream()来获取数据. 

注意:

若表单使用了 multipart/form-data ,使用原生request.getParameter()去获取参数的时候都为null

3.常见的文件上传框架

commons-fileupload : 偏底层   

struts2(底层:commons-fileupload)   

SpringMVC

serlvet3.0 

...

4.这里介绍的是commons-fileupload的使用

commons-fileupload是apache出品的一款专门处理文件上传的工具类 

使用步骤:

  1. 导入jar包

  2. 创建磁盘文件项工厂
    DiskFileItemFactory factory=new DiskFileItemFactory();
  3. 创建核心上传对象
    ServletFileUpload upload=new ServletFileUpload(factory);
  4. 解析请求,获取所有的上传组件 List
    List list=upload.parseRequest(request);
  5. 遍历list 获取每一个上传项

FileItem的API:

getFiledName():获取标签里面name属性的值

isFormFiled():判断是否是普通上传组件;

    true:普通上传组件

    false:文件上传组件
  • 普通上传组件, 不是File, 目的获得值
    getString("utf-8"):获取(普通上传组件)用户输入的内容
  • 文件上传组件 是File , 目的: 获得文件名, 获得文件的内容
    getName():获取文件名称
    getInputStream():获取文件的流(文件内容)
    delete():删除文件上传时候产生的临时文件

Eg:

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      try {
        //创建磁盘文件项工厂
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //创建核心上传对象
        ServletFileUpload fileUpload = new ServletFileUpload(factory);
        //获得所有的上传组件
        List<FileItem> list = fileUpload.parseRequest(request);
        for (FileItem fileItem : list) {    
            //判断是否是文件上传
            if(fileItem.isFormField()){
                //普通上传组件
                 //获得标签的name属性值
                String key = fileItem.getFieldName();
                //获得普通上传组件的内容.括号中编码避免中文乱码
                String value = fileItem.getString("utf-8");     
            }else{
                //文件上传组件
                //获得文件上传组件的输入流
                InputStream is = fileItem.getInputStream();
                //创建文件输出流
                OutputStream os= new FileOutputStream("G:/1.txt");
                //开始复制
                IOUtils.copy(is, os);   
              //最后关闭流
                os.close();
                is.close();
            }
        }   
    } catch (Exception e) {
        e.printStackTrace();
    }
}

5上传注意问题

  1. 文件重名问题 后面的会把前面的覆盖掉
    给文件取一个随机名称, uuid方式 或者 毫秒值+三个随机数
  2. 文件名称问题 目的是获得文件真实名字,不带盘符的

    如果是低版本IE:文件名带盘符E:/data/Desktop/a.txt
    其它的火狐,谷歌是文件本来的名字: a.txt 
  3. 常见的目录分离
    按用户划分 适合用户量不大的项目 < 1w
    按时间划分 2018/03/21/17/07
    按数量划分 eg:以2000个为单位
    随机划分 写算法

附:解决文件上传问题的小工具.

import java.util.Random;
import java.util.UUID;
public class UploadUtils {
/**
 * 获取文件真实名称
 * 由于浏览器的不同获取的名称可能为:E:\data\Desktop\a.txt
 * 最终获取的为  1.jpg
 * @param name 上传上来的文件名称
 * @return  真实名称
 */
public static String getRealName(String name){
    //获取最后一个"/"
    int index = name.lastIndexOf("\\");
    return name.substring(index+1);
}
/**
 * 获取随机名称
 * @param realName 真实名称
 * @return uuid 随机名称
 */
public static String getUUIDName(String realName){
    //realname  eg: a.jpg  ---> UUID.jpg;    a --- > UUID
    //获取后缀名
    int index = realName.lastIndexOf(".");
    if(index==-1){
        return UUID.randomUUID().toString().replace("-", "").toUpperCase();
    }else{
        return UUID.randomUUID().toString().replace("-",                                            "").toUpperCase()+realName.substring(index);
        }
    }
/**
 * 获取文件目录,可以获取256个随机目录
 * @return 随机目录
 */
public static String getDir(){//  
    String s="0123456789ABCDEF";
    Random r = new Random();
    return "/"+s.charAt(r.nextInt(16))+"/"+s.charAt(r.nextInt(16));
    }
}

前端页面示例:

<%@ page language="java" contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8"%>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Insert title here</title>
    </head>
    <body>
        <form action="${pageContext.request.contextPath }/demo01" method="post"     enctype="multipart/form-data">
            用户名:<input type="text" name="name"/> <br/>
            文件:<input type="file" name="file"/> <br/>
            <input type="submit" />
        </form>
    </body>
</html>

posted on 2018-03-21 21:14 无冥 阅读(...) 评论(...) 编辑 收藏

统计