赞
踩
yum -y install vsftpd
[root@iZ2vc8owmlobwkazif1efpZ ~]# clear [root@iZ2vc8owmlobwkazif1efpZ ~]# useradd ftpuser [root@iZ2vc8owmlobwkazif1efpZ ~]# passwd ftpuser Changing password for user ftpuser. New password: BAD PASSWORD: The password contains the user name in some form Retype new password: passwd: all authentication tokens updated successfully. [root@iZ2vc8owmlobwkazif1efpZ ~]# yum -y install vsftpd Loaded plugins: fastestmirror Determining fastest mirrors base | 3.6 kB 00:00:00 docker-ce-stable | 3.5 kB 00:00:00 epel | 4.7 kB 00:00:00 extras | 2.9 kB 00:00:00 updates | 2.9 kB 00:00:00 (1/4): epel/x86_64/updateinfo | 1.0 MB 00:00:00 (2/4): epel/x86_64/primary_db | 6.9 MB 00:00:00 (3/4): updates/7/x86_64/primary_db | 9.6 MB 00:00:00 (4/4): docker-ce-stable/7/x86_64/primary_db | 63 kB 00:00:02 Resolving Dependencies --> Running transaction check ---> Package vsftpd.x86_64 0:3.0.2-29.el7_9 will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================================================================== Package Arch Version Repository Size ================================================================================================================================== Installing: vsftpd x86_64 3.0.2-29.el7_9 updates 173 k Transaction Summary ================================================================================================================================== Install 1 Package Total download size: 173 k Installed size: 353 k Downloading packages: vsftpd-3.0.2-29.el7_9.x86_64.rpm | 173 kB 00:00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : vsftpd-3.0.2-29.el7_9.x86_64 1/1 Verifying : vsftpd-3.0.2-29.el7_9.x86_64 1/1 Installed: vsftpd.x86_64 0:3.0.2-29.el7_9 Complete!
开启阿里云的安全组策略20/21,测试ftp,发现连接失败,使用8UFTP、Xftp都试了,都是连接失败
编辑配置文件: vim /etc/vsftpd/vsftpd.conf
开启防火墙的21端口,如果不行直接关闭防火墙 service iptables stop
,重启service vsftpd restart
活动模式可以,但是被动模式不行,不知道是什么原因…
<properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> <spring-cloud.version>Hoxton.SR9</spring-cloud.version> <commons-lang3.version>3.3.2</commons-lang3.version> <commons-io.version>1.3.2</commons-io.version> <commons-net.version>3.3</commons-net.version> <commons-fileupload.version>1.3.1</commons-fileupload.version> </properties> <dependencies> <!-- ftp文件上传--> <!-- Apache工具组件 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>${commons-lang3.version}</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-io</artifactId> <version>${commons-io.version}</version> </dependency> <dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>${commons-net.version}</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>${commons-fileupload.version}</version> </dependency>
package henu.soft.xiaosi.thirdparty.ftp; import lombok.extern.slf4j.Slf4j; import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTPClient; import java.io.File; import java.io.FileInputStream; @Slf4j public class PictureFTPTest { // 测试 ftp 上传图片功能 public void testFtpClient() throws Exception { // 1. 创建一个FtpClient对象 FTPClient ftpClient = new FTPClient(); // 2. 创建 ftp 连接 ftpClient.connect("xxx", 21); // 3. 登录 ftp 服务器 ftpClient.login("ftpuser", "xxx"); // 4. 读取本地文件 FileInputStream inputStream = new FileInputStream(new File("F:\\QQ Files\\MobileFile\\6.JPG")); // 5. 设置上传的路径 ftpClient.changeWorkingDirectory("/mydata/nginx/images"); // 6. 修改上传文件的格式为二进制 ftpClient.setFileType(FTP.BINARY_FILE_TYPE); // 7. 服务器存储文件,第一个参数是存储在服务器的文件名,第二个参数是文件流 ftpClient.storeFile("6.jpg", inputStream); // 8. 关闭连接 ftpClient.logout(); } public static void main(String[] args) { try { new PictureFTPTest().testFtpClient(); log.info("测试成功"); } catch (Exception e) { log.error(e.getMessage()); } } }
若是不成功,就修改下nginx的文件夹权限,查看服务器上传成功!!
配置文件上传解析器
package henu.soft.xiaosi.thirdparty.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.multipart.commons.CommonsMultipartResolver; @Configuration public class MyFTPConfig { /** * 文件上传解析器 * @return */ @Bean public CommonsMultipartResolver commonsMultipartResolver(){ CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(); commonsMultipartResolver.setDefaultEncoding("UTF-8"); commonsMultipartResolver.setMaxUploadSize(10*1024*1024); return commonsMultipartResolver; } }
service
package henu.soft.xiaosi.thirdparty.service;
import java.util.Map;
import org.springframework.web.multipart.MultipartFile;
public interface PictureService {
/**
* 上传,批量上传接口
* @param uploadFile
* @return
*/
Map uploadPicture(MultipartFile uploadFile);
}
service-impl
package henu.soft.xiaosi.thirdparty.service.impl; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import henu.soft.xiaosi.thirdparty.service.PictureService; import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPReply; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @Service @SuppressWarnings({"rawtypes", "unchecked"}) public class PictureServiceImpl implements PictureService { // 通过 Spring4 的 Value注解,获取配置文件中的属性值 @Value("${FTP_ADDRESS}") private String FTP_ADDRESS; // ftp 服务器ip地址 @Value("${FTP_PORT}") private Integer FTP_PORT; // ftp 服务器port,默认是21 @Value("${FTP_USERNAME}") private String FTP_USERNAME; // ftp 服务器用户名 @Value("${FTP_PASSWORD}") private String FTP_PASSWORD; // ftp 服务器密码 @Value("${FTP_BASE_PATH}") private String FTP_BASE_PATH; // ftp 服务器存储图片的绝对路径 @Value("${IMAGE_BASE_URL}") private String IMAGE_BASE_URL; // ftp 服务器外网访问图片路径 @Override public Map uploadPicture(MultipartFile uploadFile) { Map resultMap = new HashMap<>(); try { // 1. 取原始文件名 String oldName = uploadFile.getOriginalFilename(); // 2. ftp 服务器的文件名 String newName = oldName; //图片上传 boolean result = uploadFile(FTP_ADDRESS, FTP_PORT, FTP_USERNAME, FTP_PASSWORD, uploadFile.getInputStream(), FTP_BASE_PATH, newName); //返回结果 if(!result) { resultMap.put("error", 1); resultMap.put("message", "upload Fail"); return resultMap; } resultMap.put("error", 0); resultMap.put("url", IMAGE_BASE_URL + "/" + newName); return resultMap; } catch (Exception e) { e.printStackTrace(); resultMap.put("error", 1); resultMap.put("message", "upload Fail"); return resultMap; } } /** * ftp 上传图片方法 * @param ip ftp 服务器ip地址 * @param port ftp 服务器port,默认是21 * @param account ftp 服务器用户名 * @param passwd ftp 服务器密码 * @param inputStream 文件流 * @param workingDir ftp 服务器存储图片的绝对路径 * @param fileName 上传到ftp 服务器文件名 * @throws Exception * */ public boolean uploadFile(String ip, Integer port, String account, String passwd, InputStream inputStream, String workingDir, String fileName) throws Exception{ boolean result = false; // 1. 创建一个FtpClient对象 FTPClient ftpClient = new FTPClient(); try { // 2. 创建 ftp 连接 ftpClient.connect(ip, port); // 3. 登录 ftp 服务器 ftpClient.login(account, passwd); int reply = ftpClient.getReplyCode(); // 获取连接ftp 状态返回值 System.out.println("code : " + reply); if (!FTPReply.isPositiveCompletion(reply)) { ftpClient.disconnect(); // 如果返回状态不再 200 ~ 300 则认为连接失败 return result; } // 4. 读取本地文件 // FileInputStream inputStream = new FileInputStream(new File("F:\\hello.png")); // 5. 设置上传的路径 ftpClient.changeWorkingDirectory(workingDir); // 6. 修改上传文件的格式为二进制 ftpClient.setFileType(FTP.BINARY_FILE_TYPE); // 7. 服务器存储文件,第一个参数是存储在服务器的文件名,第二个参数是文件流 if (!ftpClient.storeFile(fileName, inputStream)) { return result; } // 8. 关闭连接 inputStream.close(); ftpClient.logout(); result = true; } catch (Exception e) { e.printStackTrace(); }finally { // FIXME 听说,项目里面最好少用try catch 捕获异常,这样会导致Spring的事务回滚出问题???难道之前写的代码都是假代码!!! if (ftpClient.isConnected()) { try { ftpClient.disconnect(); } catch (IOException ioe) { } } } return result; } }
配置文件
# 配置ftp
FTP_ADDRESS=192.168.0.11
FTP_PORT=21
FTP_USERNAME=ftpuser
FTP_PASSWORD=xxx
FTP_BASE_PATH=/usr/local/nginx/html/images
IMAGE_BASE_URL=http://192.168.0.11/images
controller
package henu.soft.xiaosi.thirdparty.controller; import java.util.Map; import henu.soft.xiaosi.thirdparty.service.PictureService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @RestController public class PictureController { @Autowired private PictureService pictureService; @RequestMapping("pic/upload") public String pictureUpload(@RequestParam(value = "fileUpload") MultipartFile uploadFile) { String json = ""; try { Map result = pictureService.uploadPicture(uploadFile); // 浏览器擅长处理json格式的字符串,为了减少因为浏览器内核不同导致的bug,建议用json json = new ObjectMapper().writeValueAsString(result); } catch (JsonProcessingException e) { e.printStackTrace(); } return json; } }
<el-upload class="upload-demo" name="fileUpload" action="http://xxx/pic/upload" :on-preview="handlePreview" :on-remove="handleRemove" :file-list="fileList" list-type="picture"> <el-button size="small" type="primary">点击上传</el-button> <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div> </el-upload> <script> export default { data() { return { // 上传成功回显 fileList: [{name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}, {name: 'food2.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}] }; }, methods: { handleRemove(file, fileList) { console.log(file, fileList); }, handlePreview(file) { console.log(file); } } } </script>
需要注意的是组件的 name="fileUpload"
需要和 后端的@RequestParam(value = "fileUpload")
保持一致
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。