Java向伺服器上傳圖片

来源:https://www.cnblogs.com/yiychao/archive/2019/11/04/11790047.html
-Advertisement-
Play Games

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


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

一、業務描述

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

二、解決思路

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

  (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或其他技術都是可以做到的,然後也需要將該路徑寫入資料庫進行保存。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • [TOC] 不知道這個小知識點用得多不多,曾經在書上看到過,所以有一些印象,前段時間順手寫出類似如下的代碼 斷點調試之後發現無論如何都不相等,方法parseInt()返回的結果確實是NaN,但是與右側的NaN比較返回的結果卻是false,這時候才突然想起來NaN有不等於自身的特性,所以簡單收集一下資 ...
  • 過濾器的基本使用 定義一個過濾器 過濾器可以使用多個· 下麵js代碼的HTML部分 定義一個私有過濾器和私有指令 javascript // 如何自定義一個私有的過濾器(局部) var vm2 = new Vue({ el: ' app2', data: { dt: new Date() }, me ...
  • 前言 在上一篇中,我們對平時進行vue開發中遇到的常用指令進行歸類說明講解,大概已經學會了怎麼去實現數據綁定,以及實現動態的實現數據展示功能,運用指令,可以更好更快的進行開發。而在這一篇中,我們將通過實例,探究vue的生命周期。 萬物皆有靈,世間萬物都擁有靈魂,小到山河湖海,花草樹木,螞蟻到人類,以 ...
  • 前言 2019年6月中旬,實在厭倦了之前平平淡淡的工作和毫不起眼的薪資,不顧親人的反對,毅然決然地決定隻身前往沿海城市,想著找到一份更加具有挑戰性的工作,來徹徹底底地重新打磨自己,同時去追求更好的薪資待遇。當然在此之前,自己每天下班後都會利用業餘時間抓緊複習鞏固刷題等等,大概從3月份開始的吧,持續了 ...
  • 2019/11/2 1、 表現層狀態轉換(REST, representational state transfer.)一種萬維網軟體架構風格,目的是便於不同軟體/程式在網路(例如互聯網)中互相傳遞信息。表現層狀態轉換是根基於超文本傳輸協議(HTTP)之上而確定的一組約束和屬性,是一種設計提供萬維網 ...
  • 前段時間公司根據要求需要將聚石塔上伺服器從杭州整體遷移到張家口,剛好趁這次機會將這些亂七八糟的伺服器做一次梳理和整合,斷斷續續一個月遷移完 成大概優化掉了1/3的機器,完成之後遇到了一些問題,比如曾今零零散散部署在生產上一些可視化UI:apollo,kibana,grafana,jenkins 等等 ...
  • Java 控制台輸入流 System.in和Scanner System.out 是常用的在控制台輸出數據的 System.in 可以從控制台輸入數據 步驟 1 : System.in package stream; import java.io.IOException; import java.i ...
  • 如果你是一名 Java 開發人員,你肯定指定 Java 代碼有很多種不同的運行方式。比如說可以在開發工具(IDEA、Eclipse等)中運行,可以雙擊執行 jar 文件運行,也可以在命令行中運行,甚至可以在網頁(比如各種 OJ)中運行。當然,這些執行方式都離不開 JRE(Java 運行時環境)。 J ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...