ftp上传文件

1:ftp服务器安装

1.1检查是否安装了vsftpd服务

rpm -q vsftpd

在这里插入图片描述

1.2通过yum在线安装

yum install -y vsftpd

在这里插入图片描述

1.3:修改配置文件

  • /etc/vsftpd/vsftpd.conf 是主配置文件,核心配置文件
  • 使用 vim vsftpd.conf 打开并编辑主配置文件
  • 注:一般模式下输入":set nu"显示行号以便查找,按i或a进入编辑模式
1.3.1:需要修改的配置
anonymous_enable=YES
anon_upload_enable=YES
anon_mkdir_write_enable=YES
1.3.2:尾部需要添加的配置
anon_other_write_enable=YES
anon_world_readable_only=NO
anon_root=/home/vsftpd
1.3.3:默认情况下,图片只能上传到根路径下。如果想要上传到指定的目录中,可以通过ftp创建目录;

默认是不能自动创建该文件的,如果要创建需要修改配置文件;
原因一:

修改vsftpd.conf文件中的chroot_local_user=NO,
并重启 systemctl restart vsftpd.service;

原因二:
makeDirectory(path)中path的上一级目录是否存在,如果不存在则创建失败,即makeDirectory只能逐级创建;

1.4配置登录用户

//创建用户,myftp为用户名
useradd myftp
//为用户myftp设置密码
passwd myftp

1.5配置防火墙

1.5.1添加FTP到白名单
firewall-cmd --add-service=ftp --permanent
firewall-cmd --reload
1.5.2临时放宽SELinux的控制权限,即更改SELinux为Permissive模式

临时性

//查看当前SELinux模式
getenforce
//更改当前模式为Permissive模式
setenforce 0

永久

 vi /etc/selinux/config 
SELINUX=enforcing <==调整 enforcing|disabled|permissive 
1.5.1修改SELinux对FTP的控制权限
//使用getsebool -a | grep -i ftp查看相关权限,on表示允许,off表示不允许
//开启匿名上传
setsebool -P ftpd_anon_write=1 
1.5.1开放端口号 21、20
//开放21端口号
firewall-cmd --zone=public --add-port=21/tcp --permanent
//开放20端口号
firewall-cmd --zone=public --add-port=20/tcp --permanent
//查看已开放的端口号
firewall-cmd --list-ports

1.5.1修改完成后重启防火墙和vsftpd服务
//重启防火墙
firewall-cmd --reload
//重启vsftpd服务
systemctl start vsftpd

vsftpd常用命令:

状态 systemctl status vsftpd.service
启动 systemctl start vsftpd.service
关闭 systemctl enable vsftpd.service
重启 systemctl restart vsftpd.service
开机启动 systemctl enable vsftpd.service

解决Windows端无法访问的问题:

  • 打开控制面板—>网络和共享中心—>(左侧)Internet选项—>高级
    去掉“使用被动FTP”

在这里插入图片描述

  • 使用命令"systemctl stop firewalld.service"关闭Linux防火墙

注意

服务器重启需要重启vsftpd服务,或者设置启动加载vsftpd

//重启vsftpd服务
systemctl start vsftpd

1.导入坐标

 <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.3</version>
 </dependency>

2.添加ftp.properties配置文件

FTP_ADDRESS=ip地址
FTP_PORT=21
FTP_USERNAME=登陆的用户名
FTP_PASSWORD=登陆的密码
FTP_BASEPATH=用户的根目录
IMG_PATH=上传文件存放的路径

4.在springMvc里面添加配置文件扫描db.properties

<!--扫描db.ftp.properties-->
<context:property-placeholder location="classpath:ftp.properties" />

5.前台页面

<body>
<form action="addImgs.do" method="post" enctype="multipart/form-data">
    图片名:<input type="text" name="imgName"/>
    <br/>
    上传图片:<input type="file" name="imgs">
    <br/>
    <input type="submit" value="提交">
</form>
</body>

