Java操作FTP实现上传下载功能

目录
  • FTP简介
  • FTP架构
  • FTP数据连接模式
  • 用户认证
  • 客户端
  • Vsftp安装与配置
  • 启动服务
  • 配置文件说明
  • 传输模式配置
  • 系统用户配置
  • java操作ftp文件服务器
    • 1.引入依赖
    • 2.提供接口
    • 3.对提供操作ftp接口进行实现
    • 4.配置ftp相关参数
    • 5.写测试controller

FTP简介

文件传输协议(File Transfer Protocol,FTP)是用于在网络上进行文件传输的一套标准协议,它工作在 OSI 模型的第七层,TCP 模型的第四层, 即应用层, 使用 TCP 传输而不是 UDP, 客户在和服务器建立连接前要经过一个“三次握手”的过程, 保证客户与服务器之间的连接是可靠的, 而且是面向连接, 为数据传输提供可靠保证。

FTP也是一个应用程序,基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件。可以使用FTP进行下载和上传。

文件传送协议FTP(File Transfer Protocol)是Internet上使用比较广泛的文件传送协议。FTP提供交互式的访问,允许客户指明文件的类型与格式,并允许文件具有存取权限。FTP屏蔽了各种计算机系统的细节,因此适用于在异构网络中任意计算机之间传送文件。它的基本应用就是将文件从一台计算机复制到另一台计算机中。它要存取一个文件,就必须先获得一个本地文件的副本,如果修改文件,也只能对文件的副本进行修改,然后再将修改后的文件副本传回到原节点。

您只要记住几个关键词:交互式、存取权限和副本。

简单文件传送协议TFTP(Trivial File Transfer Protocol)是一个小而易于实现的文件传送协议。TFTP是基于UDP数据报,需要有自己的差错改正措施。TFTP只支持文件传输,不支持交互,没有庞大的命令集。也没有目录列表功能,以及不能对用户进行身份鉴别。但它的代码所占内存较小,不需要硬盘就可以固化TFTP代码,很适合较小的计算机和特殊用途的设备。

您会发现TFTP和FTP一个主要的区别就是它没有交互式,且不进行身份验证。

FTP的客户可以是任意平台

FTP标准端口:

  • 20 数据接口
  • 21 指令接口

FTP架构

FTP监听于TCP的21号端口,是一种C/S架构的应用程序。在Linux中常用的服务端软件和客户端软件一般如下表所示:

FTP数据连接模式

FTP有2种数据连接模式:命令连接和数据连接

  • 命令连接:是指文件管理类命令,始终在线的持久性连接,直到用户退出登录为止(可以简单的理解为建立连接)
  • 数据连接:是指数据传输,按需创建及关闭的连接(可以简单的理解为传输数据)

数据连接需要关注的点有:

1.数据传输格式

  • 文件传输
  • 二进制传输

2.数据传输模式

  • 主动模式:由服务器端创建数据连接
  • 被动模式:由客户端创建数据连接

两种数据传输模式的建立过程:

1.主动模式

命令连接(建立连接通道)

Client端以一个1024以上的随机端口(端口号大于1023小于65535)来连接Server端的21号端口

数据连接(传输数据)

Server端以20号端口去连接Client创建命令连接时使用的随机端口+1的端口

示例:

命令连接:Client(9527)–> Server(21),数据连接:Server(20/tcp) --> Client(9527+1)

2.被动模式

命令连接

Client以一个1024以上的随机端口号(端口号大于1023小于65535)来连接Server端的21号端口,命令连接建立完毕后,Server端会告知Client端用于创建数据连接的随机端口号(端口号大于1023小于65535)

数据连接

Client以创建命令连接时使用的随机端口号+1去连服务器端通过命令连接告知自己的一个随机端口号来创建数据连接

示例:

命令连接:Client(9527) --> Server(21),数据连接:Client(9527+1) --> Server(随机端口)

注意:

主动模式存在弊端,因为客户端的端口是随机的,客户端如果开了防火墙,则服务器端去连客户端创建数据连接时可能会被拒绝

用户认证

Ftp的用户认证主要有三种:

