文件上传

Posted lpl666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件上传相关的知识,希望对你有一定的参考价值。

需求

技术图片

前端代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>上传图片</title>
  <script src="js/jquery-1.12.4.min.js"></script>
  <style>
    a {
      text-decoration: none;
      display: block;
      width: 100px;
      height: 25px;
      border-radius: 25px;
      background: darkcyan;
      color:#fff;
      text-align: center;
      line-height: 25px;

    }
    a:active{
      background: orange;
    }
  </style>
</head>
<body>
  <form enctype="multipart/form-data">
    <input type="file" name="avatar"  id="avatar" style="display: none;">
  </form>
  <a href="javascript:" id="btn">上传图片</a>
  <span></span><br>
  <img src="img/default.jpg" style="width: 150px;" alt="">
  <script>
    $("#btn").click(function(){
      // 检测用户是否选择完毕
      $('#avatar').change(function(){
        // 获取文件名
        var fileName = $('#avatar').val().split("")[2];
        $('span').html(fileName);
        // 创建表单数据对象
        var fm = new FormData($('form')[0]);
        // 发送ajax请求上传图片到服务器
        $.ajax({
          url:'http://localhost/upload',
          data:fm,
          type: "post",
          processData:false,
          contentType:false,
          success:function(v){
            $('img').attr('src','http://localhost:52330/resources/images/' + v.url);
          }

        });
      });
      // 触发上传图片事件
      $('#avatar').click();
    });
  </script>
</body

后端代码(Java版)

项目核心目录结构

技术图片

Maven文件上传依赖项

    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.4</version>
    </dependency>

工具类代码

BaseUtil.java

