Java向服務器上傳圖片


在比較絢麗多彩的網站或者業務邏輯比較豐富的程序設計過程中,圖片的相關操作時必不少的,尤其時圖片的上傳。還沒有徹底擺脫紙質辦公可能需要將紙質的文件備份上傳,網站的建設可能需要上傳用戶頭像、圖片描述等等,這些都需要將圖片從本地上傳到網上(服務器)。下面將介紹筆者今天在做圖片上傳過程中所遇到的坑~

一、業務描述

  業務要求是將機器在不斷生產的照片上傳到網上,以便於能在網站上查看。

二、解決思路

  由於對圖片這一塊的處理已經比較生疏,所以打算一點一點解決這些業務需求。首先將業務分解為以下幾個部分:

  (1)服務器接收瀏覽器端上傳的圖片。這一點比較好實現,因為服務器端的開發大多數都是基於B/S架構的,也就是邏輯與瀏覽器端進行開發的。

  (2)服務器接收客戶端上傳的圖片。這一點看似也不難,但是如何正確的發送出數據確是有點難度,也是筆者今天踩坑的地方。

  (3)業務邏輯的優化完善。

三、服務器接收瀏覽器端上傳的圖片

  1、新建網頁

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <meta charset="UTF-8">
 5 <title>圖片上傳</title>
 6 </head>
 7 <body>
 8     <form action="/plant/upload.action" enctype="multipart/form-data"
 9         method="post">
10         圖片:<input type="file" name="img"/> <br/>
11         <input type="submit" value="上傳"/>
12     </form>
13 </body>
14 </html>
查看代碼

  此處需要注意的是 form標簽enctype屬性的添加,還有就是input輸入框中name屬性的設置,這與后台的代碼相對應。    

  2、編寫Controller層的代碼

 1 @Controller
 2 public class UploadController {
 3 
 4     @RequestMapping(value="/upload",method=RequestMethod.POST)
 5     @ResponseBody
 6     public String uploadImg(@RequestParam("img") MultipartFile img, HttpServletRequest request,HttpServletResponse response) {
 7         String contentType = img.getContentType();    // 獲取文件的類型
 8         System.out.println("文件類型為:" +  contentType);
 9         String originalFilename = img.getOriginalFilename();     // 獲取文件的原始名稱
10         // 判斷文件是否為空
11         if(!img.isEmpty()) {
12             File targetImg = new File("F:/img");
13             // 判斷文件夾是否存在
14             if(!targetImg.exists()) {
15                 targetImg.mkdirs();    //級聯創建文件夾
16             }
17             try {
18                 // 開始保存圖片
19                 FileOutputStream outputStream = new FileOutputStream("F:/img/" + originalFilename);
20                 outputStream.write(img.getBytes());
21                 outputStream.flush();
22                 outputStream.close();
23             } catch (IOException e) {
24                 e.printStackTrace();
25             }
26         }
27         return "SUCCESS";
28     }
29 }
查看代碼

   3、Spring配置文件的修改和項目依賴的添加(小坑)

1 <!-- 文件上傳組件 -->
2 <dependency>
3     <groupId>commons-fileupload</groupId>
4     <artifactId>commons-fileupload</artifactId>
5     <version>1.3.1</version>
6 </dependency>
查看代碼
1 <!-- 支持文件上傳 -->
2 <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
3      <!-- 請求編碼格式 -->
4      <property name="defaultEncoding" value="utf-8"></property>
5      <!-- 上傳文件大小(單位:字節) -->
6      <property name="maxUploadSize" value="50000000"></property>
7      <!-- 緩沖區大小(單位:KB) -->
8      <property name="maxInMemorySize" value="1024"></property>
9 </bean>
查看代碼

  4、啟動項目,打開瀏覽器顯示相應的圖片上傳的網頁,選擇圖片,點擊上傳,如果不出以外的化本地路徑上應該會看到剛剛上傳的圖片。

四、服務器接收客戶端上傳的圖片

  網上有不少內容關於本部分都是介紹使用HttpURLConnection進行上傳,這中方法一是比較復雜,需要自己手動封裝請求,洋洋灑灑幾十行代碼;二是如果項目比較復雜,用到Session或者Cookie的話,那就真沒轍了~

  基於上述原因,本文選擇使用HttpClient進行本地圖片的上傳

  1、引入相關的依賴

 1 <dependency>
 2     <groupId>org.apache.httpcomponents</groupId>
 3     <artifactId>httpclient</artifactId>
 4     <version>4.5.3</version>
 5 </dependency>
 6 <dependency>
 7     <groupId>org.apache.httpcomponents</groupId>
 8     <artifactId>httpmime</artifactId>
 9     <version>4.5.3</version>
10 </dependency>
查看代碼

   2、編寫客戶端程序

 1 import java.io.BufferedReader;
 2 import java.io.File;
 3 import java.io.IOException;
 4 import java.io.InputStream;
 5 import java.io.InputStreamReader;
 6 import java.util.Arrays;
 7 
 8 import org.apache.commons.codec.binary.Base64;
 9 import org.apache.commons.lang3.StringUtils;
