使用ftp上传文件

一. 服务器部分

// 安装
yum install vsftpd -y
systemctl start vsftpd

// 查看ftp是否安装成功,21号端口是ftp就是安装成功
netstat -nltp | grep 21

// 创建用户名和设置用户密码
useradd ftpfile
echo "ftpfile" | passwd ftpfile --stdin

// 开启ftp的文件访问权限和传输权限
getsebool -a|grep ftp
setsebool -P ftpd_full_access on
setsebool -P tftp_home_dir on

// 重启ftp
systemctl restart vsftpd.service

// 文件夹授权,/home/images这个目录等会作为文件的保存位置
chmod a-w /home/images && chmod 777 -R /home/images

二. java代码

  1. pom坐标
<dependency>
     <groupId>commons-net</groupId>
     <artifactId>commons-net</artifactId>
     <version>3.9</version>
 </dependency>
  1. nginx
// 监听端口和请求,遇到images自动去找/home/images下的文件
server {
         listen     1777;
         server_name _;
         root    /home/demo;
         location /images {
            alias  /home/images;
         }
}
  1. yml
ftp:
  host: 服务器ip,具体可以用ifconfig查看
  port: 21
  user: ftpfile
  pass: ftpfile
  path: /home/images/
  visit: 1777 # nginx配置的端口
  file: http://${ftp.host}:${ftp.visit}/images/
  1. 创建FTPClient Bean
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
@Scope("prototype")
public class FtpConfig implements InitializingBean, DisposableBean {

    @Value("${ftp.host}")
    private String host;

    @Value("${ftp.port}")
    private int port;

    @Value("${ftp.user}")
    private String user;

    @Value("${ftp.pass}")
    private String pass;

	@Value("${ftp.path}")
	private String path;

	private FTPClient ftpClient;

	@Override
	public void afterPropertiesSet(){
		ftpClient = new FTPClient();
		try {
			ftpClient.connect(host, port);
			ftpClient.login(user, pass);
			ftpClient.enterLocalPassiveMode();
			ftpClient.changeWorkingDirectory(path);
			ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void destroy() throws Exception {
		ftpClient.disconnect();
	}

	@Bean
	@Scope("prototype")
	public FTPClient ftpClient() {
		return ftpClient;
	}

	@Autowired
	private ObjectProvider<FTPClient> ftpClientProvider;

	public FTPClient getFtpClient() {
		return ftpClientProvider.getObject();
	}
}
  1. controller
@RestController
@RequestMapping("/file")
public class FileController {

	@Autowired
	private FtpConfig ftpConfig;

	@Value("${ftp.file}")
	private String ftpFile;

	@SneakyThrows
	@PostMapping("/putFile")
	public R<String> putFile(@RequestParam MultipartFile file) {
		FTPClient ftpClient = ftpConfig.getFtpClient();
		String filePath = new Random().nextInt(1000)+"-"+System.currentTimeMillis()+file.getOriginalFilename();
		ftpClient.storeFile(new String(filePath.getBytes("UTF-8"),"ISO-8859-1"),  file.getInputStream());
		ftpClient.logout();
		return R.data(ftpFile+filePath);
	}

}

三. 问题
在使用ftpClient时,老是出现Broken Pipe的错误。
经过分析得出,是因为ftp连接的问题。
spring默认使用单例模式,每次拿到的bean都是同一个对象。
因为调用这个接口时,第一次调用完就关闭了,后续所有的接口都会报错,假如不关闭连接,也会因为ftp连接时间的问题自动关闭,所以我这边改变了bean的作用域,使得每次返回都是一个新的对象。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值