springboot项目通过nginx访问ftp服务器文件

news2024/10/7 13:22:15

前文

本来准备记录一下。项目中遇到的springboot项目访问ftp服务器图片、视频问题的,想在我自己服务器上重新部署一遍,然后发现,执行docker的时候报错了。具体报错原因如下:
原因是我重启了一下服务器

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

这个问题,解决方案自然很多了。百度一下解析的更全面,我这里只是因为docker没启动。
解决方案: 1、执行 systemctl status docker 查看docker状态。2、执行 service docker start 启动docker。3、然后docker ps即可。
在这里插入图片描述

项目场景

当前需求是,图片或者视频,保存到一个地方,然后通过本地项目在web上可以展示。基本这种场景都是把图片视频部署到文件服务器上,比如阿里云等。因需求没那么严格。从简,所以就决定把文件保存到ftp服务器上。

环境介绍:
1、springboot项目。前后分离。
2、ftp部署在linux系统。
3、docker管理ftp。

环境安装

docker安装,可自行百度

docker安装ftp

1) docker拉取ftp镜像

docker pull fauria/vsftpd

2) 启动ftp镜像

docker run -p 20:20 -p 21:21 -p 2000:2000 --name vsftpd --restart=always -v /home/app/ftp/:/home/vsftpd -v /home/app/ftp/log/:/var/log/vsftpd -e FTP_USER=ftpuser -e FTP_PASS=ftpuser -e PASV_MIN_PORT=20000 -e PASV_MAX_PORT=20000 -e PASV_ADDRESS=你的ip -e LOG_STDOUT=1 -d fauria/vsftpd

启动之后发现21端口被占用。因为是之前在宝塔里面创建了一个ftp。
在这里插入图片描述
解决:使用 netstat -ant|grep 21、或者 lsof -i :21查看21端口使用情况,kill -9 843 关闭进程。重新启动运行ftp。

验证:
打开我的电脑在文件栏输入:ftp://你的ip/,输入密码就可以登录linux服务器的ftp
在这里插入图片描述

上传下载图片

ftp maven引入pom

<!-- https://mvnrepository.com/artifact/commons-net/commons-net -->
        <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.8.0</version>
        </dependency>

FtpUtil




import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import java.io.*;

/**
 * ftp工具类
 */
@Slf4j
public class FtpUtil {



