当前位置: 首页 > news >正文

SpringBoot使用hutool操作FTP

项目场景:

SpringBoot使用hutool操作FTP,可以实现从FTP服务器下载文件到本地,以及将本地文件上传到FTP服务器的功能。


实现步骤:

1、引入依赖

<dependency><groupId>commons-net</groupId><artifactId>commons-net</artifactId><version>3.9.0</version>
</dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.15</version>
</dependency>

2、yml配置 

ftp:# 服务器地址host: 127.0.0.1# 端口号port: 21# 用户名userName: test# 密码password: test

3、Config配置类

 我这里用的是static修饰的变量,方便工具类调用。

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;/*** ftp配置*/
@Configuration
public class FtpConfig {/*** 服务器地址*/private static String host;/*** 端口*/private static Integer port;/*** 用户名*/private static String userName;/*** 密码*/private static String password;@Value("${ftp.host}")public void setHost(String host) {FtpConfig.host = host;}public static String getHost() {return host;}@Value("${ftp.port}")public void setPort(Integer port) {FtpConfig.port = port;}public static Integer getPort() {return port;}@Value("${ftp.userName}")public void setUserName(String userName) {FtpConfig.userName = userName;}public static String getUserName() {return userName;}@Value("${ftp.password}")public void setPassword(String password) {FtpConfig.password = password;}public static String getPassword() {return password;}
}

4、 FtpUtil工具类

import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.ftp.Ftp;
import cn.hutool.extra.ftp.FtpMode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPFile;import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;/*** FTP服务工具类*/
@Slf4j
public class FtpUtil {/*** 获取 FTPClient对象*/private static Ftp getFTPClient() {try {if(StringUtils.isBlank(FtpConfig.getHost()) || FtpConfig.getPort() == null|| StringUtils.isBlank(FtpConfig.getUserName()) || StringUtils.isBlank(FtpConfig.getPassword())) {throw new RuntimeException("ftp配置信息不能为空");}Ftp ftp = new Ftp(FtpConfig.getHost(),FtpConfig.getPort(),FtpConfig.getUserName(),FtpConfig.getPassword());//设置为被动模式,防止防火墙拦截ftp.setMode(FtpMode.Passive);return ftp;} catch (Exception e) {e.printStackTrace();log.error("获取ftp客户端异常",e);throw new RuntimeException("获取ftp客户端异常:"+e.getMessage());}}/*** 下载ftp服务器上的文件到本地* @param remoteFile    ftp上的文件路径* @param localFile     输出的目录,使用服务端的文件名*/public static void download(String remoteFile, String localPath) {if(StringUtils.isBlank(remoteFile) || StringUtils.isBlank(localPath)) {return;}Ftp ftp = getFTPClient();try {if(!FileUtil.exist(localPath)){FileUtil.mkdir(localPath);}    File lFile = FileUtil.file(localPath);ftp.download(remoteFile, lFile);} catch (Exception e) {e.printStackTrace();log.error("FTP文件下载异常",e);} finally {//关闭连接try {if(ftp != null)  ftp.close();} catch (IOException e) {throw new RuntimeException(e);}}}/*** 本地文件上传到ftp服务器上* @param remoteDir 上传的ftp目录* @param remoteFileName  保存到ftp服务器上的名称* @param localFile 本地文件全名称*/public static boolean upload(String remoteDir, String remoteFileName, String localFile) {if(StringUtils.isBlank(remoteDir) || StringUtils.isBlank(remoteFileName) || StringUtils.isBlank(localFile)) {return false;}Ftp ftp = getFTPClient();try {File lFile = FileUtil.file(localFile);if(!lFile.exists()) {log.error("本地文件不存在");return false;}if(StringUtils.isBlank(remoteFileName)) {return ftp.upload(remoteDir, lFile);} else {return ftp.upload(remoteDir, remoteFileName, lFile);}} catch (Exception e) {e.printStackTrace();log.error("文件上传FTP异常",e);return false;} finally {//关闭连接try {if(ftp != null)  ftp.close();} catch (IOException e) {throw new RuntimeException(e);}}}/*** 删除FTP服务器中的文件* @param remoteFile    ftp上的文件路径*/public static boolean delFile(String remoteFile) {if(StringUtils.isBlank(remoteFile)) {return false;}Ftp ftp = getFTPClient();try {return ftp.delFile(remoteFile);} catch (Exception e) {e.printStackTrace();log.error("删除FTP服务器中的文件异常",e);return false;} finally {//关闭连接try {if(ftp != null)  ftp.close();} catch (IOException e) {throw new RuntimeException(e);}}}/*** 遍历某个目录下所有文件,不会递归遍历* @param path    目录*/public static List<String> listFile(String path) {List<String> listFile = new ArrayList<>();Ftp ftp = getFTPClient();try {FTPFile[] ftpFiles = ftp.lsFiles(path);for (int i = 0; i < ftpFiles.length; i++) {FTPFile ftpFile = ftpFiles[i];if(ftpFile.isFile()){listFile.add(ftpFile.getName());}}return listFile;} catch (Exception e) {e.printStackTrace();log.error("遍历某个目录下所有文件异常",e);return null;} finally {//关闭连接try {if(ftp != null)  ftp.close();} catch (IOException e) {throw new RuntimeException(e);}}}
}

5、测试 

@RestController
@RequestMapping("/test")
public class TestController {@RequestMapping(value = "ftpTest", method = RequestMethod.GET)public void ftpTest() {//上传文件到ftpFtpUtil.upload("opt/upload","APP_RELATION.sql", "F:/APP_RELATION.sql");//下载远程文件FtpUtil.download("opt/upload/APP_RELATION.sql", "D:/");//删除远程文件FtpUtil.delFile("opt/upload/APP_RELATION.sql");}}

总结:

上传的时候碰到一个问题,就是本地开启防火墙时,上传的文件大小是0kb,必须要关了防火墙才正常,后来FTP模式设置为“被动模式”解决。

//设置为被动模式,防止防火墙拦截
ftp.setMode(FtpMode.Passive);

主动模式(Active Mode):

