Docker下Java文件上传服务三部曲之一:准备环境

简介: 本文是《Docker下Java文件上传服务三部曲》系列的第一篇,包括上传文件的客户端开发、创建Tomcat容器(支持在线部署),安装wireshark(用于网络抓包分析)

欢迎访问我的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下载,地址和链接信息如下表所示:
名称 链接 备注
项目主页 https://github.com/zq2599/blog_demos 该项目在GitHub上的主页
git仓库地址(https) https://github.com/zq2599/blog_demos.git 该项目源码的仓库地址,https协议
git仓库地址(ssh) git@github.com:zq2599/blog_demos.git 该项目源码的仓库地址,ssh协议
  • 这个git项目中有多个目录,本次所需的资源放在uploadfileclient,如下图红框所示:

image.png

本章内容列举

  • 本章的工作是为后面章节的文件服务的运行和验证做准备的,包含以下步骤:
  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

在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 : zq2599@gmail.com
 * @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 upload
executing request POST http://192.168.119.155:8080/upload HTTP/1.1
response status : HTTP/1.1 200
response content length: 40
response 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

欢迎关注阿里云开发者社区博客:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...
相关文章
|
24天前
|
应用服务中间件 Linux nginx
在虚拟机Docker环境下部署Nginx的步骤。
以上就是在Docker环境下部署Nginx的步骤。需要注意,Docker和Nginix都有很多高级用法和细节需要掌握,以上只是一个基础入门级别的教程。如果你想要更深入地学习和使用它们,请参考官方文档或者其他专业书籍。
94 5
|
1月前
|
JSON Java 数据格式
java调用服务报错400
java调用服务报错400
69 6
java调用服务报错400
|
1月前
|
JSON Java 数据格式
java调用服务报错415 Content type ‘application/octet-stream‘ not supported
java调用服务报错415 Content type ‘application/octet-stream‘ not supported
131 6
|
3月前
|
缓存 Ubuntu Docker
Ubuntu环境下删除Docker镜像与容器、配置静态IP地址教程。
如果遇见问题或者想回滚改动, 可以重启系统.
258 16
|
3月前
|
存储 数据采集 搜索推荐
Java 大视界 -- Java 大数据在智慧文旅旅游景区游客情感分析与服务改进中的应用实践(226)
本篇文章探讨了 Java 大数据在智慧文旅景区中的创新应用,重点分析了如何通过数据采集、情感分析与可视化等技术,挖掘游客情感需求,进而优化景区服务。文章结合实际案例,展示了 Java 在数据处理与智能推荐等方面的强大能力,为文旅行业的智慧化升级提供了可行路径。
Java 大视界 -- Java 大数据在智慧文旅旅游景区游客情感分析与服务改进中的应用实践(226)
|
4月前
|
传感器 机器学习/深度学习 算法
Java 大视界 -- Java 大数据在智能农业温室环境调控与作物生长模型构建中的应用(189)
本文探讨了Java大数据在智能农业温室环境调控与作物生长模型构建中的关键应用。通过高效采集、传输与处理温室环境数据,结合机器学习算法,实现温度、湿度、光照等参数的智能调控,提升作物产量与品质。同时,融合多源数据构建精准作物生长模型,助力农业智能化、精细化发展,推动农业现代化进程。
|
Java Linux Docker
Java Spring Boot 2.0实战Docker容器与架构原理,视频与课件,基于Linux环境
Docker是最流行的开源容器引擎,Go语言开发,在互联网大规模集群、云计算、微服务等架构中广泛使用。本次课程一起学习Docker容器架构原理、如何基于Linux系统实战实战Docker容器,打包、发布、运行 Java Spring Boot 2.0应用。
11019 0
|
1月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
127 1