關於SpringBoot上傳圖片的幾種方式

網站上傳圖片、文件等,最多見的就是直接上傳到服務器的webapp目錄下,或者直接上傳服務的一個指定的文件夾下面。這種方式對於簡單的單機應用確實是很方便、簡單,出現的問題也會比較少。可是對於分佈式項目,直接上傳到項目路徑的方式顯然是不可靠的,並且隨着業務量的增長,文件也會增長,對服務器的壓力天然就增長了。這裏簡單的介紹本身所瞭解的幾種方式保存文件。html

  1. 直接上傳到指定的服務器路徑;
  2. 上傳到第三方內容存儲器,這裏介紹將圖片保存到七牛雲
  3. 本身搭建文件存儲服務器,如:FastDFS

最簡單的上傳

首先說明,該項目結構是SpringBoot+mybatis。由於項目使用jar形式打包,因此這裏將圖片保存到一個指定的目錄下。<!--more-->
添加WebAppConfig配置類java

@Configuration
public class WebAppConfig extends WebMvcConfigurerAdapter{

    /**
     * 在配置文件中配置的文件保存路徑
     */
    @Value("${img.location}")
    private String location;

    @Bean
    public MultipartConfigElement multipartConfigElement(){
        MultipartConfigFactory factory = new MultipartConfigFactory();
        //文件最大KB,MB
        factory.setMaxFileSize("2MB");
        //設置總上傳數據總大小
        factory.setMaxRequestSize("10MB");
        return factory.createMultipartConfig();
    }
}

文件上傳的方法,這個方法有些參數可能須要作簡單的修改,大體就是文件先作文件保存路徑的處理,而後保存文件到該路徑,最後返回文件上傳信息git

@PutMapping("/article/img/upload")
    public MarkDVo uploadImg(@RequestParam("editormd-image-file") MultipartFile multipartFile)  {
        if (multipartFile.isEmpty() || StringUtils.isBlank(multipartFile.getOriginalFilename())) {
           throw new BusinessException(ResultEnum.IMG_NOT_EMPTY);
        }
        String contentType = multipartFile.getContentType();
        if (!contentType.contains("")) {
            throw new BusinessException(ResultEnum.IMG_FORMAT_ERROR);
        }
        String root_fileName = multipartFile.getOriginalFilename();
        logger.info("上傳圖片:name={},type={}", root_fileName, contentType);
        //處理圖片
        User currentUser = userService.getCurrentUser();
        //獲取路徑
        String return_path = ImageUtil.getFilePath(currentUser);
        String filePath = location + return_path;
        logger.info("圖片保存路徑={}", filePath);
        String file_name = null;
        try {
            file_name = ImageUtil.saveImg(multipartFile, filePath);
            MarkDVo markDVo = new MarkDVo();
            markDVo.setSuccess(0);
            if(StringUtils.isNotBlank(file_name)){
                markDVo.setSuccess(1);
                markDVo.setMessage("上傳成功");
                markDVo.setUrl(return_path+File.separator+file_name);
                markDVo.setCallback(callback);
            }
            logger.info("返回值:{}",markDVo);
            return markDVo;
        } catch (IOException e) {
            throw new BusinessException(ResultEnum.SAVE_IMG_ERROE);
        }
    }

文件保存類github

/**
     * 保存文件,直接以multipartFile形式
     * @param multipartFile
     * @param path 文件保存絕對路徑
     * @return 返回文件名
     * @throws IOException
     */
    public static String saveImg(MultipartFile multipartFile,String path) throws IOException {
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        FileInputStream fileInputStream = (FileInputStream) multipartFile.getInputStream();
        String fileName = Constants.getUUID() + ".png";
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path + File.separator + fileName));
        byte[] bs = new byte[1024];
        int len;
        while ((len = fileInputStream.read(bs)) != -1) {
            bos.write(bs, 0, len);
        }
        bos.flush();
        bos.close();
        return fileName;
    }

配置文件保存路徑

測試:直接使用postman上傳


下面須要訪問預覽該上傳的圖片
在配置文件中添加對靜態資源的配置。SpringBoot對靜態的的處理,Springboot 之 靜態資源路徑配置

而後在瀏覽器連接欄輸入:此處應該忽略圖片
web

上傳到七牛雲

這裏首先要在七牛雲中註冊一個帳號,並開通對象存儲空間,免費用戶有10G的存儲空間。教程:http://jiantuku.com/help/faq.html?src=settings_headajax

而後在本身的項目中搭建環境:使用maven導包spring

<dependency>
    <groupId>com.qiniu</groupId>
    <artifactId>qiniu-java-sdk</artifactId>
    <version>[7.2.0, 7.2.99]</version>
</dependency>

而後再剛纔找到剛纔建立密鑰,複製出來保存保存在項目資源文件中

這裏的bucket就是上面的存儲空間名稱,而後path是域名。

上傳工具類:瀏覽器

@Component
public class QiniuUtil{

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

    @Value("${qiniu.accessKey}")
    private String accessKey;

    @Value("${qiniu.secretKey}")
    private String secretKey;

    @Value("${qiniu.bucket}")
    private String bucket;

    @Value("${qiniu.path}")
    private String path;

    /**
     * 將圖片上傳到七牛雲
     * @param file
     * @param key 保存在空間中的名字,若是爲空會使用文件的hash值爲文件名
     * @return
     */
    public  String uploadImg(FileInputStream file, String key) {
        //構造一個帶指定Zone對象的配置類
        Configuration cfg = new Configuration(Zone.zone1());
//...其餘參數參考類註釋
        UploadManager uploadManager = new UploadManager(cfg);
//...生成上傳憑證,而後準備上傳
//        String bucket = "oy09glbzm.bkt.clouddn.com";
        //默認不指定key的狀況下,以文件內容的hash值做爲文件名
        try {
            Auth auth = Auth.create(accessKey, secretKey);
            String upToken = auth.uploadToken(bucket);
            try {
                Response response = uploadManager.put(file, key, upToken, null, null);
                //解析上傳成功的結果
                DefaultPutRet putRet = JSON.parseObject(response.bodyString(), DefaultPutRet.class);
//                DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
//                System.out.println(putRet.key);
//                System.out.println(putRet.hash);
                String return_path = path+"/"+putRet.key;
                logger.info("保存地址={}",return_path);
                return return_path;
            } catch (QiniuException ex) {
                Response r = ex.response;
                System.err.println(r.toString());
                try {
                    System.err.println(r.bodyString());
                } catch (QiniuException ex2) {
                    //ignore
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
}

上傳接口方法七牛雲存儲

/**
     * 上傳文件到七牛雲存儲
     * @param multipartFile
     * @return
     * @throws IOException
     */
    @PutMapping("/article/img/qiniu")
    public String uploadImgQiniu(@RequestParam("editormd-image-file") MultipartFile multipartFile) throws IOException {
        FileInputStream inputStream = (FileInputStream) multipartFile.getInputStream();
        User currentUser = userService.getCurrentUser();
        String path = qiniuUtil.uploadImg(inputStream, currentUser.getUsername()+"_"+Constants.getUUID());
        return path;
    }

測試

springboot

上傳文件到FastDFS

首先須要搭建FastDFS服務器,這裏就不介紹了。傳送門:Linux下FastDFS系統的搭建
依賴

<!--FastDFS存儲圖片 start-->
    <dependency>
        <groupId>com.github.tobato</groupId>
        <artifactId>fastdfs-client</artifactId>
        <version>1.25.4-RELEASE</version>
    </dependency>
    <!--FastDFS存儲圖片 end-->

添加配置信息

FastDFS配置類

@Configuration
@ComponentScan(value = "com.github.tobato.fastdfs.service")
@Import(FdfsClientConfig.class)
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class FastDfsConfig {
}

這裏對於FastDFS文件的操做只處理上傳,上傳文件類:

@Autowired
    private FastFileStorageClient storageClient;

    @Autowired
    private FdfsWebServer fdfsWebServer;

     @PutMapping("/article/img/fdfs")
    public String uploadImgfdfs(@RequestParam(value = "editormd-image-file") MultipartFile multipartFile) throws IOException {
        StorePath storePath= storageClient.uploadFile(multipartFile.getInputStream(), multipartFile.getSize(), "png", null);
        String path = storePath.getFullPath();
        logger.info("保存路徑={}",path);
        return path;
    }

測試:


參考:

相關文章
相關標籤/搜索