10 import org.apache.http.HttpEntity;
11 import org.apache.http.client.ClientProtocolException;
12 import org.apache.http.client.methods.CloseableHttpResponse;
13 import org.apache.http.client.methods.HttpPost;
14 import org.apache.http.entity.ContentType;
15 import org.apache.http.entity.mime.MultipartEntityBuilder;
16 import org.apache.http.entity.mime.content.ByteArrayBody;
17 import org.apache.http.entity.mime.content.FileBody;
18 import org.apache.http.entity.mime.content.StringBody;
19 import org.apache.http.impl.client.CloseableHttpClient;
20 import org.apache.http.impl.client.HttpClients;
21 import org.apache.http.util.EntityUtils;
22 
23 public class ClientUpload {
24 
25     public static void main(String[] args) throws ClientProtocolException, IOException, InterruptedException {
26         String url = "http://localhost:8090/plant/upload.action";
27 //        String basePath = "F:\\img\\";
28         String path = "G:\\123.jpg";
29         uploadImage(url, "dfsdfsdfsdf",path);
30     }
31 
32     public static String uploadImage(String path, String base64String, String imageFilePath) throws ClientProtocolException, IOException {
33         // 1. 創建上傳需要的元素類型
34         // 1.1 裝載本地上傳圖片的文件
35         File imageFile = new File(imageFilePath);
36         FileBody imageFileBody = new FileBody(imageFile);
37         // 1.2 裝載經過base64編碼的圖片的數據
38 //        String imageBase64Data = base64String;
39 //        ByteArrayBody byteArrayBody = null;
40 //        if (StringUtils.isNotEmpty(imageBase64Data)) {
41 //            byte[] byteImage = Base64.decodeBase64(imageBase64Data);
42 //            byteArrayBody = new ByteArrayBody(byteImage, "image_name");
43 //        }
44         // 1.3 裝載上傳字符串的對象
45         StringBody name = new StringBody("admin", ContentType.TEXT_PLAIN);
46         // 2. 將所有需要上傳元素打包成HttpEntity對象
47 //        HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("name", name).addPart("img", imageFileBody).addPart("file2", byteArrayBody).build();
48         HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("name", name).addPart("img", imageFileBody).build();
49         // 3. 創建HttpPost對象,用於包含信息發送post消息
50         HttpPost httpPost = new HttpPost(path);
51         httpPost.setEntity(reqEntity);
52         // 4. 創建HttpClient對象,傳入httpPost執行發送網絡請求的動作
53         CloseableHttpClient httpClient = HttpClients.createDefault();
54         CloseableHttpResponse response = httpClient.execute(httpPost);
55         // 5. 獲取返回的實體內容對象並解析內容
56         HttpEntity resultEntity = response.getEntity();
57         String responseMessage = "";
58         try {
59             if (resultEntity != null) {
60                 InputStream is = resultEntity.getContent();
61                 BufferedReader br = new BufferedReader(new InputStreamReader(is));
62                 StringBuffer sb = new StringBuffer();
63                 String line = "";
64                 while ((line = br.readLine()) != null) {
65                     sb.append(line);
66                 }
67                 responseMessage = sb.toString();
68                 System.out.println("響應內容為:" + responseMessage);
69             }
70             EntityUtils.consume(resultEntity);
71         } finally {
72             if (null != response) {
73                 response.close();
74             }
75         }
76         return responseMessage;
77     }
78 }
查看代碼

  3、到此為止,不出意外的話因該能夠在控制台看到令人激動的“SUCCESS”輸出

五、業務邏輯的優化完善

  1、由於圖片是在不斷生成的,所以要將圖片不斷地上傳,並且保證上傳地圖片不重復。

 1 public static void main(String[] args) throws ClientProtocolException, IOException, InterruptedException {
 2     String url = "http://localhost:8090/plant/upload.action";
 3     String basePath = "F:\\img\\";
 4 //    String path = "G:\\123.jpg";
 5 //    uploadImage(url, "dfsdfsdfsdf",path);
 6     while (true) {
 7         File file = new File(basePath);
 8         String[] list = file.list();
 9         Arrays.sort(list);
10         for (String str : list) {
11             // 圖片未標記為上傳
12             if (!str.startsWith("Upload")) {
13                 uploadImage(url, "chao", basePath + str); // 上傳圖片
14                 new File(basePath + str).renameTo(new File(basePath + "Upload_" + str));    // 重命名圖片
15             }
16         }
17         Thread.sleep(1000*60);    //等待60秒
18     }
19 }
查看代碼

  2、服務端的完善

  圖片如果想要能夠在開發的網站中瀏覽到,一般業務比較小的話是直接傳至Tomcat服務器,然后將路徑記錄並寫入數據庫;業務比較龐大的可以現在本地搭建圖片服務器,采用Nginx或其他技術都是可以做到的,然后也需要將該路徑寫入數據庫進行保存。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM