網站上傳圖片、文件等,最多見的就是直接上傳到服務器的webapp目錄下,或者直接上傳服務的一個指定的文件夾下面。這種方式對於簡單的單機應用確實是很方便、簡單,出現的問題也會比較少。可是對於分佈式項目,直接上傳到項目路徑的方式顯然是不可靠的,並且隨着業務量的增長,文件也會增長,對服務器的壓力天然就增長了。這裏簡單的介紹本身所瞭解的幾種方式保存文件。html
首先說明,該項目結構是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服務器,這裏就不介紹了。傳送門: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; }
測試:
參考: