导入依赖 commons-net commons-net 3.8.0controller层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 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: 1024nginx: 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 nginxcd xxxxllcd confvi nginx.conf

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

 

 

 

 

 

浏览器访问启动nginx:

systemctl start nginxnginx403原因:用户权限问题解决:

传到一个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

查看原文