我所想要的圖片上傳接口是指服務器端在完成圖片上傳后,返回一個可訪問的圖片地址。
spring mvc框架下圖片上傳非常簡單,如下
1 @RequestMapping(value="/uploadImg", method=RequestMethod.POST) 2 @ResponseBody 3 public String uploadImg(@RequestParam(value="img")MultipartFile img){ 4 File f = new File("/data/images"); 5 try{ 6 FileUtils.copyInputStreamToFile(img.getInputStream(), f); 7 }catch(Exception e){ 8 e.printStackTrace(); 9 } 10 return "上傳成功"; 11 }
非常簡單吧!
1 <form action="http://localhost/component/common/uploadImg" method="post" enctype="multipart/form-data"> 2 頭像:<input type="file" name="img" /><br/> 3 <input type="image" src="./images/img_submit.gif" /> 4 </form>
以上僅僅只是能夠上傳文件而已,而我們還要能返回一個圖片地址,這個圖片地址要能在瀏覽器中直接訪問,如下:

直接代碼吧!
controller層
1 @RequestMapping(value="/uploadImg", method=RequestMethod.POST) 2 @ResponseBody 3 public String uploadImg(@RequestParam(value="img")MultipartFile img, HttpServletResponse response){ 4 JSONObject result = new JSONObject(); 5 boolean flag = true; 6 try { 7 flag = pictureUploadService.upload(img, result); 8 } catch (Exception e) { 9 result.put("mess", "調用失敗"); 10 flag = false; 11 e.printStackTrace(); 12 } 13 result.put("flag", flag); 14 15 response.setContentType("text/html;charset=UTF-8"); 16 //解決跨域名訪問問題 17 response.setHeader("Access-Control-Allow-Origin", "*"); 18 19 return result.toString(); 20 }
service層
1 /** 2 * 上傳圖片 3 * @param file 4 * @param params 5 * @return 6 * @throws Exception 7 */ 8 public boolean upload(MultipartFile file, JSONObject params) throws Exception{ 9 //過濾合法的文件類型 10 String fileName = file.getOriginalFilename(); 11 String suffix = fileName.substring(fileName.lastIndexOf(".")+1); 12 String allowSuffixs = "gif,jpg,jpeg,bmp,png,ico"; 13 if(allowSuffixs.indexOf(suffix) == -1){ 14 params.put("resultStr", "not support the file type!"); 15 return false; 16 } 17 18 //獲取網絡地址、本地地址頭部 19 Properties config = new Properties(); 20 config.load(this.getClass().getClassLoader().getResourceAsStream("config.properties")); 21 String urlPath = config.getProperty("urlRoot"); 22 String localPath = config.getProperty("localRoot"); 23 24 //創建新目錄 25 String uri = File.separator + DateUtil.getNowDateStr(File.separator); 26 File dir = new File(localPath + uri); 27 if(!dir.exists()){ 28 dir.mkdirs(); 29 } 30 31 //創建新文件 32 String newFileName = StringUtil.getUniqueFileName(); 33 File f = new File(dir.getPath() + File.separator + newFileName + "." + suffix); 34 35 //將輸入流中的數據復制到新文件 36 FileUtils.copyInputStreamToFile(file.getInputStream(), f); 37 38 //創建Picture對象 39 Picture pic = new Picture(); 40 pic.setLocalPath(f.getAbsolutePath()); 41 pic.setName(f.getName()); 42 pic.setUrl(urlPath + uri.replace("\\", "/") + "/" + newFileName + "." + suffix); 43 pic.setAddTime(new Date()); 44 45 //插入到數據庫 46 //... 47 48 params.put("resultStr", pic.getUrl()); 49 50 return true; 51 }
(暫時沒有dao層,我在properties中配置網絡地址的域名以及本地文件存儲目錄)
上傳文件有幾個地方需要注意:
- 上傳文件的中文亂碼(這個暫不考慮,畢竟要實現的是圖片上傳)
- 限制上傳文件大小(文件過大,會導致服務器不堪重負),這個我們在spring mvc的配置文件中進行限制
1 <beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 2 <beans:property name="defaultEncoding" value="utf-8" /> 3 <beans:property name="maxUploadSize" value="10485760000" /> 4 <beans:property name="maxInMemorySize" value="40960" /> 5 </beans:bean>
- 限制上傳文件類型(這個我們在service層進行處理)
- 如果一個文件夾下面保存超過1000個文件,就會影響文件訪問性能,所以上傳的文件要分散存儲(這個分散策略有多種,不必拘泥於一種。我這里偷懶用了年月日作為目錄層級)
1 /** 2 * 獲取當前日期字符串 3 * @param separator 4 * @return 5 */ 6 public static String getNowDateStr(String separator){ 7 Calendar now = Calendar.getInstance(); 8 int year = now.get(Calendar.YEAR); 9 int month = now.get(Calendar.MONTH)+1; 10 int day = now.get(Calendar.DATE); 11 12 return year + separator + month + separator + day; 13 }
- 上傳成功后保存的文件不能重名(即文件名要唯一)
1 //生成唯一的文件名 2 public static String getUniqueFileName(){ 3 String str = UUID.randomUUID().toString(); 4 return str.replace("-", ""); 5 }
上傳圖片流程如下:

點擊上傳后,返回

在瀏覽器中輸入上面的這個圖片地址訪問,然后出現