    /**
     * Description: 向FTP服务器上传文件
     *
     * @param host     FTP服务器hostname
     * @param port     FTP服务器端口
     * @param username FTP登录账号
     * @param password FTP登录密码
     * @param basePath FTP服务器基础目录
     * @param filePath FTP服务器文件存放路径。文件的路径为basePath+filePath
     * @param filename 上传到FTP服务器上的文件名
     * @param input    输入流
     * @return 成功返回true,否则返回false
     */
    public static boolean uploadFile(String host, int port, String username, String password, String basePath,
                                     String filePath, String filename, InputStream input) {
        FTPClient ftp = new FTPClient();
        try {
            int reply;
            ftp.connect(host, port);// 连接FTP服务器
            // 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
            ftp.login(username, password);// 登录
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                log.error("ftp connect failed");
                return false;
            }
            //切换到上传目录
            if (!ftp.changeWorkingDirectory(basePath + filePath)) {
                //如果目录不存在创建目录
                String[] dirs = filePath.split("/");
                String tempPath = basePath;
                for (String dir : dirs) {
                    if (null == dir || "".equals(dir)) continue;
                    tempPath += "/" + dir;
                    if (!ftp.changeWorkingDirectory(tempPath)) {  //进不去目录,说明该目录不存在
                        if (!ftp.makeDirectory(tempPath)) { //创建目录
                            //如果创建文件目录失败,则返回
                            log.error("创建文件目录" + tempPath + "失败");
                            log.error("dir creat failed");
                            return false;
                        } else {
                            //目录存在,则直接进入该目录
                            ftp.changeWorkingDirectory(tempPath);
                        }
                    }
                }
            }
            //设置上传文件的类型为二进制类型
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            // 设置被动模式
//            ftp.enterLocalPassiveMode();
            // 设置主动模式
            ftp.enterLocalActiveMode();
            ftp.setRemoteVerificationEnabled(false);

            //上传文件
            if (!ftp.storeFile(filename, input)) {
                log.error("upload failed");
                return false;
            } else {
                log.info("文件:" + filename + " 上传成功");
            }
            input.close();
            ftp.logout();
        } catch (IOException e) {
            log.error("失败,服务器返回:" + ftp.getReplyString());//获取上传失败的原因
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                    log.error("ftp.isConnected() fail!");
                    ioe.printStackTrace();
                }
            }
        }
        return true;
    }


    /**
     * Description: 从FTP服务器下载文件
     *
     * @param host       FTP服务器hostname
     * @param port       FTP服务器端口
     * @param username   FTP登录账号
     * @param password   FTP登录密码
     * @param remotePath FTP服务器上的相对路径
     * @param fileName   要下载的文件名
     * @param localPath  下载后保存到本地的路径
     * @return
     */
    public static boolean downloadFile(String host, int port, String username, String password, String remotePath,
                                       String fileName, String localPath) {
        boolean result = false;
        FTPClient ftp = new FTPClient();
        try {
            int reply;
            ftp.connect(host, port);
            // 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
            ftp.login(username, password);// 登录
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return result;
            }
            ftp.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
            FTPFile[] fs = ftp.listFiles();
            for (FTPFile ff : fs) {
                if (ff.getName().equals(fileName)) {
                    File localFile = new File(localPath + "/" + ff.getName());

                    OutputStream is = new FileOutputStream(localFile);
                    ftp.retrieveFile(ff.getName(), is);
                    is.close();
                }
            }
            ftp.logout();
            result = true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return result;
    }

    /**
     * 连接ftp服务器
     * @param hostName ip
     * @param port 端口
     * @param userName 用户名
     * @param password 密码
     * @return
     * @throws IOException
     */
    public static FTPClient connectFtp(String hostName, int port, String userName, String password) throws IOException {
        FTPClient ftpClient = new FTPClient();
        //设置编码格式,FTP Server 协议里规定文件名编码是iso-8859-1
        ftpClient.setControlEncoding("GBK");
        //设置传输命令的超时
        ftpClient.setDefaultTimeout(20000);//毫秒
        //设置两个服务连接超时时间
        ftpClient.setConnectTimeout(10000);//毫秒
        //被动模式下设置数据传输的超时时间
        ftpClient.setDataTimeout(15000);//毫秒
        //连接FTP
        ftpClient.connect(hostName, port);
        //更加账户密码登录服务
        ftpClient.login(userName, password);
        //被动模式
        ftpClient.enterLocalPassiveMode();

        return ftpClient;
    }

    /**
     * 关闭ftp
     */
    public static void close(FTPClient ftpClient) {
        try {
            if (ftpClient != null && ftpClient.isConnected()) {
                ftpClient.disconnect();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

nginx访问ftp服务文件

springboot项目部署到linux服务器上运行之后。前端需要通过nginx转发到ftp服务,直接访问图片视频文件。

docker安装nginx。

之前装过了,所以改一下nginx配置重启一下就行了。修改配置如下。

user  root;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    #include /etc/nginx/conf.d/*.conf;
    server {
	listen 80;
	server_name xxx.xx.x.xx;
	location / {
		root   /usr/share/nginx/html/dist;
		index  index.html index.htm;
		try_files $uri $uri/ /index.html;
	}
	location /prod-api/ {
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header REMOTE-HOST $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://xxx.xx.x.xx:8080/;
        }
    }
   server {
   	listen 81;
	server_name xxx.xx.x.xx;
	location / {
                root /usr/share/nginx/ftproot/testftpuser;
        } 
    }

}

docker 启动nginx指令:

docker run -p 80:80 -p 81:81 --name nginx -v /home/app-data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /app-data/ftp_home:/usr/share/nginx/ftproot -v /home/app-data/nginx/conf/conf.d:/etc/nginx/conf.d -v /home/app-data/nginx/log:/var/log/nginx -v /home/app-data/nginx/html:/usr/share/nginx/html -d nginx:latest

注意: -v /app-data/ftp_home:/usr/share/nginx/ftproot 这个就是挂载ftp服务地方。

然后启动nginx之后,直接访问:你的ip + ftp文件路径,就可以访问了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/705864.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ChatGPT实战:生成演讲稿

当众发言&#xff08;演讲&#xff09;是一种传达信息、观点和情感的重要方式。通过演讲&#xff0c;人们可以在公共场合表达自己的观点&#xff0c;向观众传递自己的知识和经验&#xff0c;激发听众的思考和行动。无论是商务演讲、学术讲座还是政治演说&#xff0c;演讲稿的写…

linux查找文件内容命令之grep -r ‘关键字‘

目录 grep命令介绍参数选项 grep命令的使用1. 在指定的文件中查找包含的关键字2. 在指定目录下多个文件内容中查找包含的关键字3.在追加的文件内容中查找关键字4. 统计文件中关键字出现的次数5. vi或vim打开的文件查找关键字(补充) 总结 grep命令介绍 Linux操作系统中 grep 命…

EventBus源码分析

差不多两年没写博客了&#xff0c;最近想着要找工作了&#xff0c;打算复习下一些常用的开源库&#xff0c;也是这篇博客的由来&#xff5e; EventBus使用非常简单 参考&#xff1a;github 再贴一张官网的图 一、示例代码 示例代码是为了便于理解后面注解处理器生成代码的处…

1. MyBatis 整体架构

作为正式内容的第一篇&#xff0c;本次不会介绍具体的技术&#xff0c;而是先从全局视角上对 MyBatis 做一个俯瞰&#xff0c;了解 MyBatis 项目工程的组织结构&#xff0c;以及内部的核心功能模块。 工程结构 打开 MyBatis 的 Github 地址&#xff0c;就可以看到其代码工程结…

C语言:打印用 * 组成的带空格直角三角形图案

题目&#xff1a; 多组输入一个整数&#xff08;2~20&#xff09;&#xff0c;表示直角三角形直角边的长度&#xff0c;即 * 的数量&#xff0c;也表示输出行数。 思路&#xff1a; 总体思路&#xff1a; 找到规律&#xff1a; 行数 列数 < 三角形长度 - 1 打印 两个空格…

一步一步学OAK之十四: 获取OAK设备信息

这一节我们通过调用DepthAI API 来获取OAK设备信息 目录 DeviceBootloader简介获取OAK设备信息的方法Setup 1: 创建文件Setup 2: 安装依赖Setup 3: 导入需要的包Setup 4: 获取可用设备Setup 5: 判断infos的长度Setup 6: 遍历infosSetup 7: 打印提示消息Setup 8: 连接设备Setup…

html_4——知识总结

html_4——知识总结 一、计算机基础知识二、html4总结2.1 html基本结构2.2 全局属性-id,class,style,dir,title,lang2.3 格式排版标签-div,p,h1-h6,br,hr,pre2.4 文本标签-span,en,strong,del,ins,sub,sup2.5 图片标签-img:src,alt,width,height,boder2.6 超链接-a:herf,target…

内部函数和外部函数

文章目录 怎么来的&#xff1f;内部函数外部函数明确一下内外的概念&#xff1a;外部函数的实例fgets()函数 怎么来的&#xff1f; 函数本质上是全局的&#xff0c;因为定义一个函数的目的就是这个函数与其他函数之间相互调用&#xff0c;如果不声明的话&#xff0c;一个函数既…

YouTube正测试屏蔽“广告拦截器”,以确保其广告收入

YouTube目前正在进行一项全球范围内的小规模测试&#xff0c;警告用户关掉他们的广告屏蔽器&#xff0c;否则将被限制观看视频的次数。 周三&#xff08;6月28日&#xff09;&#xff0c;Reddit的一位用户发现&#xff0c;在使用YouTube时弹出了一个窗口&#xff0c;提示该用户…

Cali3F: Calibrated Fast Fair Federated Recommendation System

Decentralized Collaborative Learning Framework for Next POI Recommendation 标定的&#xff08;校准的&#xff09;快速公平联邦推荐系统 1. What does literature study? 提出一个经过校准的快速而公平的联邦推荐框架Cali3F&#xff0c;通过集群内参数共享解决了收敛问…

创新引领未来:RFID技术在汽车装配中的智能革命

射频识别&#xff08;RFID&#xff09;技术作为一种自动识别技术&#xff0c;已经在许多领域得到广泛应用。在汽车装配领域&#xff0c;RFID技术的应用可以提高装配过程的效率、降低人工错误率&#xff0c;并帮助实现自动化和智能化生产。本文将介绍RFID技术在汽车装配中的应用…

动态二维码生成器PHP Dynamic QRcode

什么是 PHP Dynamic QRcode &#xff1f; PHP Dynamic QRcode 是一个允许生成和保存动态和静态二维码&#xff08;QR码&#xff09;的应用。它具有简洁、响应灵敏且用户友好的设计。其中包含您网站中可能需要的一般功能&#xff0c;如&#xff1a;记录管理&#xff08;CRUD&…

【2023,学点儿新Java-27】是的——C语言中的const关键字 | 附:按照类型 快速了解与划分:C语言中的关键字 | goto关键字解释

前情回顾&#xff1a; 【2023&#xff0c;学点儿新Java-26】关键字介绍示例代码&#xff1a;assert 断言&#xff08;如何启用断言&#xff09;&#xff0c;以 验证一个数组的长度是否不为零 为例说明【2023&#xff0c;学点儿新Java-25】如何解决浮点计算存在误差&#xff1a…

Selenium Grid入门详解

目录 前言&#xff1a; 一、简介 二、使用场景 三、使用前提 四、使用方式 五、实现在另一台电脑运行脚本 前言&#xff1a; Selenium Grid是一个用于分布式测试的工具&#xff0c;它允许同时在多个机器上执行Selenium测试。通过使用Selenium Grid&#xff0c;你可以在不…

Linux系统Centos7 安装MySQL8.0详细步骤

MySql安装 1.下载wget命令 yum -y install wget 2. 在线下载mysql安装包 wget https://repo.mysql.com//mysql80-community-release-el7-3.noarch.rpm 3.MySQL的GPG升级了&#xff0c;需要更新&#xff0c;如果是新安装的MySQL&#xff0c;执行以下脚本即可&#xff1…

Vite + Vue3 + Electron实现进程通信

Vite Vue3 Electron实现进程通信 实现 渲染进程 / 主进程 通信&#xff08;IPC&#xff09; Electron 是一个基于 Chromium 和 Node.js 的桌面应用程序开发框架&#xff0c;而 Vue3 则是一种流行的前端框架。将两者结合使用可以快速地打造出跨平台的桌面应用程序。在这种组…

Sui x KuCoin Labs夏季黑客松第三批入围项目公布

自Sui x KuCoin Labs夏季黑客松开放注册以来&#xff0c;已收获了众多开发者的报名参与。赛程过半&#xff0c;截至目前为止&#xff0c;第一批和第二批入围项目已在前两周公布&#xff0c;第三批入围名单项目新鲜出炉&#xff0c;进入最终的Demo Day。 第三批入围名单 SuiVi…

在 Linux 中查找 IP 地址的 3 种简单方法

在 Linux 系统中&#xff0c;经常需要查找 IP 地址以进行网络配置、故障排除或安全管理。无论是查找本地主机的 IP 地址还是查找其他设备的 IP 地址&#xff0c;本文将介绍三种简单的方法&#xff0c;帮助你在 Linux 中轻松找到所需的 IP 地址。 总结 通过上述三种简单的方法&…

自动化测试进阶之路(WEB自动化二)

一、设计模式 Pom模块关键字驱动模式 pom模块&#xff1a;page object model 页面对象模式好处&#xff1a; 解决线性脚本的问题解决代码不能重复利用的问题后期的维护问题 分三层&#xff08;页面对象层调用基础层的方法&#xff0c;测试用例层调用页面对象层的方法&#xff0…

Spring Boot 有哪些方式可以实现热部署

一、什么是热部署&#xff1f; 释义 所谓热部署&#xff0c;就是在应用正在运行的时候升级软件&#xff0c;却不需要重新启动应用。 对于Java应用程序来说&#xff0c;热部署就是在运行时更新Java类文件。在基于Java的应用服务器实现热部署的过程中&#xff0c;类装入器扮演着…