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 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"%>



Insert title here



用户名:

文件:




posted on 2018-03-21 21:14  无冥  阅读(214)  评论(0)    收藏  举报