package util;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class BaseUtil {
  private static String uploadDir=null;
  static {
    try {
      // 获取上传文件目录的配置文件流
      InputStream uploadBaseUrl_inputStream = BaseUtil.class.getClassLoader().getResourceAsStream("upload.properties");
      // 创建Properties集合
      Properties uploadBaseUrl_properties = new Properties();
      uploadBaseUrl_properties.load(uploadBaseUrl_inputStream);
      uploadDir=uploadBaseUrl_properties.get("baseUrl").toString();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  // 获取文件上传的目录
  public static String getUploadBaseDir(){
    return uploadDir;
  }
}

FileUtil.java

package util;
import java.io.File;
import java.util.Random;
import java.util.UUID;
public class FileUtil {
  private static Random random = new Random();
  // 随机生成分散目录
  public static String getDir(){
    String dir = null;
    String values = "abcdefg01234567890";
    int i = random.nextInt(values.length());
    String path =  String.valueOf(values.charAt(i));
    return path;
  };
  // 保证目录必须存在
  public static String mustDir(String path){
    File file = new File(path);
    if(!file.exists()){
      file.mkdirs();
    }
    return path;
  };
  // 生成唯一文件名
  public static String FileName(String uploadName){
    UUID uuid = UUID.randomUUID();
    String uid = uuid.toString().replaceAll("-","");
    String fileName =  uid;
    return fileName+"."+getExt(uploadName);
  }
  // 根据上传文件名获取扩展名
  public static String getExt(String uploadName){
    return uploadName.split(".")[1];
  }
  
}

配置文件

upload.properties

baseUrl=C:/Users/Bruce/Desktop/H5/resources/images/

过滤器-跨域设置

CORSFilter.java

package web;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter("/*")
public class CORSFilter implements Filter {
  public void destroy() {
  }
  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
    HttpServletRequest request = (HttpServletRequest)req;
    HttpServletResponse response = (HttpServletResponse)resp;
    String origin = request.getHeader("Origin");
    // 解决跨域的数据问题
    response.setHeader("Access-Control-Allow-Origin",origin);
    // 解决跨域的cookie问题
    response.setHeader("Access-Control-Allow-Credentials","true");
    chain.doFilter(req, resp);
  }

  public void init(FilterConfig config) throws ServletException {

  }

}

Servlet处理程序

UploadServlet.java

package web;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import util.BaseUtil;
import util.FileUtil;

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 java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
  // 【post】
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 上传文件并获取参数集合
    Map<String, String[]> paramsMap = getParamsMap(request);
    // 获取文件名称
    String value = paramsMap.get("avatar")[0];
    // 创建map对象
    Map<String,String> obj = new HashMap<>();
    obj.put("url",value);
    // jackson
    ObjectMapper mapper = new ObjectMapper();
    // 设置响应头
    response.setContentType("application/json;charset=utf-8");
    // 响应并返回json
    mapper.writeValue(response.getOutputStream(),obj);
  }
  // 【上传文件并获取参数集合】
  public Map<String,String[]> getParamsMap(HttpServletRequest request){
    Map<String,String[]> map = new HashMap<>();
    try {
      // 1. 创建文件磁盘工厂对象
      DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
      // 2. 创建上传解析对象,帮助解析request对象中的inputStream
      ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
      // 3. 解析完成,返回List集合
      List<FileItem> fileItems = servletFileUpload.parseRequest(request);
      // 4. 遍历集合
      for (FileItem fileItem : fileItems) {
        // 4.1 获取表单项名字
        String fieldName = fileItem.getFieldName();
        // 4.2 检测是否是普通表单项
        if (fileItem.isFormField()) {
          // 4.2.1 获取普通项的值
          String value = fileItem.getString("utf-8");
          if(map.containsKey(fieldName)){
            String[]oldArr = map.get(fieldName);
            String[]newArr = new String[]{value};
            String[]result=new String[oldArr.length + newArr.length];
            System.arraycopy(oldArr,0,result,0,oldArr.length);
            System.arraycopy(newArr,0,result,oldArr.length,newArr.length);
            map.put(fieldName,result);
          }
          else {
            map.put(fieldName,new String[]{value});
          }
        }
        // 4.3 操作文件流
        else {
          // 获取文件名
          String fileName = fileItem.getName();
          // 获取要上传的目录
          String baseDir = BaseUtil.getUploadBaseDir();
          // 获取分散目录
          String smallDir=FileUtil.getDir();
          // 完整目录
          String path = baseDir + smallDir;
          // 该目录必须存在
          FileUtil.mustDir(path);
          // 定义唯一文件名
          String fileNameId = FileUtil.FileName(fileName);

          // 4.3.1 获取文件流输入流
          InputStream inputStream = fileItem.getInputStream();
          // 4.3.2 创建输出流
          FileOutputStream os = new FileOutputStream(path
                  +"/"+fileNameId);
          byte[] bs = new byte[1024];
          int len = 0;
          // 读取文件流输入流中内容
          while ((len = inputStream.read(bs)) != -1) {
            os.write(bs, 0, len);
          }
          inputStream.close();
          os.close();
          // 删除临时文件
          fileItem.delete();
          map.put(fieldName,new String[]{smallDir + "/" + fileNameId});
        }

      }

    }
    catch (Exception e) {
      e.printStackTrace();
    }
    return map;
  }
  // 【get】
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    this.doPost(request, response);
  }

}

上传多个文件

前端代码

技术图片

    <form action="upload2Servlet" enctype="multipart/form-data" method="post">
        <p>
            <span>姓名:</span>
            <input type="text" name="username">
        </p>
        <p>
            <span>爱好:</span>
            <input type="checkbox" name="hobby" value="跑步"> 跑步
            <input type="checkbox" name="hobby" value="跳绳"> 跳绳
            <input type="checkbox" name="hobby" value="拳击"> 拳击
        </p>
        <p>
            <span>相册:</span>
            <input type="file" name="avatar" multiple>
        </p>
        <input type="submit">
    </form>

后端处理程序

Upload2Servlet.java

