Docker 下 Java 檔案上傳服務三部曲之一:準備環境

語言: CN / TW / HK

歡迎訪問我的 GitHub

這裡分類和彙總了欣宸的全部原創(含配套原始碼): https://github.com/zq2599/blog_demos

本篇概覽

  • 《Docker 下 Java 檔案上傳服務三部曲》的主要內容是 Java 的檔案上傳服務實戰,由三篇文章組成,內容分別如下:

  1. 準備工作(即本章),包括上傳檔案的客戶端開發、建立 Tomcat 容器(支援線上部署),安裝 wireshark;

  2. 服務端編碼,建立三個應用,實戰 SpringMVC、Apache fileupload 庫,SpringBoot 三種場景下的檔案上傳服務;

  3. wireshark 抓包,分析檔案上傳服務過程中的傳輸詳情;

實戰環境

整個環境由兩臺電腦組成,作業系統分別是 win10 和 ubuntu16,如下圖:

如上圖,在 win10 電腦上執行一個 java 類,發起 POST 請求將檔案提交到 ubuntu 電腦上的 Docker 容器中,該容器執行著上傳檔案的 web 服務,在 win10 電腦上安裝有 wireshark,用來分析這個上傳檔案的 POST 請求;

注:客戶端和服務端部署在不同的機器上,這樣方便 wireshark 抓包,您也可以用 vmware 在 win10 上裝一個 ubuntu 虛擬機器,不過此時 wireshark 抓包前請注意選擇正確的網絡卡(vmware 虛擬出的那個);

  • 開發環境的具體資訊如下:

  1. 作業系統:win10,ubuntu16;

  2. JDK:1.8.0_151;

  3. maven:3.3.3;

  4. Docker 版本:17.03.2-ce;

  5. wireshark 版本:2.4.4;

原始碼下載

  • 上傳檔案的客戶端原始碼,您可以在 GitHub 下載,地址和連結資訊如下表所示:

  • 這個 git 專案中有多個目錄,本次所需的資源放在 uploadfileclient,如下圖紅框所示:

本章內容列舉

  • 本章的工作是為後面章節的檔案服務的執行和驗證做準備的,包含以下步驟:

  1. 在 win10 電腦上,安裝 wireshark;

  2. 在 win10 電腦上,建立 maven 工程 uploadfileclient,裡面有一個 java 類 UploadFileClient,後續所有上傳檔案的請求都是這個類的 main 方法完成的;

  3. 我們要驗證 UploadFileClient.java 能不能正常工作(上傳檔案全靠它了),所以在 ubuntu 電腦上建立一個檔案服務的 docker 容器,用於接收 UploadFileClient 類上傳的檔案;

  4. 在 win10 電腦上,執行 UploadFileClient.java 的 main 方法,看能否把檔案上傳到步驟 4 中搭建的檔案伺服器上;

  5. 下一章的檔案服務應用會做成 war 包執行在 Tomcat 上,所以我們要在 Docker 下建立一個 Tomcat 容器,並且該容器支援線上部署 war 包;

安裝 wireshark

  • 請在官網下載 wireshark 安裝檔案,地址:https://www.wireshark.org/#download

在 ubuntu 電腦上,建立一個檔案服務的 Docker 容器

  • 在裝好了 docker 的 ubuntu 電腦上執行以下命令,可以啟動一個檔案服務的容器:

docker run --name fileserver001 -p 8080:8080 -v /usr/local/work/fileupload/upload:/usr/Downloads -idt  bolingcavalry/springbootfileserver:0.0.1-SNAPSHOT

複製程式碼

  • 啟動後,容器的/usr/Downloads 目錄被對映到了 ubuntu 電腦的/usr/local/work/fileupload/upload 目錄(此目錄要確保存在),這樣上傳的檔案就能通過這個目錄匯出到 ubuntu 電腦上,便於我們驗證檔案是否完好無損;

注:有關該容器的映象的會在下一章詳細說明,本章我們就直接拿來用吧,作為上傳檔案的服務端;

上傳檔案的客戶端開發

  • 在 win10 電腦上建立一個 maven 工程,pom.xml 如下:

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>
<groupId>com.bolingcavalry</groupId> <artifactId>uploadfileclient</artifactId> <version>1.0-SNAPSHOT</version>
<!-- 指明編譯原始碼時使用的字元編碼,maven編譯的時候預設使用的GBK編碼, 通過project.build.sourceEncoding屬性設定字元編碼,告訴maven這個專案使用UTF-8來編譯 --> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties>
<dependencies> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.3.5</version> </dependency>
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.3.5</version> </dependency> </dependencies>
</project>

複製程式碼

  • 該工程只依賴了兩個庫:httpclient 和 httpmime;

  • 建立一個 java 類用來發起上傳檔案的請求,原始碼如下:

