当前位置:   article > 正文

Java使用FTP时碰到的坑--服务部署到linux时storeFile返回false_java fileclient.storefile 失败

java fileclient.storefile 失败

背景

正常情况下,我们都是把上传的文件保存到Java服务运行的服务器上。前段时间根据公司正式环境上的情况,必须要把文件做成跨服务器存储,经过考虑,最终采用FTP工具存储文件。
因为保存的文件并不是客户使用的文件,而是给运维人员使用的,所以这里并不需要考虑太多,直接写个简单的功能实现就好了。

正文

FTP服务站点怎么建,网上很多教程,不做赘述。本文只记录碰到的坑。
我是在window下开发,FTP服务端是window操作系统,开发阶段测试也在window下debug进行,正式环境下Java服务运行在linux上,采用docker部署。
在开发时一切正常,可是部署到服务器上,没有报出任何异常,但是ftp.storeFile()返回false。

依赖

查阅不少资料,很多人找不到jar包,甚至到网上求博主私信jar包,我不太理解为什么找不到,这里直接maven引入依赖就行了。

        <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.6</version>
        </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

实现代码

    /**
     * @param url       服务器IP地址
     * @param port      服务器端口
     * @param userName  用户登录名
     * @param password  用户登录密码
     * @param storePath 服务器文件存储路径
     * @param fileName  服务器文件存储名称
     * @param is        文件输入流
     * @return 			true上传成功    false上传失败
     */
    public static boolean storeFile(String url,
                                    int port,
                                    String userName,
                                    String password,
                                    String storePath,
                                    String fileName,
                                    InputStream is) {
        boolean result = false;
        FTPClient ftp = new FTPClient();
        try {
            ftp.connect(url, port);// 连接至服务器,端口默认为21时,可直接通过URL连接
            ftp.login(userName, password);// 登录服务器
            // 判断返回码是否合法
            if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
                ftp.disconnect();// 不合法时断开连接
                return result;// 结束程序
            }
            ftp.setControlEncoding("UTF-8"); // 中文转码
            ftp.enterLocalPassiveMode();// 被动模式
            ftp.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);//设置传输方式为流方式
            ftp.changeWorkingDirectory(storePath); // 设置文件操作目录
            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);// 设置文件类型,二进制
            ftp.setBufferSize(3072); // 设置缓冲区大小
            fileName = new String(fileName.getBytes("GBK"), "iso-8859-1");//文件名中文报错问题
            result = ftp.storeFile(fileName, is);//上传文件
            is.close();
            ftp.logout();// 登出服务器
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != is) {
                    is.close();
                }
                if (ftp.isConnected()) {
                    ftp.disconnect();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

重点在下面这两句:
ftp.enterLocalPassiveMode();// 被动模式
ftp.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);//设置传输方式为流方式

主动模式和被动模式

  1. PORT主动模式:ftp.enterLocalActiveMode();
    在这个模式下,客户端通过服务端的默认端口与服务端连接。在使用时客户端会随机开发一个端口发送PORT命令道服务端,告诉服务端客户端采用了主动模式和开放的端口。服务端收到客户端的PORT命令后,与客户端连接发送数据。
  2. PASV被动模式:ftp.enterLocalPassiveMode();
    在这个模式下,客户端发送的命令为PASV,此时是服务端开放端口给客户端连接,对于客户端而言是被动连接上服务端(客户端:我很被动,因为你服务端不告诉我端口,请问我要怎么连接?),开始数据传输。
    在正式环境里面,服务器的防火墙基本都是开的,需要什么端口在开放什么端口,如果没有设置被动模式传输数据,那客户端恐怕一辈子都连不上服务端,这导致的结果就是文件传输请求成功了,但是文件没有传过去,返回false。
    这也就是为什么服务器上没有上传的文件了。
    至于为什么不会报错,我跟了一下源码,大概意思就是针对文件传输结果一个返回码的问题。
    在这里插入图片描述
    看上图,返回结果就是true或者false,并无报错。上面的注释大概意思就是请求会返回一个响应码,2开头为true,3开头就是false。
    最后附上调用方法:
			MultipartFile file = ((MultipartHttpServletRequest) request).getFile("file");
            if (!file.isEmpty()) {
                try {
                    InputStream inputStream = file.getInputStream();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                boolean res = FTPUtils.storeFile("127.0.0.1", "21", userName, password, "//", file.getOriginalFilename(), inputStream);
                if (!res) {
                    msg = "FTP发生异常---->>>>文件上传失败";
                    return new ResponseDto<>(RespCode.ERROR.getId(), msg, null);
                }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

本文END。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/255548
推荐阅读
相关标签
  

闽ICP备14008679号