package web;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import util.BaseUtil;
import util.FileUtil;

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 java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@WebServlet("/upload2Servlet")
public class Upload2Servlet extends HttpServlet {
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 上传文件,并获取相关参数
    Map<String, String[]> paramsMap = getParamsMap(request);
    Set<Map.Entry<String, String[]>> entries = paramsMap.entrySet();
    // 循环遍历查看参数信息
    for (Map.Entry<String, String[]> entry : entries) {
      System.out.println(entry.getKey()+"---"+ Arrays.toString(entry.getValue()));
    }
    // 输出结果
    //    avatar---[0/d777d06d4a214b068cb0633012924375.jpg, e/f06da8b44d6c4848ad2dbdf216b80508.jpg, d/f0dcb11671af46309ae2d45bee8b88ae.jpg, 6/32bdd21eb2fb491cb5fc9acd7bcc24cf.jpg]
    //    username---[Bruce]
    //    hobby---[跑步, 跳绳, 拳击]
  }
  // 【上传文件并获取参数集合】
  public Map<String,String[]> getParamsMap(HttpServletRequest request){
    Map<String,String[]> map = new HashMap<>();
    try {
      // 1. 创建文件磁盘工厂对象
      DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
      // 2. 创建上传解析对象,帮助解析request对象中的inputStream
      ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
      // 3. 解析完成,返回List集合
      List<FileItem> fileItems = servletFileUpload.parseRequest(request);
      // 4. 遍历集合
      for (FileItem fileItem : fileItems) {
        // 4.1 获取表单项名字
        String fieldName = fileItem.getFieldName();
        // 4.2 检测是否是普通表单项
        if (fileItem.isFormField()) {
          // 4.2.1 获取普通项的值
          String value = fileItem.getString("utf-8");
          if(map.containsKey(fieldName)){
            String[]oldArr = map.get(fieldName);
            String[]newArr = new String[]{value};
            String[]result=new String[oldArr.length + newArr.length];
            System.arraycopy(oldArr,0,result,0,oldArr.length);
            System.arraycopy(newArr,0,result,oldArr.length,newArr.length);
            map.put(fieldName,result);
          }
          else {
            map.put(fieldName,new String[]{value});
          }
        }
        // 4.3 操作文件流
        else {
          // 获取文件名
          String fileName = fileItem.getName();
          // 获取要上传的目录
          String baseDir = BaseUtil.getUploadBaseDir();
          // 获取分散目录
          String smallDir= FileUtil.getDir();
          // 完整目录
          String path = baseDir + smallDir;
          // 该目录必须存在
          FileUtil.mustDir(path);
          // 定义唯一文件名
          String fileNameId = FileUtil.FileName(fileName);

          // 4.3.1 获取文件流输入流
          InputStream inputStream = fileItem.getInputStream();
          // 4.3.2 创建输出流
          FileOutputStream os = new FileOutputStream(path
                  +"/"+fileNameId);
          byte[] bs = new byte[1024];
          int len = 0;
          // 读取文件流输入流中内容
          while ((len = inputStream.read(bs)) != -1) {
            os.write(bs, 0, len);
          }
          inputStream.close();
          os.close();
          // 删除临时文件
          fileItem.delete();
          // 检测是否已经存在
          if(map.containsKey(fieldName)){
            String[]oldArr = map.get(fieldName);
            String[]newArr = new String[]{smallDir + "/" + fileNameId};
            String[]result=new String[oldArr.length + newArr.length];
            System.arraycopy(oldArr,0,result,0,oldArr.length);
            System.arraycopy(newArr,0,result,oldArr.length,newArr.length);
            map.put(fieldName,result);
          }
          else{
            map.put(fieldName,new String[]{smallDir + "/" + fileNameId});
          }

        }

      }

    }
    catch (Exception e) {
      e.printStackTrace();
    }
    return map;
  }
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    this.doPost(request, response);
  }
}

以上是关于文件上传的主要内容,如果未能解决你的问题,请参考以下文章

将存储在内存中的文件上传到s3

JS创建文件并上传服务器

ajaxFileUpload上传带参数文件及JS验证文件大小

android的自带的httpClient 怎么上传文件

大文件上传下载实现思路,分片断点续传代码实现,以及webUpload组件

如何通过 HttpWebRequest 上传文件?