package com.bolingcavalry;
import org.apache.http.HttpEntity;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.config.RequestConfig;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpPost;import org.apache.http.entity.ContentType;import org.apache.http.entity.mime.MultipartEntityBuilder;import org.apache.http.entity.mime.content.FileBody;import org.apache.http.entity.mime.content.StringBody;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.util.EntityUtils;
import java.io.File;import java.io.IOException;
/** * @Description : 上傳檔案的類,將本地檔案POST到server * @Author : [email protected] * @Date : 2018-02-24 18:12 */public class UploadFileClient {
/** * 檔案服務的ULR */ private static final String POST_URL = "http://www.bolingcavalry.com:8088/springmvcfileserver/upload";
/** * 要上傳的本地檔案的完整路徑加檔名 */ private static final String UPLOAD_FILE_FULLPATH = "D:\\temp\\201802\\21\\abc.zip";
public static void main(String[] args) throws Exception{ System.out.println("start upload"); CloseableHttpClient httpclient = HttpClients.createDefault(); try { HttpPost httppost = new HttpPost(POST_URL);
//基本的配置資訊 RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(200000).setSocketTimeout(200000).build();
httppost.setConfig(requestConfig);
//要上傳的檔案 FileBody bin = new FileBody(new File(UPLOAD_FILE_FULLPATH));
//在POST中新增一個字串請求引數 StringBody comment = new StringBody("This is comment", ContentType.TEXT_PLAIN);
HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("file", bin).addPart("comment", comment).build();
httppost.setEntity(reqEntity);
System.out.println("executing request " + httppost.getRequestLine());
//發起POST CloseableHttpResponse response = httpclient.execute(httppost);
try {
HttpEntity resEntity = response.getEntity(); if (resEntity != null) { String responseEntityStr = EntityUtils.toString(response.getEntity()); System.out.println("response status : " + response.getStatusLine()); System.out.println("response content length: " + resEntity.getContentLength()); System.out.println("response entity str : " + responseEntityStr); } EntityUtils.consume(resEntity); } finally { response.close(); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } }
System.out.println("end upload"); }}

複製程式碼

  • 上面的程式碼,有以下三點需要注意:

  1. 利用 httpclient 的 API 可以發起 POST 請求,提交的二進位制檔案用 FileBody 物件處理,字串用 StringBody 物件處理;

  2. 我的 ubuntu 電腦 IP 地址是 192.168.119.155 ,所以 POST_URL 的值是:http://192.168.119.155:8080/upload,請將此改為您的 ubuntu 電腦的 IP 地址;

  3. UPLOAD_FILE_FULLPATH 的值是要上傳的檔案在 win10 電腦上的路徑;

驗證 UploadFileClient 類上傳檔案的功能

  • 在 pom.xml 所在目錄執行以下命令,即可編譯並執行 UploadFileClient 類的 main 方法:

mvn clean compile -U exec:java -Dexec.mainClass="com.bolingcavalry.UploadFileClient"

複製程式碼

  • 上述命令執行時,會輸出類似以下的資訊:

[INFO][INFO] --- exec-maven-plugin:1.6.0:java (default-cli) @ uploadfileclient ---start uploadexecuting request POST http://192.168.119.155:8080/upload HTTP/1.1response status : HTTP/1.1 200response content length: 40response entity str : SpringBoot環境下,上傳檔案成功end upload[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time: 10.226 s[INFO] Finished at: 2018-02-25T00:00:13+08:00[INFO] Final Memory: 20M/181M[INFO] ------------------------------------------------------------------------

複製程式碼

“SpringBoot 環境下,上傳檔案成功"這一句是服務端接收檔案成功後返回的資訊;

在服務端驗證上傳成功

  • 在 ubuntu 電腦執行 docker logs fileserver001 ,能看到容器的日誌,如下:

2018-02-24 16:00:13.077  INFO 1 --- [nio-8080-exec-5] c.b.s.controller.UploadController        : start upload, comment [This is comment]2018-02-24 16:00:13.079  INFO 1 --- [nio-8080-exec-5] c.b.s.controller.UploadController        : base save path [/tmp/tomcat-docbase.8533878395220260315.8080/WEB-INF/upload], original file name [abc.zip]2018-02-24 16:00:13.080  INFO 1 --- [nio-8080-exec-5] c.b.s.controller.UploadController        : real save path [/tmp/tomcat-docbase.8533878395220260315.8080/WEB-INF/upload/15/1], real file name [fba8a275-cfc0-4471-b4f7-21d2913450cb_abc.zip]2018-02-24 16:00:13.080  INFO 1 --- [nio-8080-exec-5] c.b.s.controller.UploadController        : save file success [/tmp/tomcat-docbase.8533878395220260315.8080/WEB-INF/upload/15/1/fba8a275-cfc0-4471-b4f7-21d2913450cb_abc.zip]

複製程式碼

  • 如上所示,上傳的檔案存放在資料夾: /tmp/tomcat-docbase.8533878395220260315.8080/WEB-INF/upload/15/1/

  • 執行命令 docker exec -it fileserver001 /bin/bash 進入容器,再將上述資料夾內的檔案複製到/usr/Downloads 目錄下,此檔案就從 docker 容器被匯出到 ubuntu 的/usr/local/work/fileupload/upload 目錄下了,方便您驗證該檔案與上傳的是否一致;

建立支援線上部署的 Tomcat 容器

  • 在 ubuntu 電腦上,執行以下命令即可建立 Tomcat 容器,並且該容器支援線上部署 war 包:

docker run --name tomcat006 -p 8088:8080 -v /usr/local/work/fileupload/upload:/usr/Downloads -idt  bolingcavalry/online_deploy_tomcat:0.0.1

複製程式碼

  • 這樣檔案服務的 maven 工程就可以直接線上部署到這個 tomcat 上去了,關於 Tomcat 線上部署的詳情,請參照《實戰 docker,編寫 Dockerfile 定製 tomcat 映象,實現 web 應用線上部署》;

  • 至此,前期的準備工作已經完成,接下來的章節我們一起來開發和部署檔案服務的 web 應用吧;

歡迎關注 InfoQ:程式設計師欣宸

學習路上,你不孤單,欣宸原創一路相伴...