1.虚拟用户:仅用于访问某特定服务中的资源

虚拟用户通过ftp访问的资源位置为给虚拟用户指定的映射成为的系统用户的家目录

2.系统用户:可以登录系统的真实用户(出于对安全性的考虑,这种认证很少使用)

系统用户通过ftp访问的资源位置为用户的家目录

3.匿名用户

匿名用户(映射为ftp用户)的共享资源位置是/var/ftp

服务端

  • /etc/pam.d/vsftpd #vsftpd用户认证配置文件
  • /etc/vsftpd/ #配置文件目录
  • /etc/vsftpd/vsftpd.conf #主配置文件
  • vsftpd常见的配置参数

客户端

lftp工具 支持指定用户名和密码登录

Vsftp安装与配置

在linux环境下,使用最多的FTP服务端软件就是Vsftpd!

安装Vsftpd,运行一下命令需要在root用户下进行!

yum install vsftpd 安装
yum remove vsftpd 卸载

启动服务

启动服务 service vsftpd start 或者 systemctl start vsftpd.service

重启服务 systemctl restart vsftpd.service

停止服务 systemctl stop vsftpd.service

设置开机自启动  systemctl enable vsftpd.service

配置文件说明

/etc/vsftpd/vsftpd.conf 这个文件是vsftpd服务的核心配置文件!

我们在修改配置文件的时候,最好先备份一份!

cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.bak

/etc/vsftpd/ftpusers这个文件是禁止使用vsftpd的用户列表文件。记录不允许访问FTP服务器的用户名单,管理员可以把一些对系统安全有威胁的用户账号记录在此文件中,以免用户从FTP登录后获得大于上传下载操作的权利,而对系统造成损坏。

/etc/vsftpd/user_list这个文件禁止或允许使用vsftpd的用户列表文件。这个文件中指定的用户缺省情况(即在/etc/vsftpd/vsftpd.conf中设置userlist_deny=YES)下也不能访问FTP服务器,在设置了userlist_deny=NO时,仅允许user_list中指定的用户访问FTP服务器。

注意配置文件中的值一定不要有空格

# Example config file /etc/vsftpd/vsftpd.conf
#
#
# 禁止匿名登录
anonymous_enable=NO
# 是否允许本地用户(即linux系统中的用户帐号)登录FTP服务器,默认设置为YES允许
# 本地用户登录后会进入用户主目录,而匿名用户登录后进入匿名用户的下载目录/var/ftp/pub
# 若只允许匿名用户访问,前面加上 #注释掉即可阻止本地用户访问FTP服务器
local_enable=YES
#
# 是否允许本地用户对FTP服务器文件具有写权限,默认设置为YES允许
write_enable=YES
#
# 掩码,本地用户默认掩码为077
# 你可以设置本地用户的文件掩码为缺省022,也可根据个人喜好将其设置为其他值
local_umask=022
#
# 是否允许匿名用户上传文件,须将全局的write_enable=YES。默认为YES
#anon_upload_enable=YES
#
#是否允许匿名用户创建新文件夹
#anon_mkdir_write_enable=YES

