springboot2之文件上传接口两种实现(后端调用直接传输文件流和前端ajax调用支持Formdata)

Posted 零度anngle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot2之文件上传接口两种实现(后端调用直接传输文件流和前端ajax调用支持Formdata)相关的知识,希望对你有一定的参考价值。

package com.citicpress.cspp.user.controller;

import com.citicpress.cspp.common.dto.ResponseHeader;
import com.citicpress.cspp.common.dto.ResponseParam;
import com.citicpress.cspp.common.model.TokenUserInfo;
import com.citicpress.cspp.common.service.RedisClientService;
import com.citicpress.cspp.user.dto.UploadFileResponseBody;
import com.citicpress.cspp.user.service.FileService;
import com.citicpress.cspp.utils.OSSManageUtil;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


@RestController
@RequestMapping("/api")
public class FileController

    private static final Logger logger = LoggerFactory.getLogger(FileController.class);

    @Value("$client.logout.fixed.token")
    private String logoutFixedToken;

    @Autowired
    private RedisClientService redisClientService;

    @Autowired
    private FileService fileService;

    /**
     * 1、文件上传---request仅仅接收二进制文件流(适用于后端调用rest进行文件上传)
     * @param request
     * @return
     */
    @RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
    public ResponseParam<UploadFileResponseBody> uploadFile(HttpServletRequest request)

        try
        InputStream ins = request.getInputStream();
            ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
            byte[] b = new byte[2048];
            int rc = 0;
            while ((rc = ins.read(b)) > 0)
                swapStream.write(b, 0, rc);
           
            byte[] fileContent = swapStream.toByteArray();

            //文件上传到OSS中,可忽略:根据情况而定-上传到其他云端,还是进存储再本地
            String filePath = OSSManageUtil.simpleUploadFileStream(new ByteArrayInputStream(fileContent), imageType, fileName);


            filePath = OSSManageUtil.getImgUrl(filePath);
            //返回文件的相对路径
            if (StringUtils.isBlank(filePath))
                return new ResponseParam<>(new ResponseHeader("500", "上传失败!"));
            else
                return new ResponseParam<>(new ResponseHeader("200", "上传成功!"), new UploadFileResponseBody(filePath));
           
        catch (Exception e)
            logger.error("上传文件出错", e);
            return new ResponseParam<>(new ResponseHeader("200", "上传失败!"));
       


   


    /**

      *2、上传文件---支持formdata形式(适用于H5前端组件ajax上传)---解决Springboot 直接使用MultiPartFile file 接收文件报:
      *java.io.FileNotFoundException异常;网上查了很多都不能解决使用MultiPartFile file参数接收formdata的文件数据,直接使          *用request获取亲测可行;

      */

    @RequestMapping(value = "/uploadFile4FormData")
    public ResponseParam<UploadFileResponseBody> uploadImg(HttpServletRequest request) throws Exception

        DefaultMultipartHttpServletRequest req = (DefaultMultipartHttpServletRequest)request;  //重点关注:强制转换
        MultipartFile file = req.getFile("file");
        InputStream ins = file.getInputStream();
        ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
        byte[] a = new byte[2048];
        int rca = 0;
        while ((rca = ins.read(a)) > 0)
            swapStream.write(a, 0, rca);
       
        byte[] fileContent = swapStream.toByteArray();
        //文件上传到OSS中,可忽略:根据情况而定-上传到其他云端
        String filePath = OSSManageUtil.simpleUploadFileStream(new ByteArrayInputStream(fileContent), imageType, fileName);

        filePath = OSSManageUtil.getImgUrl(filePath);
        //返回文件的相对路径
        if (StringUtils.isBlank(filePath))
            return new ResponseParam<>(new ResponseHeader("500", "上传失败!"));
        else
            return new ResponseParam<>(new ResponseHeader("200", "上传成功!"), new UploadFileResponseBody(filePath));
       

   

 

接口2,需要添加下面配置:

@Bean
public MultipartConfigElement multipartConfigElement() 
   MultipartConfigFactory factory = new MultipartConfigFactory();
   factory.setMaxFileSize(DataSize.ofBytes(1024*1024*64));
   factory.setMaxRequestSize(DataSize.ofBytes(1024*1024*64));
   return factory.createMultipartConfig();



@Bean
public CommonsMultipartResolver multipartResolver() 
   return new CommonsMultipartResolver();

否则会报:org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.ClassCastException: org.springframework.web.multipart.support.StandardMultipartHttpServletRequest cannot be cast to org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)


以上是关于springboot2之文件上传接口两种实现(后端调用直接传输文件流和前端ajax调用支持Formdata)的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot + Vue(前后端分离之博客上传)

springboot2.0结合webuploader实现文件分片上传

配置Spring项目上传的两种方式(全解析)

fetch上传图片(formData数据格式)失败之解决办法

Android实战——第三方服务之Bmob后端云的增删改查上传文件获取文件修改密码

springboot2.0结合fastdfs实现文件分布式上传