How SpringBoot uses FTP to operate files
Introduction
Use SpringBoot to configure the FTP server to upload, delete, and download files.
Configuring FTP
Check whether vsftpd is installed
rpm -qa | grep vsftpd
Check whether vsftpd is installed and check the version number.
Install vsftpd
yum -y install vsftpd
If an error is reported, use administrator rights to execute
sudo yum -y install vsftpd
Turn off anonymous access
After turning off anonymous access, you need an account and password to access the files inside; if you don't turn it off, you can access it directly.
vim /etc/vsftpd/vsftpd.conf
If the prompt is a read-only file, then you only need to enter the command:
sudo vim /etc/vsftpd/vsftpd.conf
is as follows :
# Example config file /etc/vsftpd/vsftpd.conf # # The default compiled in settings are fairly paranoid. This sample file # loosens things up a bit, to make the ftp daemon more usable. # Please see vsftpd.conf.5 for all compiled in defaults. # # READ THIS: This example file is NOT an exhaustive list of vsftpd options. # Please read the vsftpd.conf.5 manual page to get a full idea of vsftpd's # capabilities. # # Allow anonymous FTP? (Beware - allowed by default if you comment this out). anonymous_enable=NO # # Uncomment this to allow local users to log in. local_enable=YES # # Uncomment this to enable any form of FTP write command. write_enable=YES # # Default umask for local users is 077. You may wish to change this to 022, # if your users expect that (022 is used by most other ftpd's) local_umask=022 # # Uncomment this to allow the anonymous FTP user to upload files. This only # has an effect if the above global write enable is activated. Also, you will # obviously need to create a directory writable by the FTP user. # When SELinux is enforcing check for SE bool allow_ftpd_anon_write, allow_ftpd_full_access #anon_upload_enable=YES # # Uncomment this if you want the anonymous FTP user to be able to create # new directories. #anon_mkdir_write_enable=YES # # Activate directory messages - messages given to remote users when they # go into a certain directory. dirmessage_enable=YES # # Activate logging of uploads/downloads. xferlog_enable=YES # # Make sure PORT transfer connections originate from port 20 (ftp-data). connect_from_port_20=YES # # If you want, you can arrange for uploaded anonymous files to be owned by # a different user. Note! Using "root" for uploaded files is not # recommended! #chown_uploads=YES #chown_username=whoever # # You may override where the log file goes if you like. The default is shown # below. #xferlog_file=/var/log/xferlog # # If you want, you can have your log file in standard ftpd xferlog format. # Note that the default log file location is /var/log/xferlog in this case. xferlog_std_format=YES # # You may change the default value for timing out an idle session. #idle_session_timeout=600
To turn off anonymous access is to: anonymous_enable=NO
Start the service
systemctl start vsftpd.service
View the service status
systemctl status vsftpd.service
[root@hadoop-master ~]# systemctl status vsftpd.service ● vsftpd.service - Vsftpd ftp daemon Loaded: loaded (/usr/lib/systemd/system/vsftpd.service; disabled; vendor preset: disabled) Active: active (running) since 一 2022-12-19 10:15:39 CST; 58min ago Process: 21702 ExecStart=/usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf (code=exited, status=0/SUCCESS) Main PID: 21703 (vsftpd) CGroup: /system.slice/vsftpd.service └─21703 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf 12月 19 10:15:39 hadoop-master systemd[1]: Starting Vsftpd ftp daemon... 12月 19 10:15:39 hadoop-master systemd[1]: Started Vsftpd ftp daemon. [root@hadoop-master ~]#
See the green
active (running)
, which means the startup is successful and running.
Add FTP user
Because on Linux, the root user cannot log in to FTP. If you enter the root user, the login will fail.
adduser ftpadmin
Set password:
passwd ftpadmin
Enter the password twice and it will be ok.
Configure to allow root user to log in
Place the /etc/vsftpd/user_list
file and /etc/vsftpd/ftpusers
Comment out the root
line in the file
Modify /etc/vsftpd/vsftpd.conf
and add local_root=/
to the last line
service vsftpd restart
In this way, you can remotely log in to ftp as the root user.
File storage address authorization
If the storage address is: app/upload/
, set the permission to:
chmod 777 /app/upload/
SpringBoot Coding
Add dependency
<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.55</version> </dependency>
Operation file tool class
package com.demo.utils; import com.jcraft.jsch.*; import com.demo.dto.UploadFileDto; import lombok.extern.slf4j.Slf4j; import java.io.File; import java.io.FileOutputStream; import java.util.Properties; /** * @ClassName: UploadFileUtils.java * @Description: 上传文件 * @Author: tanyp * @Date: 2022/12/19 10:38 **/ @Slf4j public class UploadFileUtils { /** * @MonthName: upload * @Description: 上传文件 * @Author: tanyp * @Date: 2022/12/19 10:38 * @Param: [dto] * @return: boolean **/ public static boolean upload(UploadFileDto dto) throws Exception { log.info("============上传文件开始=============="); Boolean result = false; ChannelSftp sftp = null; Channel channel = null; Session sshSession = null; try { JSch jSch = new JSch(); jSch.getSession(dto.getAccount(), dto.getHost(), dto.getPort()); sshSession = jSch.getSession(dto.getAccount(), dto.getHost(), dto.getPort()); sshSession.setPassword(dto.getPasswd()); Properties sshConfig = new Properties(); sshConfig.put("StrictHostKeyChecking", "no"); sshSession.setConfig(sshConfig); sshSession.connect(); channel = sshSession.openChannel("sftp"); channel.connect(); sftp = (ChannelSftp) channel; sftp.cd(dto.getWorkingDir()); sftp.put(dto.getInputStream(), dto.getFileName()); result = true; log.info("============上传文件结束=============="); } catch (JSchException e) { result = false; log.error("=====上传文件异常:{}", e.getMessage()); e.printStackTrace(); } finally { closeChannel(sftp); closeChannel(channel); closeSession(sshSession); } return result; } /** * @MonthName: delete * @Description: 删除文件 * @Author: tanyp * @Date: 2022/12/19 10:38 * @Param: [dto] * @return: boolean **/ public static boolean delete(UploadFileDto dto) throws Exception { log.info("============删除文件开始=============="); Boolean result = false; ChannelSftp sftp = null; Channel channel = null; Session sshSession = null; try { JSch jSch = new JSch(); jSch.getSession(dto.getAccount(), dto.getHost(), dto.getPort()); sshSession = jSch.getSession(dto.getAccount(), dto.getHost(), dto.getPort()); sshSession.setPassword(dto.getPasswd()); Properties sshConfig = new Properties(); sshConfig.put("StrictHostKeyChecking", "no"); sshSession.setConfig(sshConfig); sshSession.connect(); channel = sshSession.openChannel("sftp"); channel.connect(); sftp = (ChannelSftp) channel; sftp.cd(dto.getWorkingDir()); sftp.rm(dto.getFileName()); result = true; log.info("============删除文件结束=============="); } catch (JSchException e) { result = false; log.error("=====删除文件异常:{}", e.getMessage()); e.printStackTrace(); } finally { closeChannel(sftp); closeChannel(channel); closeSession(sshSession); } return result; } /** * @MonthName: download * @Description: 下载文件 * @Author: tanyp * @Date: 2022/12/19 10:38 * @Param: [dto] * @return: boolean **/ public static boolean download(UploadFileDto dto) throws Exception { log.info("============下载文件开始=============="); Boolean result = false; ChannelSftp sftp = null; Channel channel = null; Session sshSession = null; try { JSch jSch = new JSch(); jSch.getSession(dto.getAccount(), dto.getHost(), dto.getPort()); sshSession = jSch.getSession(dto.getAccount(), dto.getHost(), dto.getPort()); sshSession.setPassword(dto.getPasswd()); Properties sshConfig = new Properties(); sshConfig.put("StrictHostKeyChecking", "no"); sshSession.setConfig(sshConfig); sshSession.connect(); channel = sshSession.openChannel("sftp"); channel.connect(); sftp = (ChannelSftp) channel; sftp.cd(dto.getWorkingDir()); sftp.get(dto.getFileName(), new FileOutputStream(new File(dto.getDownloadPath()))); sftp.disconnect(); sftp.getSession().disconnect(); result = true; log.info("============下载文件结束=============="); } catch (JSchException e) { result = false; log.error("=====下载文件异常:{}", e.getMessage()); e.printStackTrace(); } finally { closeChannel(sftp); closeChannel(channel); closeSession(sshSession); } return result; } private static void closeChannel(Channel channel) { if (channel != null) { if (channel.isConnected()) { channel.disconnect(); } } } private static void closeSession(Session session) { if (session != null) { if (session.isConnected()) { session.disconnect(); } } } }
UploadFileDto.java
package com.demo.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.io.InputStream; /** * @ClassName: UploadFileDto.java * @ClassPath: com.demo.dto.UploadFileDto.java * @Description: 上传文件 * @Author: tanyp * @Date: 2022/12/19 10:38 **/ @Data @AllArgsConstructor @NoArgsConstructor @Builder @ApiModel(value = "上传文件Dto") public class UploadFileDto { @ApiModelProperty(value = " ftp 服务器ip地址") private String host; @ApiModelProperty(value = " ftp 服务器port,默认是21") private Integer port; @ApiModelProperty(value = " ftp 服务器用户名") private String account; @ApiModelProperty(value = " ftp 服务器密码") private String passwd; @ApiModelProperty(value = " ftp 服务器存储图片的绝对路径") private String workingDir; @ApiModelProperty(value = "上传到ftp 服务器文件名") private String fileName; @ApiModelProperty(value = " 文件流") private InputStream inputStream; @ApiModelProperty(value = " 下载文件的路径") private String downloadPath; }
UploadVo .java
package com.demo.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; /** * @ClassName: UploadVo.java * @ClassPath: com.demo.vo.UploadVo.java * @Description: 文件VO * @Author: tanyp * @Date: 2022/12/19 15:18 **/ @Data @AllArgsConstructor @NoArgsConstructor @Builder @ApiModel(value = "文件VO") public class UploadVo { @ApiModelProperty(value = "原始文件名称") private String oldName; @ApiModelProperty(value = "新文件名称") private String newName; @ApiModelProperty(value = "访问路径") private String path; }
UploadController
package com.demo.controller; import com.demo.vo.UploadVo; import com.demo.service.UploadService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; /** * @ClassName: UploadController.java * @ClassPath: com.demo.controller.UploadController.java * @Description: 上传文件 * @Author: tanyp * @Date: 2022/12/19 15:18 **/ @Slf4j @RestController @RequestMapping("/upload") @Api(value = "upload", tags = "上传文件") public class UploadController { @Autowired private UploadService uploadService; @ApiOperation(value = "上传图片", notes = "上传图片") @PostMapping("/uploadImage") public UploadVo uploadImage(@RequestParam("file") MultipartFile file) { return uploadService.uploadImage(file); } @ApiOperation(value = "删除文件", notes = "删除文件") @GetMapping("/delFile") public Boolean delFile(String fileName) { return uploadService.delFile(fileName); } @ApiOperation(value = "下载文件", notes = "下载文件") @GetMapping("/downloadFile") public Boolean downloadFile(String fileName, String downloadPath) { return uploadService.downloadFile(fileName, downloadPath); } }
UploadService
package com.demo.service; import com.demo.vo.UploadVo; import org.springframework.web.multipart.MultipartFile; /** * @ClassName: UploadService.java * @ClassPath: com.demo.service.UploadService.java * @Description:上传文件 * @Author: tanyp * @Date: 2022/12/19 15:18 **/ public interface UploadService { UploadVo uploadImage(MultipartFile file); Boolean delFile(String fileName); Boolean downloadFile(String fileName, String downloadPath); }
UploadServiceImpl
package com.demo.service.impl; import com.demo.dto.UploadFileDto; import com.demo.vo.UploadVo; import com.demo.config.FtpConfig; import com.demo.service.UploadService; import com.demo.utils.UUIDUtils; import com.demo.utils.UploadFileUtils; import com.demo.exception.BusinessException; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.Objects; /** * @ClassName: UploadServiceImpl.java * @ClassPath: com.demo.service.impl.UploadServiceImpl.java * @Description: 上传文件 * @Author: tanyp * @Date: 2022/12/19 15:18 **/ @Slf4j @Service public class UploadServiceImpl implements UploadService { @Autowired private FtpConfig ftpConfig; @Override public UploadVo uploadImage(MultipartFile file) { log.info("=======上传图片开始,图片名称:{}", file.getOriginalFilename()); try { // 1. 取原始文件名 String oldName = file.getOriginalFilename(); // 2. ftp 服务器的文件名 String newName = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + UUIDUtils.getUUID(10) + oldName.substring(oldName.lastIndexOf(".")); // 3.上传图片 Boolean result = UploadFileUtils.upload( UploadFileDto.builder() .host(ftpConfig.host) .port(ftpConfig.post) .account(ftpConfig.username) .passwd(ftpConfig.password) .workingDir(ftpConfig.basePath) .fileName(newName) .inputStream(file.getInputStream()) .build() ); // 4.返回结果 if (!result) { throw new BusinessException("上传图片失败!"); } log.info("=======上传图片结束,新图片名称:{}", newName); return UploadVo.builder() .oldName(oldName) .newName(newName) .path(ftpConfig.imageBaseUrl + "/" + newName) .build(); } catch (Exception e) { log.error("=======上传图片异常,异常信息:{}", e.getMessage()); e.printStackTrace(); } return null; } @Override public Boolean delFile(String fileName) { if (Objects.isNull(fileName)) { throw new BusinessException("文件名称为空,请核实!"); } try { Boolean result = UploadFileUtils.delete( UploadFileDto.builder() .host(ftpConfig.host) .port(ftpConfig.post) .account(ftpConfig.username) .passwd(ftpConfig.password) .workingDir(ftpConfig.basePath) .fileName(fileName) .build() ); return result; } catch (Exception e) { log.error("=======删除文件异常,异常信息:{}", e.getMessage()); e.printStackTrace(); } return null; } @Override public Boolean downloadFile(String fileName, String downloadPath) { if (Objects.isNull(fileName) || Objects.isNull(downloadPath)) { throw new BusinessException("文件名称或下载路径为空,请核实!"); } try { Boolean result = UploadFileUtils.download( UploadFileDto.builder() .host(ftpConfig.host) .port(ftpConfig.post) .account(ftpConfig.username) .passwd(ftpConfig.password) .workingDir(ftpConfig.basePath) .fileName(fileName) .downloadPath(downloadPath) .build() ); return result; } catch (Exception e) { log.error("=======下载文件异常,异常信息:{}", e.getMessage()); e.printStackTrace(); } return null; } }
FtpConfig
package com.demo.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * @ClassName: FtpConfig.java * @ClassPath: com.demo.config.FtpConfig.java * @Description: FTP配置 * @Author: tanyp * @Date: 2022/12/19 22:28 **/ @Component public class FtpConfig { // ftp 服务器ip地址 @Value("${ftp.host}") public String host; // ftp 服务器port,默认是21 @Value("${ftp.post}") public Integer post; // ftp 服务器用户名 @Value("${ftp.username}") public String username; // ftp 服务器密码 @Value("${ftp.password}") public String password; // ftp 服务器存储图片的绝对路径 @Value("${ftp.base-path}") public String basePath; // ftp 服务器外网访问图片路径 @Value("${ftp.image-base-url}") public String imageBaseUrl; }
application.yml
# ftp ftp: host: 127.0.0.1 post: 22 username: ftpadmin password: ftpadmin base-path: /app/upload/images image-base-url: http://127.0.0.1:8080/images
Configuring Nginx
server { listen 8080; server_name localhost; location /images/ { root /app/upload/; autoindex on; } }
The above is the detailed content of How SpringBoot uses FTP to operate files. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

With the rapid development of the Internet, File Transfer Protocol (FTP) has always been an important file transfer method. In Go language, using FTP to transfer files may be a need of many developers. However, maybe many people don't know how to use FTP in Go language. In this article, we will explore how to use FTP in Go language, from connecting to FTP server to file transfer, and how to handle errors and exceptions. Create FTP connection In Go language, we can use the standard "net" package to connect to FTP

1. Redis implements distributed lock principle and why distributed locks are needed. Before talking about distributed locks, it is necessary to explain why distributed locks are needed. The opposite of distributed locks is stand-alone locks. When we write multi-threaded programs, we avoid data problems caused by operating a shared variable at the same time. We usually use a lock to mutually exclude the shared variables to ensure the correctness of the shared variables. Its scope of use is in the same process. If there are multiple processes that need to operate a shared resource at the same time, how can they be mutually exclusive? Today's business applications are usually microservice architecture, which also means that one application will deploy multiple processes. If multiple processes need to modify the same row of records in MySQL, in order to avoid dirty data caused by out-of-order operations, distribution needs to be introduced at this time. The style is locked. Want to achieve points

Springboot reads the file, but cannot access the latest development after packaging it into a jar package. There is a situation where springboot cannot read the file after packaging it into a jar package. The reason is that after packaging, the virtual path of the file is invalid and can only be accessed through the stream. Read. The file is under resources publicvoidtest(){Listnames=newArrayList();InputStreamReaderread=null;try{ClassPathResourceresource=newClassPathResource("name.txt");Input

SpringBoot and SpringMVC are both commonly used frameworks in Java development, but there are some obvious differences between them. This article will explore the features and uses of these two frameworks and compare their differences. First, let's learn about SpringBoot. SpringBoot was developed by the Pivotal team to simplify the creation and deployment of applications based on the Spring framework. It provides a fast, lightweight way to build stand-alone, executable

PHP and FTP: Achieve file sharing among multiple departments in website development. With the development of the Internet, more and more companies are beginning to use website platforms for information release and business promotion. However, the problem that arises is how to achieve file sharing and collaboration among multiple departments. In this case, PHP and FTP become one of the most commonly used solutions. This article will introduce how to use PHP and FTP to achieve file sharing among multiple departments in website development. 1. Introduction to FTP FTP (FileTransferPr

1. Customize RedisTemplate1.1, RedisAPI default serialization mechanism. The API-based Redis cache implementation uses the RedisTemplate template for data caching operations. Here, open the RedisTemplate class and view the source code information of the class. publicclassRedisTemplateextendsRedisAccessorimplementsRedisOperations, BeanClassLoaderAware{//Declare key, Various serialization methods of value, the initial value is empty @NullableprivateRedisSe

How to compare directories and files on an FTP server through PHP In web development, sometimes we need to compare local files with files on the FTP server to ensure consistency between the two. PHP provides some functions and classes to implement this functionality. This article will introduce how to use PHP to compare directories and files on an FTP server, and provide relevant code examples. First, we need to connect to the FTP server. PHP provides the ftp_connect() function to establish an FTP server

In projects, some configuration information is often needed. This information may have different configurations in the test environment and the production environment, and may need to be modified later based on actual business conditions. We cannot hard-code these configurations in the code. It is best to write them in the configuration file. For example, you can write this information in the application.yml file. So, how to get or use this address in the code? There are 2 methods. Method 1: We can get the value corresponding to the key in the configuration file (application.yml) through the ${key} annotated with @Value. This method is suitable for situations where there are relatively few microservices. Method 2: In actual projects, When business is complicated, logic