# 是否激活目录欢迎信息功能
# 当用户用CMD模式首次访问服务器上某个目录时,FTP服务器将显示欢迎信息
# 默认情况下,欢迎信息是通过该目录下的.message文件获得的
# 此文件保存自定义的欢迎信息,由用户自己建立
dirmessage_enable=YES
#
# 是否让系统自动维护上传和下载的日志文件
# 默认情况该日志文件为/var/log/vsftpd.log,也可以通过下面的xferlog_file选项对其进行设定
# 默认值为NO
xferlog_enable=YES
#
# 是否设定FTP服务器将启用FTP数据端口的连接请求
# ftp-data数据传输,21为连接控制端口
connect_from_port_20=YES
#
# 设定是否允许改变上传文件的属主,与下面一个设定项配合使用
# 注意,不推荐使用root用户上传文件
#chown_uploads=YES
# 设置想要改变的上传文件的属主,如果需要,则输入一个系统用户名
# 可以把上传的文件都改成root属主。whoever:任何人
#chown_username=whoever
#
# 设定系统维护记录FTP服务器上传和下载情况的日志文件
#xferlog_file=/var/log/xferlog
#
#如果你想,你可以有一个标准的ftpd xferlog格式的日志文件。
#注意默认的日志文件位置是/var/log/xferlog。
xferlog_std_format=YES
#
#您可以更改默认值,以使空闲会话超时。
#idle_session_timeout=600
#
# #您可以更改数据连接超时的默认值。
#data_connection_timeout=120
#
#运行vsftpd需要的非特权系统用户,缺省是nobody
#nopriv_user=ftpsecure
#
# 是否识别异步ABOR请求。
# 如果FTP client会下达“async ABOR”这个指令时,这个设定才需要启用
# 而一般此设定并不安全,所以通常将其取消
#async_abor_enable=YES
#
# 是否以ASCII方式传输数据。默认情况下,服务器会忽略ASCII方式的请求。
# 启用此选项将允许服务器以ASCII方式传输数据
# 不过,这样可能会导致由"SIZE /big/file"方式引起的DoS攻击
#ascii_upload_enable=YES
#ascii_download_enable=YES

# 登录FTP服务器时显示的欢迎信息
# 如有需要,可在更改目录欢迎信息的目录下创建名为.message的文件,并写入欢迎信息保存后
#ftpd_banner=Welcome to blah FTP service.

# 黑名单设置。如果很讨厌某些email address,就可以使用此设定来取消他的登录权限
# 可以将某些特殊的email address抵挡住。
#deny_email_enable=YES

# 当上面的deny_email_enable=YES时,可以利用这个设定项来规定哪些邮件地址不可登录vsftpd服务器
# 此文件需用户自己创建,一行一个email address即可
#banned_email_file=/etc/vsftpd/banned_emails

# You may specify an explicit list of local users to chroot() to their home
# directory. If chroot_local_user is YES, then this list becomes a list of
# users to NOT chroot().
# (Warning! chroot'ing can be very dangerous. If using chroot, make sure that
# the user does not have write access to the top level directory within the
# chroot)
chroot_local_user=YES

#  允许 chroot 用户具备写权限
allow_writeable_chroot=YES
#当chroot_list_enable=YES,chroot_local_user=YES时,在/etc/vsftpd.chroot_list文件中列出的用户,可以切换到其他目录;未在文件中列出的用户,不能切换到其他目录。
#当chroot_list_enable=YES,chroot_local_user=NO时,在/etc/vsftpd.chroot_list文件中列出的用户,不能切换到其他目录;未在文件中列出的用户,可以切换到其他目录。
#当chroot_list_enable=NO,chroot_local_user=YES时,所有的用户均不能切换到其他目录。
#当chroot_list_enable=NO,chroot_local_user=NO时,所有的用户均可以切换到其他目录。
chroot_list_enable=YES

# 被列入此文件的用户,在登录后将不能切换到自己目录以外的其他目录
# 从而有利于FTP服务器的安全管理和隐私保护。此文件需自己建立
#chroot_list_file=/etc/vsftpd/chroot_list
#
# 是否允许递归查询。默认为关闭,以防止远程用户造成过量的I/O
#ls_recurse_enable=YES
#
# 是否允许监听。
# 如果设置为YES,则vsftpd将以独立模式运行,由vsftpd自己监听和处理IPv4端口的连接请求
listen=YES
#
# 设定是否支持IPV6。如要同时监听IPv4和IPv6端口,
# 则必须运行两套vsftpd,采用两套配置文件
# 同时确保其中有一个监听选项是被注释掉的
# listen_ipv6=NO

# 设置是否阻扯user_list文件中的用户登录FTP服务器,默认为YES
#userlist_deny=YES/NO

# 设置PAM外挂模块提供的认证服务所使用的配置文件名,即/etc/pam.d/vsftpd文件
# 此文件中file=/etc/vsftpd/ftpusers字段,说明了PAM模块能抵挡的帐号内容来自文件/etc/vsftpd/ftpusers中
pam_service_name=vsftpd

# 是否允许ftpusers文件中的用户登录FTP服务器,默认为NO
# 若此项设为YES,则user_list文件中的用户允许登录FTP服务器
# 而如果同时设置了userlist_deny=YES,则user_list文件中的用户将不允许登录FTP服务器,甚至连输入密码提示信息都没有
userlist_enable=YES
# 是否使用tcp_wrappers作为主机访问控制方式。
# tcp_wrappers可以实现linux系统中网络服务的基于主机地址的访问控制
# 在/etc目录中的hosts.allow和hosts.deny两个文件用于设置tcp_wrappers的访问控制
# 前者设置允许访问记录,后者设置拒绝访问记录。
# 如想限制某些主机对FTP服务器192.168.57.2的匿名访问,编缉/etc/hosts.allow文件,如在下面增加两行命令:
# vsftpd:192.168.57.1:DENY 和vsftpd:192.168.57.9:DENY
# 表明限制IP为192.168.57.1/192.168.57.9主机访问IP为192.168.57.2的FTP服务器
# 此时FTP服务器虽可以PING通,但无法连接
tcp_wrappers=YES

#开启被动模式
pasv_enable=YES
# 传输文件的端口范围,如果是云服务器记得开放端口,linux服务器本身也要开放端口
pasv_min_port=9000
pasv_max_port=9005

传输模式配置

开启被动模式:

connect_from_port_20=NO(默认为YES) #设置是否允许主动模式
pasv_enable=YES(默认为YES) #设置是否允许被动模式
pasv_min_port=50000(default:0(use any port))
pasv_max_port=60000(default:0(use any port))

开启主动模式:

connect_from_port_20=YES
pasv_enable=NO

系统用户配置

linux创建用户:

useradd -d /home/ftp/compass -s /sbin/nologin  compass
passwd compass

为虚拟用户创建家目录

mkdir -p /home/ftp/compass

设置权限

chown -R compass:compass /home/ftp/compass

配置selinux允许ftp访问home和外网访问

[root@master ~]# setsebool -P allow_ftpd_full_access on
[root@master ~]# setsebool -P tftp_home_dir on

重启vsftpd服务

[root@master ~]# systemctl restart vsftpd

无法登录的情况 在/etc/vsftpd/vsftpd.conf配置文件中添加了以下两句

    chroot_local_user=YES  #原本就有,取掉注释就好
    allow_writeable_chroot=YES   #添加
    chown compass:compass -R /home/ftp/compass

java操作ftp文件服务器

有时候,我们需要接收用户上传的文件存储到服务器,然后保存起来,下次用户可以直接下载,或者是保存为档案,我这里提供三个方法,一个是上传文件到ftp,还有就是从ftp下载文件,还有就是删除ftp服务器删的文件

1.引入依赖

       <!--    ftp上传下载-->
        <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.7</version>
        </dependency>

2.提供接口

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * ftp文件服务器操作接口
 *
 * @author compass
 * @date 2022/10/19 15:00
 * @since 1.0.0
 **/
public interface FtpService {

    /**
     * 上传文件到ftp
     *
     * @param inputStream 输入流
     * @param fileName    新的文件名,包含拓展名
     * @param filePath    保存路径
     * @return
     * @author compass
     */
    Boolean uploadFile(InputStream inputStream, String fileName, String filePath);

    /**
     * 下载ftp文件,直接转到输出流
     * @author compass
     * @param ftpFilePath
     * @author compass
     */
    byte[] downloadFileBytes(String ftpFilePath, HttpServletResponse response);

    /**
     * 删除ftp文件
     * @author compass
     * @param ftpFilePath ftp下文件路径,根目录开始
     * @return
     */
    Boolean deleteFile(String ftpFilePath);
}

3.对提供操作ftp接口进行实现

/**
 * @author compass
 * @date 2022-10-19
 * @since 1.0
 **/

import java.io.*;

import compass.token.pocket.com.common.AjaxResult;
import compass.token.pocket.com.entity.FtpInstanceEntity;
import compass.token.pocket.com.service.FtpService;
import compass.token.pocket.com.utils.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

@Slf4j
@Service
public class FtpServiceImpl implements FtpService {

