springboot上传文件

1.本地服务器保存文件

1.1配置服务器保存地址

#图片存放地址
file:
  linux:
    path: /images/
  window:
    path: D:/images/

1.2文件上传

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

@Component
@Slf4j
public class FileUtil {
    private static String linuxPath;

    public static String getLinuxPath() {
        return linuxPath;
    }

    @Value("${file.linux.path}")
    public void setLinuxPath(String linuxPath) {
        FileUtil.linuxPath = linuxPath;
    }

    private static String windowPath;

    public static String getWindowPath() {
        return windowPath;
    }

    @Value("${file.window.path}")
    public void setWindowPath(String windowPath) {
        FileUtil.windowPath = windowPath;
    }

    //保存图片并返回地址
    public static String getImgSrc(MultipartFile file){
        try {
            String fileName = file.getOriginalFilename();
            String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
            File files;
            String os = System.getProperty("os.name");
            if(os.toLowerCase().startsWith("win")){
                files = new File(windowPath);
            }else{
                files = new File(linuxPath);
            }
            log.debug("文件夹{}",files);
            if (!files.exists()) {//目录不存在就创建
                files.mkdirs();
            }
            String newName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
            log.debug("文件名称{}",newName);
            file.transferTo(new File(files + File.separator + newName + "." + suffix));
            String realPath;
            if(os.toLowerCase().startsWith("win")){
                realPath = "/" + windowPath + newName + "." + suffix;
            }else{
                realPath = linuxPath + newName + "." + suffix;
            }
            log.debug("路径地址{}",realPath);
            return realPath;
        } catch (IOException e) {
            throw new RuntimeException("文件上传失败");
        }
    }
}

1.3WebConfig配置

import com.oigcn.association.common.WebInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Value("${file.linux.path}")
    private String linuxPath;

    @Value("${file.window.path}")
    private String windowPath;

    /**
     * 拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new WebInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/login/in")
                .excludePathPatterns("/images/**");
    }
    /**
     * 跨域支持
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowCredentials(true)
                .allowedHeaders("*")
                .allowedOrigins("*")
                .allowedMethods("*")
                .maxAge(3600);
    }

    /**
     * 文件上传
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        String os = System.getProperty("os.name");
        if(os.toLowerCase().startsWith("win")){
            registry.addResourceHandler("/" + windowPath + "**").addResourceLocations("file:///" + windowPath);
        }else{
            registry.addResourceHandler(linuxPath + "**").addResourceLocations("file:" + linuxPath);
        }
    }
}

2.外部oss存储minio

2.1服务器配置、maven依赖

#图片服务器minio配置
minio:
  ip: http://ip:9000
  #minio登录账号密码
  accessKey: admin
  secretKey: admin

  #桶名(文件夹)命名规则要符合 亚马逊S3标准 详情可看http://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html
  bucketName:
    #照片文件夹
    images: file
<!--minio oss-->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>5.0.2</version>
        </dependency>

2.2上传文件

import io.minio.MinioClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;

@Component
@Slf4j
public class FileUploader {
    /**
     * 服务器地址
     */
    @Value("${minio.ip}")
    private String ip;

    /**
     * 登录账号
     */
    @Value("${minio.accessKey}")
    private String accessKey;

    /**
     * 登录密码
     */
    @Value("${minio.secretKey}")
    private String secretKey;

    /**
     * 文件上传
     * @param file
     * @param fileName 文件名
     * @param bucketName 桶名(文件夹)
     * @return
     */
    public String upload(MultipartFile file, String fileName, String bucketName){
        try {
            MinioClient minioClient = new MinioClient(ip, accessKey, secretKey);
            boolean bucketExists = minioClient.bucketExists(bucketName);
            if (bucketExists) {
                log.info("仓库" + bucketName + "已经存在,可直接上传文件。");
            } else {
                minioClient.makeBucket(bucketName);
            }
            //上传
            minioClient.putObject(bucketName, fileName, file.getInputStream(), file.getContentType());
            log.info("成功上传文件 " + fileName + "" + bucketName);
            String fileUrl = "/" + bucketName + "/" + fileName;
            return fileUrl;
        } catch (Exception  e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 判断文件是否存在
     * @param fileName 文件名
     * @param bucketName 桶名(文件夹)
     * @return
     */
    public boolean isFileExisted(String fileName, String bucketName) {
        InputStream inputStream = null;
        try {
            MinioClient minioClient = new MinioClient(ip, accessKey, secretKey);
            inputStream = minioClient.getObject(bucketName, fileName);
            if (inputStream != null) {
                return true;
            }
        } catch (Exception e) {
            return false;
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }
    /**
     * 删除文件
     * @param fileName 文件名
     * @param bucketName 桶名(文件夹)
     * @return
     */
    public boolean delete(String fileName,String bucketName) {
        try {
            MinioClient minioClient = new MinioClient(ip, accessKey, secretKey);
            minioClient.removeObject(bucketName,fileName);
            return true;
        } catch (Exception e) {
            log.error(e.getMessage());
            return false;
        }
    }
    /**
     * 获取文件流
     * @param fileName 文件名
     * @param bucketName 桶名(文件夹)
     * @return
     */
    public InputStream getFileInputStream(String fileName,String bucketName) {
        try {
            MinioClient minioClient = new MinioClient(ip, accessKey, secretKey);
            return minioClient.getObject(bucketName,fileName);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return null;
    }
}

2.3文件上传、预览

import com.oigcn.association.utils.FileUploader;
import com.oigcn.association.utils.Response;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

@RestController
@RequestMapping("/common")
@Slf4j
@Api(tags = "公共接口")
public class CommonAction {
    @Autowired
    private FileUploader fileUploader;

    @Value("${minio.bucketName.images}")
    private String bucketName;

    @PostMapping("/image/upload")
    @ApiOperation(value = "图片上传")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "MultipartFile[]",required = true),
    })
    public Response imageUpload(@RequestParam("file") MultipartFile file){
        if(file == null){
            return Response.failure("file为空");
        }
        log.info("图片上传{}",file.getOriginalFilename());
        //文件是否存在
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
        String newName = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + "." + suffix;
        boolean exist = fileUploader.isFileExisted(newName,bucketName);
        if(exist){
            throw new RuntimeException("文件名重复");
        }
        //上传文件
        String fileUrl = fileUploader.upload(file,newName,bucketName);
        return Response.success(fileUrl);
    }
    @GetMapping("/image/view/**")
    @ApiOperation(value = "图片预览")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "imgSrc", value = "上传图片时候返回地址",required = true),
    })
    public void imageView(HttpServletRequest request, HttpServletResponse response){
        String imgSrc = extractPathFromPattern(request);
        if(StringUtils.isBlank(imgSrc)){
            throw new RuntimeException("图片地址为空");
        }
        response.setContentType("image/jpeg;charset=utf-8");
        //文件
        String bucketName = imgSrc.split("/")[0];
        //文件名
        String fileName = imgSrc.split("/")[1];
        try(InputStream inputStream = fileUploader.getFileInputStream(fileName,bucketName); OutputStream outputStream = response.getOutputStream()) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) > 0) {
                outputStream.write(buffer, 0, len);
            }
            response.flushBuffer();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static String extractPathFromPattern(final HttpServletRequest request) {
        String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
        String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
        return new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path);
    }
}
原文地址:https://www.cnblogs.com/i-tao/p/14247916.html