示例環境:JDK8+MAVEN3+SSM(Spring+SpringMVC+MyBatis Plus或者MyBatis)javascript
如今比較流行的除了分佈式或微服務就是動靜分離。css
動靜分離,以nginx集羣爲例,nginx一般加載靜態資源(js,img,css等)效率相對tomcat等應用服務器效率是很是高的,由其專門處理靜態資源,而動態資源,一般由tomcat等應用服務器來處理,應用服務器處理動態資源的效率比nginx處理靜態資源效率又要高不少不少。就將它們作一個分工。利於靜態資源處理就使用nginx,利於動態資源處理使用tomcat或者其餘應用服務器等。這樣分離的好處,各自發揮其優點,即利於資源充分利用,又利於系統性能。html
傳統的圖片服務器ftp,就如今而言已經沒幾我的在用了,固然了,wordpress相關的插件安裝和主題下載就用到ftp。java
固然了,還有很多企業將上傳文件(包含圖片等)放入線上tomcat某個文件夾下或者項目裏面,這樣的弊端使項目會愈來愈龐大,以前龐大是由於不斷增加的需求,代碼不得不越多,所以也會擴充容量。jquery
不過目前不少企業一般採用好比騰訊雲、阿里雲、七牛雲等對象存儲,做爲圖片存儲。nginx
1、導入依賴web
<!-- 騰訊雲 --> <dependency> <groupId>com.qcloud</groupId> <artifactId>cos_api</artifactId> <version>5.2.4</version> </dependency>
2、編寫工具類ajax
package com.custome; import com.qcloud.cos.COSClient; import com.qcloud.cos.ClientConfig; import com.qcloud.cos.auth.BasicCOSCredentials; import com.qcloud.cos.auth.COSCredentials; import com.qcloud.cos.model.ObjectMetadata; import com.qcloud.cos.model.PutObjectResult; import com.qcloud.cos.region.Region; import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.net.URL; import java.util.Date; import java.util.Random; public class COSClientUtil { //todo 這些變量信息自行到 騰訊雲對象存儲控制檯 獲取 private COSClient cOSClient; private static final String ENDPOINT = "test.com"; //用戶能夠指定域名,不指定則爲默認生成的域名 //secretId private static final String secretId = "AKIDCJ"; // secretKey private static final String secretKey = "CD7"; // 存儲通名稱 private static final String bucketName = "test";//公有讀私有寫 // 1 初始化用戶身份信息(secretId, secretKey) private static COSCredentials cred = new BasicCOSCredentials(secretId, secretKey); // 2 設置bucket的區域, COS地域的簡稱請參照 https://cloud.tencent.com/document/product/436/6224 private static ClientConfig clientConfig = new ClientConfig(new Region("ap-beijing-1")); // 3 生成cos客戶端 private static COSClient cosclient = new COSClient(cred, clientConfig); public COSClientUtil() { cOSClient = new COSClient(cred, clientConfig); } /** * 銷燬 */ public void destory() { cOSClient.shutdown(); } /** * 上傳圖片 * * @param url */ public void uploadImg2Cos(String url) throws Exception { File fileOnServer = new File(url); FileInputStream fin; try { fin = new FileInputStream(fileOnServer); String[] split = url.split("/"); this.uploadFile2Cos(fin, split[split.length - 1]); } catch (FileNotFoundException e) { throw new Exception("圖片上傳失敗"); } } public String uploadFile2Cos(MultipartFile file) throws Exception { if (file.getSize() > 10 * 1024 * 1024) { throw new Exception("上傳圖片大小不能超過10M!"); } //圖片名稱 String originalFilename = file.getOriginalFilename(); System.out.println("originalFilename = " + originalFilename); //圖片後綴 String substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase(); System.out.println("substring = " + substring); Random random = new Random(); //生成新的圖片名稱(隨機數0-9999+系統當前時間+上傳圖片名) String name = random.nextInt(10000) + System.currentTimeMillis() + "_" + substring; try { InputStream inputStream = file.getInputStream(); this.uploadFile2Cos(inputStream, name); return name; } catch (Exception e) { throw new Exception("圖片上傳失敗"); } } /** * 得到圖片路徑 * * @param fileUrl * @return */ public String getImgUrl(String fileUrl) { return getUrl(fileUrl); } /** * 得到url連接 * * @param key * @return */ public String getUrl(String key) { // 設置URL過時時間爲10年 3600l* 1000*24*365*10 Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 10); // 生成URL URL url = cOSClient.generatePresignedUrl(bucketName, key, expiration); if (url != null) { return url.toString(); } return null; } /** * 上傳到COS服務器 若是同名文件會覆蓋服務器上的 * * @param instream * 文件流 * @param fileName * 文件名稱 包括後綴名 * @return 出錯返回"" ,惟一MD5數字簽名 */ public String uploadFile2Cos(InputStream instream, String fileName) { String ret = ""; try { // 建立上傳Object的Metadata ObjectMetadata objectMetadata = new ObjectMetadata(); objectMetadata.setContentLength(instream.available()); objectMetadata.setCacheControl("no-cache"); objectMetadata.setHeader("Pragma", "no-cache"); objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf(".")))); objectMetadata.setContentDisposition("inline;filename=" + fileName); // 上傳文件 PutObjectResult putResult = cOSClient.putObject(bucketName, fileName, instream, objectMetadata); ret = putResult.getETag(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (instream != null) { instream.close(); } } catch (IOException e) { e.printStackTrace(); } } return ret; } /** * Description: 判斷Cos服務文件上傳時文件的contentType * * @param filenameExtension 文件後綴 * @return String */ public static String getcontentType(String filenameExtension) { if (filenameExtension.equalsIgnoreCase("bmp")) { return "image/bmp"; } if (filenameExtension.equalsIgnoreCase("gif")) { return "image/gif"; } if (filenameExtension.equalsIgnoreCase("jpeg") || filenameExtension.equalsIgnoreCase("jpg") || filenameExtension.equalsIgnoreCase("png")) { return "image/jpeg"; } if (filenameExtension.equalsIgnoreCase("html")) { return "text/html"; } if (filenameExtension.equalsIgnoreCase("txt")) { return "text/plain"; } if (filenameExtension.equalsIgnoreCase("vsd")) { return "application/vnd.visio"; } if (filenameExtension.equalsIgnoreCase("pptx") || filenameExtension.equalsIgnoreCase("ppt")) { return "application/vnd.ms-powerpoint"; } if (filenameExtension.equalsIgnoreCase("docx") || filenameExtension.equalsIgnoreCase("doc")) { return "application/msword"; } if (filenameExtension.equalsIgnoreCase("xml")) { return "text/xml"; } return "image/jpeg"; } }
3、編寫Controller方法spring
@PostMapping(value="/uploadPicture",produces="application/json;charset=utf-8") public JSONObject upModify(HttpServletRequest request, MultipartFile file) { JSONObject json = new JSONObject(); try { COSClientUtil cosClientUtil = new COSClientUtil(); //獲取Cookie String cookie = CookieUtils.getCookie(request,"userCode"); //解密後的userCode String decodeStr = Base64.decodeStr(cookie); if(!file.isEmpty()) { String name = cosClientUtil.uploadFile2Cos(file); //圖片名稱 System.out.println("name = " + name); //上傳到騰訊雲 String img_url = cosClientUtil.getImgUrl(name); System.out.println("img_url = " + img_url); //數據庫保存圖片地址 String db_img_url = img_url.substring(0,img_url.indexOf("?")); System.out.println("db_img_url = " + db_img_url); SysUser user = new SysUser(); user.setUserCode(decodeStr); user.setAvatar(db_img_url); //調用修改邏輯 boolean isModifyUser = userService.updateById(user); if(isModifyUser) { json.put("returnCode", "000000"); json.put("returnMsg", "上傳文件成功"); }else { json.put("returnCode", "111111"); json.put("returnMsg", "上傳文件失敗"); } }else { json.put("returnCode", "222222"); json.put("returnMsg", "參數異常"); } } catch (Exception e) { e.printStackTrace(); json.put("returnCode", "333333"); json.put("returnMsg", "特殊異常"); } return json; }
4、編寫簡單html測試數據庫
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>上傳圖片測試</title> <script type="text/javascript" src="../js/jquery-1.8.0.min.js"></script> <script type="text/javascript"> function setImg(obj){//用於進行圖片上傳,返回地址 var f = $(obj).val(); if(f == null || f == undefined || f == ''){ return false; } if(!/\.(?:png|jpg|bmp|gif|PNG|JPG|BMP|GIF)$/.test(f)) { alertLayel("類型必須是圖片(.png|jpg|bmp|gif|PNG|JPG|BMP|GIF)"); $(obj).val(''); return false; } var data = new FormData(); $.each($(obj)[0].files,function(i,file){ data.append('file', file); }); var upload_img = $("#uploadinput")[0].files[0]; var url = window.URL.createObjectURL(upload_img); $.ajax({ type: "POST", url: "uploadPicture", data: data, cache: false, contentType: false, //必須false纔會自動加上正確的Content-Type processData: false, //必須false纔會自動加上正確的Content-Type dataType:"json", success: function(data) { alert(data.returnMsg) }, error: function(XMLHttpRequest, textStatus, errorThrown) { alert(XMLHttpRequest.status); // 狀態 alert(XMLHttpRequest.readyState); // 錯誤信息 alert(textStatus); } }); } </script> </head> <body> <input type="file" id="uploadinput" name="file" onchange="setImg(this)"/> </body> </html>