    @Resource
    FtpInstanceEntity ftpInstanceEntity;

    /**
     * 上传文件到ftp
     *
     * @param inputStream 输入流
     * @param fileName    新的文件名,包含拓展名
     * @param filePath    保存路径
     * @return
     * @author compass
     */
    @Override
    public Boolean uploadFile(InputStream inputStream, String fileName, String filePath) {
        // 定义保存结果
        boolean isSuccess = false;
        // 初始化连接
        FTPClient ftp = connectFtpServer();
        if (ftp != null) {
            try {
                // 设置文件传输模式为二进制,可以保证传输的内容不会被改变
                ftp.setFileType(FTP.BINARY_FILE_TYPE);
                //注:上传文件都为0字节,设置为被动模式即可
                ftp.enterLocalPassiveMode();
                // 跳转到指定路径,逐级跳转,不存在的话就创建再进入
                toPathOrCreateDir(ftp, filePath);
                // 上传文件 参数:上传后的文件名,输入流,,返回Boolean类型,上传成功返回true
                isSuccess = ftp.storeFile(fileName, inputStream);
                // 关闭输入流
                inputStream.close();
                // 退出ftp
                ftp.logout();
            } catch (IOException e) {
                log.error(e.toString());
            } finally {
                if (ftp.isConnected()) {
                    try {
                        // 断开ftp的连接
                        ftp.disconnect();
                    } catch (IOException ioe) {
                        log.error(ioe.toString());
                    }
                }
            }
        }
        return isSuccess;
    }

    /**
     * 下载ftp文件,直接转到输出流
     *
     * @param ftpFilePath
     * @author compass
     */
    @Override
    public byte[] downloadFileBytes(String ftpFilePath , HttpServletResponse response) {
        FTPClient ftp = connectFtpServer();
        try {
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftp.enterLocalPassiveMode();
            boolean retrieveFile = ftp.retrieveFile(ftpFilePath, stream);
            if (!retrieveFile){
                throw new RuntimeException("FTP文件下载失败");
            }
            ftp.logout();
            return stream.toByteArray();
        } catch (Exception e) {
            log.error("FTP文件下载失败!" + e.toString());
            ResponseUtil.response(response,AjaxResult.businessError(e.getMessage(), "-1"));
            throw new RuntimeException(e.getMessage());
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                    log.error(ioe.toString());
                }
            }

        }
    }

    /**
     * 删除ftp文件
     * @param ftpFilePath 文件路径
     * @return java.lang.Boolean
     * @author compass
     * @date 2022/10/19 18:35
     * @since 1.0.0
     **/
    @Override
    public Boolean deleteFile(String ftpFilePath ) {
        FTPClient ftp = connectFtpServer();
        boolean result = false;
        try {
            result = ftp.deleteFile(ftpFilePath);
            ftp.logout();
            return result;
        } catch (Exception e) {
            log.error("FTP文件删除失败!" + e.toString());
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                    log.error(ioe.toString());
                }
            }
        }
        return result;
    }

    /**
     * 创建FTPClient对象
     *
     * @return org.apache.commons.net.ftp.FTPClient
     * @author compass
     * @date 2022/10/19 18:35
     * @since 1.0.0
     **/
    private FTPClient connectFtpServer() {
        // 创建FTPClient对象(对于连接ftp服务器,以及上传和上传都必须要用到一个对象)
        FTPClient ftpClient = new FTPClient();
        // 设置连接超时时间
        ftpClient.setConnectTimeout(1000 * 10);
        // 设置ftp字符集
        ftpClient.setControlEncoding("utf-8");
        // 设置被动模式,文件传输端口设置,否则文件上传不成功,也不报错
        ftpClient.enterLocalPassiveMode();
        try {
            // 定义返回的状态码
            int replyCode;
            // 连接ftp(当前项目所部署的服务器和ftp服务器之间可以相互通讯,表示连接成功)
            ftpClient.connect(ftpInstanceEntity.getHost());
            // 输入账号和密码进行登录
            ftpClient.login(ftpInstanceEntity.getUsername(), ftpInstanceEntity.getPassword());
            // 接受状态码(如果成功,返回230,如果失败返回503)
            replyCode = ftpClient.getReplyCode();
            // 根据状态码检测ftp的连接,调用isPositiveCompletion(reply)-->如果连接成功返回true,否则返回false
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                log.info("connect ftp {} failed", ftpInstanceEntity.getHost());
                // 说明连接失败,需要断开连接
                ftpClient.disconnect();
                throw new RuntimeException(String.format("connect ftp %s failed", ftpInstanceEntity.getHost()));
            }
            log.info("连接状态码:" + replyCode);
        } catch (IOException e) {
            log.error("connect fail:" + e.toString());
            throw new RuntimeException(String.format("connect ftp %s error", ftpInstanceEntity.getHost()));
        }
        return ftpClient;
    }

    /**
     * 跳转到指定路径 不存在就创建
     *
     * @param ftp      操作ftp对象
     * @param filePath 文件路径
     * @return void
     * @author compass
     * @date 2022/10/19 15:05
     * @since 1.0.0
     **/
    private void toPathOrCreateDir(FTPClient ftp, String filePath) throws IOException {
        String[] dirs = filePath.split("/");
        for (String dir : dirs) {
            if (StringUtils.isEmpty(dir)) {
                continue;
            }
            if (!ftp.changeWorkingDirectory(dir)) {
                ftp.makeDirectory(dir);
                ftp.changeWorkingDirectory(dir);
            }
        }
    }

}

