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 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 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)


}

你可能感兴趣的:(Java,spring,boot,springboot,文件上传)