  • 工作原理:客户端在本地打开一个非特权端口(通常大于1023),并通过这个端口发送PORT命令给服务器,告诉服务器客户端用于数据传输的端口号。然后,服务器使用其20端口(数据端口)主动连接到客户端指定的端口进行数据传输。
  • 安全性:由于服务器需要主动连接到客户端的端口,这可能引发一些安全问题,特别是当客户端位于防火墙或NAT设备后面时。
  • 适用场景:适用于客户端位于可以接受入站连接的网络环境,且没有防火墙或NAT设备限制的场景。

被动模式(Passive Mode): 

  • 工作原理:客户端发送PASV命令给服务器,服务器在本地打开一个端口(通常是高位的非特权端口),并通过PASV命令的响应告诉客户端这个端口号。然后,客户端主动连接到服务器指定的这个端口进行数据传输。
  • 安全性:由于客户端主动连接到服务器,这种模式更适合于客户端位于防火墙或NAT设备后面的场景,因为这些设备通常允许出站连接但限制入站连接。
  • 适用场景: 特别适用于网络环境不稳定、存在防火墙或NAT设备的场景。

相关文章:

SpringBoot使用hutool操作FTP

项目场景&#xff1a; SpringBoot使用hutool操作FTP&#xff0c;可以实现从FTP服务器下载文件到本地&#xff0c;以及将本地文件上传到FTP服务器的功能。 实现步骤&#xff1a; 1、引入依赖 <dependency><groupId>commons-net</groupId><artifactId>…...

如何防止SQL注入攻击

SQL注入攻击是一种常见的网络安全威胁&#xff0c;攻击者通过在用户输入中插入恶意的SQL代码&#xff0c;从而可以执行未经授权的数据库操作。为了防止SQL注入攻击&#xff0c;我们可以采取一系列有效的措施来保护数据库和应用程序的安全性。以下是一些关键的防范策略&#xff…...

Java List类

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;Java 目录 &#x1f449;&#x1f3fb;List1. 接口与实现2. 特性3. 常用方法4. 示例代码5. 遍历6. 线程安全 &#x1f449;&#x1f3fb;List Java的 List …...

使用 Internet 共享 (ICS) 方式分配ip

设备A使用dhcp的情况下&#xff0c;通过设备B分配ip并共享网络的方法。 启用网络共享&#xff08;ICS&#xff09;并配置 NAT Windows 自带的 Internet Connection Sharing (ICS) 功能可以简化 NAT 设置&#xff0c;允许共享一个网络连接给其他设备。 打开网络设置&#xff1…...

SMTP/IMAP服务发在线邮件时要用到

SMTP/IMAP服务 require PHPMailerAutoload.php; // 或 require class.phpmailer.php;// 创建实例 $mail new PHPMailer();// 设定邮件服务器 $mail->isSMTP(); $mail->Host smtp.example.com; // 邮件服务器地址 $mail->SMTPAuth true; $mail->Username your…...

Threejs绘制圆锥体

上一章节实现了胶囊体的绘制&#xff0c;这节来绘制圆锥体&#xff0c;圆锥体就是三角形旋转获得的&#xff0c;如上文一样&#xff0c;先要创建出基础的组件&#xff0c;包括场景&#xff0c;相机&#xff0c;灯光&#xff0c;渲染器。代码如下&#xff1a; initScene() {this…...

速通LLaMA3:《The Llama 3 Herd of Models》全文解读

文章目录 概览论文开篇IntroductionGeneral OverviewPre-TrainingPre-Training DataModel ArchitectureInfrastructure, Scaling, and EfficiencyTraining Recipe Post-TrainingResultsVision ExperimentsSpeech Experiments⭐Related WorkConclusionLlama 3 模型中的数学原理1…...

Python网络爬虫获取Wallhaven壁纸图片(源码)

** 话不多说&#xff0c;直接附源码&#xff0c;可运行&#xff01; ** import requests from lxml import etree from fake_useragent import UserAgent import timeclass wallhaven(object):def __init__(self):# yellow# self.url "https://wallhaven.cc/search?co…...

智能化引领等保测评新时代:AI与大数据的深度融合

随着信息技术的飞速发展&#xff0c;等级保护测评&#xff08;简称“等保测评”&#xff09;作为保障信息系统安全的重要手段&#xff0c;正迎来前所未有的变革。在这一背景下&#xff0c;人工智能&#xff08;AI&#xff09;与大数据技术的深度融合&#xff0c;正引领等保测评…...

深入解析:HTTP 和 HTTPS 的区别

网络安全问题正变得日益重要&#xff0c;而 HTTP 与 HTTPS 对用户数据的保护十分关键。本文将深入探讨这两种协议的特点、工作原理&#xff0c;以及保证数据安全的 HTTPS 为何变得至关重要。 认识 HTTP 与 HTTPS HTTP 的工作原理 HTTP&#xff0c;全称超文本传输协议&#xf…...

《动手学深度学习》笔记1.11——实战Kaggle比赛:预测房价+详细代码讲解

目录 0. 前言 原书正文 1. 下载和缓存数据集 1.1 download() 下载数据集 1.2 download_extract() 解压缩 2. Kaggle 简介 3. 访问和读取数据集 4. 数据预处理 5. 训练&#xff08;核心难点&#xff09; 5.1 get_net() 定义模型-线性回归 5.2 log_rmse() 对数均方根…...

数据结构:单链表实现信息管理

一、函数声明部分 #ifndef __LINK_H__ #define __LINK_H__ #include <myhead.h> typedef struct Link1 {union{int len;//用于头结点&#xff0c;统计节点个数int data;//用于正常节点&#xff0c;存储数据};struct Link1 *next;//指针域 }Link,*Plink;/**********函数声…...

【Linux】解锁文件描述符奥秘,高效缓存区的实战技巧

fd和缓冲区 1. 文件描述符fd1.1. 概念与本质1.2. 打开文件的管理1.3. 一切皆文件的理解1.4. 分配规则1.5. 重定向的本质1.5.1. dup2 2. FILE中的缓冲区2.1. 概念2.2. 存在的原因2.3. 类型(刷新方案)2.4. 存放的位置2.4.1. 代码证明、现象解释 2.5. 模拟C标准库中的方法 1. 文件…...

EmguCV学习笔记 VB.Net 11.9 姿势识别 OpenPose

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。 教程VB.net版本请访问…...

2024.9.26 Spark学习

资料&#xff1a; Spark基础入门-第一章-1.1-Spark简单介绍_哔哩哔哩_bilibili &#xff08;1&#xff09;基础知识 Apache Spark 是用于大规模数据&#xff08;large-scale data&#xff09;处理的统一分析引擎。 分布式处理数据 PySpark模块 Spark 和 Hadoop 有区别&…...

我与Linux的爱恋:进程地址空间

​ ​ &#x1f525;个人主页&#xff1a;guoguoqiang. &#x1f525;专栏&#xff1a;Linux的学习 文章目录 1.来段代码2.引入最基本的理解3.尝试理解 1.来段代码 #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h&g…...

C++的哲学思想

C的哲学思想 文章目录 C的哲学思想&#x1f4a1;前言&#x1f4a1;C的哲学思想☁️C底层不应该基于任何其他语言&#xff08;汇编语言除外&#xff09;☁️只为使用的东西付费&#xff08;不需要为没有使用到的语言特性付费&#xff09;☁️以低成本提供高级抽象&#xff08;更…...

IO(输入输出流)

1.IO a.介绍 i.IO是指Input和Output&#xff0c;即输入和输出&#xff0c;以内存为中心&#xff1a; 1.Input是指从外部读入数据到内存。 2.Output是指把数据从内存输出到外部。 ii.IO流是一种顺序读写数据的模式&#xff0c;它的特点是单向流动。数据类似自…...

python爬虫:从12306网站获取火车站信息

代码逻辑 初始化 (init 方法)&#xff1a; 设置请求头信息。设置车站版本号。 同步车站信息 (synchronization 方法)&#xff1a; 发送GET请求获取车站信息。返回服务器响应的文本。 提取信息 (extract 方法)&#xff1a; 从服务器响应中提取车站信息字符串。去掉字符串末尾的…...

Android个性名片界面的设计——约束布局的应用

节选自《Android应用开发项目式教程》&#xff0c;机械工业出版社&#xff0c;2024年7月出版 做最简单的安卓入门教程&#xff0c;手把手视频、代码、答疑全配齐 【任务目标】 使用约束布局、TextView控件实现一个个性名片界面的设计&#xff0c;界面如图1所示。 图1 个性名片…...

NaViL-9B开源模型实战:媒体内容审核平台图文敏感信息识别案例

NaViL-9B开源模型实战&#xff1a;媒体内容审核平台图文敏感信息识别案例 1. 模型与平台介绍 NaViL-9B是上海人工智能实验室研发的原生多模态大语言模型&#xff0c;能够同时处理文本和图像信息。这个开源模型特别适合构建智能内容审核系统&#xff0c;因为它具备以下核心能力…...

资源捕获高效解决方案:猫抓浏览器扩展让媒体提取更简单

资源捕获高效解决方案&#xff1a;猫抓浏览器扩展让媒体提取更简单 【免费下载链接】cat-catch 猫抓 chrome资源嗅探扩展 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 在当今数字时代&#xff0c;我们每天都在网页上浏览大量的媒体内容&#xff0c;从精…...

Image-to-Video镜像使用技巧:提示词怎么写?参数怎么调?

Image-to-Video镜像使用技巧&#xff1a;提示词怎么写&#xff1f;参数怎么调&#xff1f; 1. 快速上手Image-to-Video镜像 Image-to-Video图像转视频生成器是一款基于I2VGen-XL模型的实用工具&#xff0c;能够将静态图片转化为动态视频。这个由科哥二次开发的镜像已经预装了…...

手把手教你学Simulink——基于Simulink的同步整流Buck变换器效率提升仿真

目录 手把手教你学Simulink——基于Simulink的同步整流Buck变换器效率提升仿真​ 摘要​ 一、背景与挑战​ 1.1 传统二极管整流的效率瓶颈​ 1.1.1 二极管损耗机理​ 1.2 同步整流的优势与挑战​ 1.2.1 同步整流原理​ 1.2.2 核心挑战​ 1.3 设计目标​ 二、系统架构与…...

保姆级教程:用Cloudreve+Obsidian打造私人云笔记(附WebDAV配置避坑指南)

零基础构建私有知识库&#xff1a;Cloudreve与Obsidian的完美联姻 在信息爆炸的时代&#xff0c;如何高效管理个人知识资产已成为现代人的刚需。想象一下&#xff1a;你正在咖啡馆用iPad记录灵感&#xff0c;回到家打开电脑时这些想法已自动同步&#xff1b;出差途中用手机查阅…...

多模态扩展实验:OpenClaw+Qwen3-32B处理图片描述生成

多模态扩展实验&#xff1a;OpenClawQwen3-32B处理图片描述生成 1. 实验背景与动机 最近在探索如何将OpenClaw的自动化能力扩展到视觉领域。作为一个长期依赖文本交互的框架&#xff0c;OpenClaw能否结合多模态大模型处理图像任务&#xff1f;这引发了我的兴趣。恰好手头有台…...

5分钟掌握游戏高清截图秘诀:SRWE窗口分辨率自定义完整教程

5分钟掌握游戏高清截图秘诀&#xff1a;SRWE窗口分辨率自定义完整教程 【免费下载链接】SRWE Simple Runtime Window Editor 项目地址: https://gitcode.com/gh_mirrors/sr/SRWE 你是否曾梦想为心爱的游戏角色拍摄一张高清壁纸&#xff0c;却发现游戏分辨率选项有限&…...

从反射率到耐候性:5个关键参数教你像专业人士一样测试LED封装胶水

从反射率到耐候性&#xff1a;5个关键参数教你像专业人士一样测试LED封装胶水 在LED制造领域&#xff0c;封装胶水就像光学系统的"隐形工程师"&#xff0c;它不仅要牢固固定芯片和荧光粉&#xff0c;更承担着光线管理的关键任务。一款优质的高反射率封装胶水&#xf…...

Windows 11下保姆级安装Isaac Sim 4.5.0与Isaac Lab避坑全记录(含CUDA 12.8配置)

Windows 11下Isaac Sim 4.5.0与Isaac Lab全流程部署指南&#xff08;RTX 4090实测版&#xff09; 对于机器人仿真和AI开发领域的从业者来说&#xff0c;NVIDIA Isaac Sim和Isaac Lab无疑是当前最强大的工具组合之一。然而&#xff0c;当我在自己的RTX 4090显卡上首次尝试部署这…...

Lingbot-Depth-Pretrain-VitL-14处理复杂光照与反射场景效果展示

Lingbot-Depth-Pretrain-VitL-14处理复杂光照与反射场景效果展示 深度估计技术&#xff0c;简单来说就是让计算机像人眼一样&#xff0c;判断出画面中每个物体离我们有多远。这项技术在自动驾驶、机器人导航、增强现实等领域都扮演着关键角色。然而&#xff0c;当场景中出现一…...