4.配置ftp相关参数

在配置文件中配置连接ftp服务器的配置

ftp:
  #ftp服务器的地址
  host: 127.0.0.1
  #ftp服务器的端口号(连接端口号)
  port: 21
  #ftp的用户名
  username: compass
  #ftp的密码
  password: 6317738ef8324199a24602308f3a9a18
  #ftp上传的根目录
  basePath: /home/ftp/compass
  #回显地址
  httpPath: ftp://127.0.0.1

然后将配置文件的内容读取到一个bean里面

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Data
@Configuration
@ConfigurationProperties(prefix = "ftp")
public class FtpInstanceEntity {
    /**
     * ftp服务器的地址
     */
    private String host;
    /**
     * ftp服务器的端口号(连接端口号)
     */
    private String port;
    /**
     * ftp的用户名
     */
    private String username;
    /**
     * ftp的密码
     */
    private String password;
    /**
     * ftp上传的根目录
     */
    private String basePath;
    /**
     * 回显地址
     */
    private String httpPath;

}

5.写测试controller

package compass.token.pocket.com.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import compass.token.pocket.com.common.AjaxResult;
import compass.token.pocket.com.entity.FtpInstanceEntity;
import compass.token.pocket.com.service.FtpService;
import compass.token.pocket.com.utils.FileUtils;
import compass.token.pocket.com.utils.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 文件测试控制器
 * @author compass
 * @date 2022/10/27 22:41
 * @since 1.0.0
 **/
@Slf4j
@RestController
@RequestMapping("/fileTestController")
public class FileTestController {

    @Resource
    private FtpService ftpService;

    @Resource
    FtpInstanceEntity ftpInstanceEntity;

