一、简述
该文章用于上传一个文件或者图片,最后上传到服务器上文件夹中,然后返回给一个url路径。
没有多余的文字介绍,基本通用,不用url路径的自行简单性修改即可使用。
二、实操
1.导入依赖
<!--文件上传-->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
2.创建ftp上传下载工具类 --FtpUtil
package com.satoken.util;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import java.io.*;
import java.net.MalformedURLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* ftp上传下载工具类
*/
public class FtpUtil {
private static String host="ip地址";//本地IP地址或者服务器IP地址,服务器ip的话不能只用,需要用外网ip
private static Integer port=21;
private static String username="FtpUser";//自己定义
private static String password="*****";//查看个人的
private static String basePath="file";//自己定义
/**
* Description: 向FTP服务器上传文件
* @param filePath FTP服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath
* @param filename 上传到FTP服务器上的文件名
* @param input 输入流
* @return filePath 图片访问路径 fileName文件名 fileLocation文件绝对路径
*/
public static Map<String,String> uploadFile(String filePath,String filename, InputStream input) {
Map<String,String> map=new HashMap<>();
filename = imageName(filename);
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect(host, port);// 连接FTP服务器
// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
ftp.login(username, password);// 登录
ftp.setControlEncoding("utf-8");
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return null;
}
/*===========================================================*/
//切换到上传目录
if (!ftp.changeWorkingDirectory(filePath)) {
// 将路径中的斜杠统一
char[] chars = filePath.toCharArray();
StringBuffer sbStr = new StringBuffer(256);
for (int i = 0; i < chars.length; i++) {
if ('\\' == chars[i]) {
sbStr.append('/');
} else {
sbStr.append(chars[i]);
}
}
filePath = sbStr.toString();
System.out.println("ftpPath:" + filePath);
if (filePath.indexOf('/') == -1) {
// 只有一层目录
ftp.makeDirectory(new String(filePath.getBytes(), "UTF-8"));
ftp.changeWorkingDirectory(new String(filePath.getBytes(), "UTF-8"));
} else {
// 多层目录循环创建
String[] paths = filePath.split("/");
for (int i = 0; i < paths.length; i++) {
ftp.makeDirectory(new String(paths[i].getBytes(), "UTF-8"));
ftp.changeWorkingDirectory(new String(paths[i].getBytes(), "UTF-8"));
}
}
}
/*===========================================================*/
//设置上传文件的类型为二进制类型
ftp.setFileType(FTP.BINARY_FILE_TYPE);
//上传文件
if (!ftp.storeFile(filename, input)) {
return null;
}
input.close();
ftp.logout();
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
map.put("fileName",filename);
map.put("fileLocation","http://ip地址:项目端口号"+filePath+"/"+filename);
// 如果是服务器就只用ip,这里不用外网ip,这里的端口号和上面的port不一样,是个人项目端口号。
return map;
}
/**
* 删除文件
* @param pathname FTP服务器保存目录
* @param filename 要删除的文件名称
* @return true删除成功 false删除失败
*/
public static boolean deleteFile(String pathname, String filename){
boolean flag = false;
FTPClient ftpClient = new FTPClient();
try {
ftpClient.setControlEncoding("utf-8");
try {
ftpClient.connect(host, port); //连接ftp服务器
ftpClient.login(username, password); //登录ftp服务器
int replyCode = ftpClient.getReplyCode(); //是否成功登录服务器
if(!FTPReply.isPositiveCompletion(replyCode)){
ftpClient.disconnect();
return flag;
}
}catch (MalformedURLException e) {
e.printStackTrace();
}
//切换FTP目录
ftpClient.changeWorkingDirectory(pathname);
ftpClient.dele(filename);
ftpClient.logout();
flag = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
if(ftpClient.isConnected()){
try{
ftpClient.disconnect();
}catch(IOException e){
e.printStackTrace();
}
}
}
return flag;
}
/**
* 判断ftp服务器是否存在
* @param path 文件名
* @return true存在 false不存在
* @throws IOException
*/
public static boolean existFile(String path) throws IOException {
boolean flag = false;
FTPClient ftpClient = new FTPClient();
ftpClient.connect(host, port);// 连接FTP服务器
// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
ftpClient.login(username, password);// 登录
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
return flag;
}
FTPFile[] ftpFileArr = ftpClient.listFiles(path);
if (ftpFileArr.length > 0) {
flag = true;
}
return flag;
}
/**
* 生成文件名
* @param fileName 文件名
* @return 返回生成后的文件名
*/
public static String imageName(String fileName){
String name=new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())+UUID.randomUUID().toString().replaceAll("-","").substring(0,5);
String imgType =fileName.substring(fileName.lastIndexOf(".")+1,fileName.length());
return name+"."+imgType;
}
}
3.直接在控制层controller调用
创建图片上传类,写方法调用。
@ApiOperation(value = "图片上传" , produces = "application/json")
@PostMapping("imageUpload")
public Resp imageUpload( MultipartFile file) throws IOException {
Map<String, String> stringStringMap = FtpUtil.uploadFile("/image", file.getOriginalFilename(), file.getInputStream());
if(stringStringMap == null){
return Resp.fail("上传失败");
}
System.out.println(stringStringMap);//控制台查看
return Resp.success(stringStringMap);
}
也可以自己在工具类中写个main方法测,效果一样。
public static void main(String[] args) {
try {
FileInputStream in=new FileInputStream(new File("C:\\Users\\TTT\\Desktop\\1111.jpg"));
Map<String, String> stringStringMap = uploadFile("/2020/03/29", "2222.jpg", in);
System.out.println(stringStringMap );
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
有上传了,就得有删除,不然光上传不删除,不用文件,光删除数据库,服务器上不删除,就形成浪费资源了。
@ApiOperation(value = "图片删除" , produces = "application/json")
@PostMapping("imageDel")
public Resp imageDel( String file){
String [] a = file.split("/");
boolean result = FtpUtil.deleteFile("image",a[a.length-1]);
if(result == false){
return Resp.fail("删除失败");
}
return Resp.success("删除成功");
}
可自行去文件夹中查看是否删除,文件夹在你配置FTP时那个目录里,有个image文件夹。