ftp+springboot文件传输(图片服务器配置)

导入依赖
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.8.0</version>
</dependency>

controller层
package com.neutech.controller;

import com.neutech.vo.ResultVO;
import com.neutech.vo.WangEditorItemVO;
import com.neutech.vo.WangEditorVO;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping(value = "/upload")
public class FileUploadController {

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

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

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

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

@Value("${ftp.speed}")
private Integer speed;

@Value("${nginx.prefix}")
private String nginxPrefix;

@PostMapping("/fileUpload")
public ResultVO fileUpload(MultipartFile file) {
// MultipartFile类型的对象当前台不传此参数有时是null,有时不是null
if (file == null || file.getSize() == 0) {
return ResultVO.error(1006, "文件未选择");
}

String fileName = "";
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect(hostname, port);
ftpClient.login(username, password);
int replyCode = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(replyCode)) {
return ResultVO.error(1007, "ftp服务器连接失败");
}
ftpClient.setControlEncoding("utf-8");
ftpClient.enterLocalPassiveMode();
ftpClient.setBufferSize(speed);
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);

// 切换文件夹
ftpClient.changeWorkingDirectory("/home/ftpuser/");
// 推送到服务器上的文件名一定不能重复,需要我们生成一个不重复的文件名
// UUID 号称全世界都不会重复 1.jpg
fileName = UUID.randomUUID().toString() +
file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
if (!ftpClient.storeFile(fileName, file.getInputStream())) {
return ResultVO.error(1009, "上传失败");
}

} catch (IOException e) {
e.printStackTrace();
return ResultVO.error(1010, "ftp服务器连接失败");
}
// 生成一个可访问的地址返回
return ResultVO.success(nginxPrefix + fileName);
// return ResultVO.success(fileName);
}


@PostMapping("/wangUpload")
public WangEditorVO wangUpload(MultipartFile[] files) {
if (files == null || files.length == 0) {
return WangEditorVO.error();
}

List<WangEditorItemVO> wangEditorItemVOList = new ArrayList<>();
for (MultipartFile file : files) {
ResultVO resultVO = fileUpload(file);
WangEditorItemVO wangEditorItemVO = new WangEditorItemVO();
wangEditorItemVO.setUrl((String) resultVO.getData());
wangEditorItemVOList.add(wangEditorItemVO);
}

return WangEditorVO.success(wangEditorItemVOList);
}
}


配置文件层
application.yml文件中写入:

ftp:
hostname: 192.168.253.151
port: 21
username: ftpuser
password: 52xzg1314
speed: 1024
nginx:
prefix: http://192.168.253.151/

说明:
1. 解决更换端口号时需要代码重新编译打包的问题
一些值放常量类里:需要重启服务器、重新编译、重新打包
可以防止配置文件中:项目重启,但不用重新编译。配置文件不是java代码,不用重新编译。
这里使用第二种方式:
首先,yml配置文件中写入如下内容。

ftp:
hostname: 192.168.253.151
post: 21
username: ftpuser
password: 52xzg1314

注意:yml文件中,数字不可以以0开头,会把他当成八进制解析。
解决方法:
加双引号,告诉他这是字符串,你别转
而在java代码中读取配置文件:

(在添加了@RestController注解的类里面,涉及框架原理:
yml文件是spring里面的。
当添加了@RestController表示将这个类交给IOC去处理,spring就能往类里面添加值。
而不添加时,spring无法往类里面加东西

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

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

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

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

@Value("${nginx.prefix}")
private String nginxPrefix;

2. 保证逻辑完整
保证在任何情况下都有返回值

3. 文件名处理
不可以叫用户自己的文件名。容易重名。
如何生成一个不重复的文件名:

时间:不行(web是并发程序)
UUID号称全世界都不会重复
fileName = UUID.randomUUID().toString() +
file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
if (!ftpClient.storeFile(fileName, file.getInputStream())) {
return ResultVO.error(1009, "上传失败");
}

UUID:36位,无后缀

结果示例:
postman请求入下:

 

 

Xftp中也可以看到该文件

 

 


linux下nginx配置文件访问路径
whereis nginx
cd xxxx
ll
cd conf
vi nginx.conf


更改配置文件到图片存储路径:如图:

 

 

 

 

 

浏览器访问
启动nginx:

systemctl start nginx

nginx403原因:用户权限问题
解决:

传到一个nginx能访问的路径,ftpuser用户就得配权限
nginx能访问ftpuser目录
采用方法二:
如下图:更改这一行语句如图:

 

 


之后访问:
linux主机ip地址/图片名
例如:http://192.168.253.151/a08f4ff4-ebac-47d0-9433-d78c4a7020c8.jpg

访问成功。

 

 


后续运行
只需要在虚拟机内启动ftp服务后,即可发送文件。

systemctl start vsftpd
————————————————
版权声明:本文为CSDN博主「海里有太阳」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_45926015/article/details/118599395

posted @ 2022-01-19 17:33  疯子110  阅读(734)  评论(0编辑  收藏  举报