    /**
     * ftp服务器文件上传
     * @param file 需要上传的文件
     * @return compass.token.pocket.com.common.AjaxResult<java.lang.String>
     * @author compass
     * @date 2022/10/19 14:51
     * @since 1.0.0
     **/
    @PostMapping(value = "/pdfUpload")
    public AjaxResult<String> pdfUpload(@RequestParam("file") MultipartFile file) {
        try {
            String fileDir = DateUtil.format(new Date(), "yyyy-MM-dd");
            boolean upload = ftpService.uploadFile(file.getInputStream(), file.getOriginalFilename(), fileDir);
            if (upload) {
                String savePath = ftpInstanceEntity.getBasePath() + "/" + fileDir + "/" + file.getOriginalFilename();
                return AjaxResult.success("上传成功", savePath);
            } else {
                return new AjaxResult<>("file upload error");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new AjaxResult<>("file upload error");
    }

    /**
     * ftp服务器文件下载
     * @param ftpPath 需要下载的文件路径
     * @return compass.token.pocket.com.common.AjaxResult<java.lang.String>
     * @author compass
     * @date 2022/10/19 14:51
     * @since 1.0.0
     **/
    @GetMapping(value = "/pdfDownload", produces = "application/octet-stream")
    public void downloadFile(@RequestParam("ftpPath") String ftpPath, HttpServletRequest request, HttpServletResponse response) {
        String userAgent = request.getHeader("User-Agent");
        String fileName = ftpPath.substring(ftpPath.lastIndexOf('/') + 1);
        try {
            if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
                //IE浏览器处理
                fileName = URLEncoder.encode(fileName, "UTF-8");
            } else {
                // 非IE浏览器的处理:
                fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
            }
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            response.setContentType("application/octet-stream; charset=UTF-8");
            byte[] bytes = ftpService.downloadFileBytes( ftpPath,response);
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(bytes);
            outputStream.flush();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * ftp服务器文件删除
     * @param ftpPath 需要删除的文件路径
     * @return compass.token.pocket.com.common.AjaxResult<java.lang.Boolean>
     * @author compass
     * @date 2022/10/19 14:51
     * @since 1.0.0
     **/
    @PostMapping("ftpDeleteFile")
    public AjaxResult<Boolean> ftpDeleteFile(@RequestParam("ftpPath") String ftpPath){
        Boolean isSuccess = ftpService.deleteFile(ftpPath);
        if (isSuccess){
             return  AjaxResult.success("删除成功", true);
        }else {
            return  AjaxResult.businessError("删除失败", false);
        }

    }

}

到这里操作ftp文件服务器的基本操作差不多结束了,讲的不是特别详细,但是基本来说,够用,如果遇到不能解决的问题请自行百度。

以上就是Java操作FTP实现上传下载功能的详细内容,更多关于Java FTP上传下载的资料请关注我们其它相关文章!

(0)

相关推荐

  • java实现ftp文件上传下载功能

    本文实例为大家分享了ftp实现文件上传下载的具体代码,供大家参考,具体内容如下 package getUrlPic; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; import org

  • Java FTP上传下载删除功能实例代码

    在没给大家上完整代码之前先给大家说下注意点: FTP上传下载,容易出现乱码,记得转换 package com.yinhai.team.action; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; impo

  • Java实现FTP文件的上传和下载功能的实例代码

    FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为"文传协议".用于Internet上的控制文件的双向传输.同时,它也是一个应用程序(Application).基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件.在FTP的使用当中,用户经常遇到两个概念:"下载"(Download)和"上传"(Upload)."下载"文件就是从远程主机拷贝文件至自己

  • Java实现FTP文件与文件夹的上传和下载

    FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为"文传协议".用于Internet上的控制文件的双向传输.同时,它也是一个应用程序(Application).基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件.在FTP的使用当中,用户经常遇到两个概念:"下载"(Download)和"上传"(Upload)."下载"文件就是从远程主机拷贝文件至自己

  • java实现文件上传下载至ftp服务器

    以前做的一个项目,用到了文件上传下载至ftp服务器,现在对其进行一下复习,比较简单,一下就能看明白. 环境:首先,先安装ftp服务器,我是在win8本地用IIS配置的, 百度一下就可以找到安装文档. 1.在你的项目目录下建立ftp配置文件,目录如下图 01 ftpconfig.properties: ftpIp=10.73.222.29 ftpPort=21 ftpUser=WP ftpPwd=04143114wp ftpRemotePath=d://share 02 读取ftpconfig.p

  • Java实现FTP上传与下载功能

    本文实例为大家分享了Java实现FTP上传与下载的具体代码,供大家参考,具体内容如下 JAVA操作FTP服务器,只需要创建一个FTPClient即可,所有的操作都封装在FTPClient中,JDK自带的有FTPClient(sun.net.ftp.FtpClient),也可以用第三方的FTPClient,一般使用apache的FTPClient(org.apache.commons.net.ftp.FTPClient),本文将使用apache的FTPClient,API都大同小异 关键依赖:co

  • Java操作FTP实现上传下载功能

    目录 FTP简介 FTP架构 FTP数据连接模式 用户认证 客户端 Vsftp安装与配置 启动服务 配置文件说明 传输模式配置 系统用户配置 java操作ftp文件服务器 1.引入依赖 2.提供接口 3.对提供操作ftp接口进行实现 4.配置ftp相关参数 5.写测试controller FTP简介 文件传输协议(File Transfer Protocol,FTP)是用于在网络上进行文件传输的一套标准协议,它工作在 OSI 模型的第七层,TCP 模型的第四层, 即应用层, 使用 TCP 传输而

  • Java实现ftp文件上传下载解决慢中文乱码多个文件下载等问题

    废话不多说了,直接给大家贴代码了,具体代码如下所示: //文件上传 public static boolean uploadToFTP(String url,int port,String username,String password,String path,String filename,InputStream input) { boolean success=false; FTPClient ftp=new FTPClient();//org.apache.commons.net.ftp

  • java基于servlet编写上传下载功能 类似文件服务器

    本人闲来无事,写了个servlet,实现上传下载功能.启动服务后,可以在一个局域网内当一个小小的文件服务器. 一.准备工作 下载两个jar包: commons-fileupload-1.3.1.jar commons-io-2.2.jar 二.创建一个web工程 我的工程名叫:z-upload 三.配置web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="ht

  • java实现简单图片上传下载功能

    本文实例为大家分享了java实现简单图片上传下载的具体代码,供大家参考,具体内容如下 1.首先在上传图片界面:将form表单的enctype改为:multipart/form-data 2.定义一个实体类用来将存放图片存放的路径存入到mysql中private String imgpath; 3.在spring容器中注入处理图片的解析器 <bean name="multipartResolver" class="org.springframework.web.multi

  • Java通过FTP服务器上传下载文件的方法

    对于使用文件进行交换数据的应用来说,使用FTP 服务器是一个很不错的解决方案. 关于FileZilla Server服务器的详细搭建配置过程,详情请见FileZilla Server安装配置教程.之前有朋友说,上传大文件(几百M以上的文件)到FTP服务器时会重现无法重命名的问题,但本人亲测上传2G的文件到FileZilla Server都没有该问题,朋友们可以放心使用该代码. FavFTPUtil.Java package com.favccxx.favsoft.util; import jav

  • java实现FTP文件上传与文件下载

    本文实例为大家分享了两种java实现FTP文件上传下载的方式,供大家参考,具体内容如下 第一种方式: package com.cloudpower.util; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import sun.net.TelnetInputStream; import sun.net.TelnetO

  • 基于Java文件输入输出流实现文件上传下载功能

    本文为大家分享了Java实现文件上传下载功能的具体代码,供大家参考,具体内容如下 前端通过form表单的enctype属性,将数据传递方式修改为二进制"流"的形式,服务端(servlet)通过  getInputStream() 获取流信息, 运用java I/O 流的基础操作将流写入到一个服务端临时创建的文件temp中,然后再次利用文件基本操作,读取并截取临时文件内容,根据其中信息创建相应的文件,将读取出来的具体信息写入,下载时,根据提交的文件名称,找到服务器端相应的文件,然后根据输

  • java中struts2实现文件上传下载功能实例解析

    本文实例讲述了java中struts2实现文件上传下载功能实现方法.分享给大家供大家参考.具体分析如下: 1.文件上传 首先是jsp页面的代码 在jsp页面中定义一个上传标签 复制代码 代码如下: <tr>      <td align="right" bgcolor="#F5F8F9"><b>附件:</b></td>      <td bgcolor="#FFFFFF">

  • FasfDFS整合Java实现文件上传下载功能实例详解

    在上篇文章给大家介绍了FastDFS安装和配置整合Nginx-1.13.3的方法,大家可以点击查看下. 今天使用Java代码实现文件的上传和下载.对此作者提供了Java API支持,下载fastdfs-client-java将源码添加到项目中.或者在Maven项目pom.xml文件中添加依赖 <dependency> <groupId>org.csource</groupId> <artifactId>fastdfs-client-java</arti

随机推荐