后台

控制层 通过@value获取db.properties数据

controller
package com.mr.ftp.controller;

import com.mr.ftp.service.FtpService;
import com.mr.utils.MyFtpUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by LI WAN on 2019/1/21.
 */
@Controller
public class FtpController {

    @Autowired
    private FtpService ftpService;

    @ResponseBody
    @RequestMapping("ftpTest")
    public String ftpTest(){
        return "hei";
    }

    @RequestMapping("openFtp")
    public String openFtp(){
        return "ftpList";
    }

    //获取ip地址
    @Value("${FTP_ADDRESS}")
    private String FTP_ADDRESS;

    //端口号
    @Value("${FTP_PORT}")
    private int FTP_PORT;

    //用户名
    @Value("${FTP_USERNAME}")
    private String FTP_USERNAME;

    //密码
    @Value("${FTP_PASSWORD}")
    private String FTP_PASSWORD;

    //ftp的基本路径
    @Value("${FTP_BASEPATH}")
    private String FTP_BASEPATH;

    //自定义需要上传的文件夹
    @Value("${IMG_PATH}")
    private String IMG_PATH;




   /*//获取ip地址
    private String FTP_ADDRESS="地址";
    //端口号
    private int FTP_PORT=21;
    //用户名
    private String FTP_USERNAME="zx2";
    //密码
    private String FTP_PASSWORD="root";
    //ftp的基本路径s
    private String FTP_BASEPATH="/home/zx2/";
    //自定义需要上传的文件夹sss
    private String IMG_PATH = "/ccc/imgs";
*/

    @RequestMapping("addImgs")
    @ResponseBody
    public String img(String imgName, MultipartFile imgs){
        boolean b = false;
        String oldName = imgs.getOriginalFilename();//获取源文件名
        String newName = MyFtpUtil.getFileSuffName(oldName);//修改为随机的文件名
        String url = "";// 上传成功之后访问的路径
        try {


            //通过工具类上传,如果上传成功则返回 true, 不成功为false
            b = MyFtpUtil.uploadFile(FTP_ADDRESS,FTP_USERNAME,FTP_PASSWORD,FTP_PORT,FTP_BASEPATH+IMG_PATH,newName,imgs.getInputStream());
            //ftp的访问路径: ftp://ip:端口号/自定义文件路径/w服务器中的文件名
            url = "ftp://"+FTP_ADDRESS+":"+FTP_PORT+"/"+IMG_PATH+"/"+newName;
            //将参数添加在map中吗,传递到后台插入数据,注意service层事务管理
            Map<String,String> map = new HashMap<>();
            map.put("imgName",imgName);
            map.put("url",url);
            //新增方法
            ftpService.addImg(map);

        } catch (IOException e) {
            e.printStackTrace();
        }
        if(b){//如果成功,返回访问路径
            return url;
        }
        return "error";//失败返回error
    }

}

service实现类

package com.mr.ftp.service;

import com.mr.ftp.mapper.FtpMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * Created by LI WAN on 2019/1/21.
 */
@Service
public class FtpServiceImpl implements FtpService{

    @Autowired
    private FtpMapper ftpMapper;

    @Override
    public void addImg(Map<String, String> map) {
        ftpMapper.addImg(map);
    }
}

mapper.xml

  <!--void addImg(Map<String, String> map);-->
    <insert id="addImg" parameterType="map">
        insert into t_imgs (img_name, img_url) VALUES (#{imgName},#{url})
  </insert>

工具类

package com.mr.utils;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

import java.io.*;
import java.net.SocketException;
import java.util.UUID;

/**
 * Created by LI WAN on 2019/1/21.
 */
public class MyFtpUtil {
    /**
     * 获取FTPClient对象
     *
     * @param ftpHost     FTP主机服务器
     * @param ftpPassword FTP 登录密码
     * @param ftpUserName FTP登录用户名
     * @param ftpPort     FTP端口 默认为21
     * @return
     */
    public static FTPClient getFTPClient(String ftpHost, String ftpUserName,
                                         String ftpPassword, int ftpPort) {
        FTPClient ftpClient = new FTPClient();
        try {
            ftpClient = new FTPClient();
            ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器
            ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器
            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                System.out.println("未连接到FTP,用户名或密码错误。");
                ftpClient.disconnect();
            } else {
                System.out.println("FTP连接成功。");
            }
        } catch (SocketException e) {
            e.printStackTrace();
            System.out.println("FTP的IP地址可能错误,请正确配置。");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("FTP的端口错误,请正确配置。");
        }
        return ftpClient;
    }


    /**
     * 从FTP服务器下载文件
     * @param ftpHost FTP IP地址
     * @param ftpUserName FTP 用户名
     * @param ftpPassword FTP用户名密码
     * @param ftpPort FTP端口
     * @param ftpPath FTP服务器中文件所在路径 格式: ftptest/aa
     * @param localPath 下载到本地的位置 格式:H:/download
     * @param fileName 文件名称
     */
    public static void downloadFtpFile(String ftpHost, String ftpUserName,
                                       String ftpPassword, int ftpPort, String ftpPath, String localPath,
                                       String fileName) {

        FTPClient ftpClient = null;

        try {
            boolean flag = ftpClient.changeWorkingDirectory(ftpPath);
            if(!flag){
                //创建上传的路径  该方法只能创建一级目录,在这里如果/home/ftpuser存在则可创建image
                ftpClient.makeDirectory(ftpPath);
            }
            //指定上传路径
            ftpClient.changeWorkingDirectory(ftpPath);


            ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
            ftpClient.setControlEncoding("UTF-8"); // 中文支持
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            ftpClient.changeWorkingDirectory(ftpPath);

            File localFile = new File(localPath + File.separatorChar + fileName);
            OutputStream os = new FileOutputStream(localFile);
            ftpClient.retrieveFile(fileName, os);
            os.close();
            ftpClient.logout();

        } catch (FileNotFoundException e) {
            System.out.println("没有找到" + ftpPath + "文件");
            e.printStackTrace();
        } catch (SocketException e) {
            System.out.println("连接FTP失败.");
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("文件读取错误。");
            e.printStackTrace();
        }

    }

    /**
     * Description: 向FTP服务器上传文件
     * @param ftpHost FTP服务器hostname
     * @param ftpUserName 账号
     * @param ftpPassword 密码
     * @param ftpPort 端口
     * @param ftpPath  FTP服务器中文件所在路径 格式: ftptest/aa
     * @param fileName ftp文件名称
     * @param input 文件流
     * @return 成功返回true,否则返回false
     */
    public static boolean uploadFile(String ftpHost, String ftpUserName,
                                     String ftpPassword, int ftpPort, String ftpPath,
                                     String fileName,InputStream input) {
        boolean success = false;
        FTPClient ftpClient = null;
        try {
            int reply;
            ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
            reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                return success;
            }
            ftpClient.setControlEncoding("UTF-8"); // 中文支持
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            boolean b = ftpClient.makeDirectory(ftpPath);
            System.out.println("创建目录:"+ftpPath);
            System.out.println(b);
            ftpClient.changeWorkingDirectory(ftpPath);

            ftpClient.storeFile(fileName, input);

            input.close();
            ftpClient.logout();
            success = true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return success;
    }

    /**
     * 修改文件名为uuid开头避免文件名重复
     * @param fileName 获取上传的文件名
     * @return 新的文件名
     */
    public static String getFileSuffName(String fileName){
        File file=new File(fileName);
        String oldFileName=file.getName();
        String suffixFileName=oldFileName.substring(oldFileName.lastIndexOf(".")+1);

        String uuid= UUID.randomUUID().toString().replace("-","");
        String newFileName=uuid+"."+suffixFileName;

        return newFileName;
    }

}

先登录再访问

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 终极编程指南 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值