SSM框架集成FTP+nginx实现文件的上传和下载
1、背景与设计思路
1、背景:
在很多场景中,经常会遇到文件或者图片上传的需求。如用户反馈、背景图片上传等等。
2、设计思路:
可以先看看人家是怎么设计的,下面是随意找的一个网站,查看图片上传的逻辑:
a、图片上传页面:
b、使用F12查看实际发起的请求:
很显然,在系统调用ajaxuploadpic接口后,返回了一response,这个就是后台服务器在保存了上传的这张图片后,该图片在服务器中保存的文件名
2、设计方案
根据第一步,我们基本就可以确定下开发思路了。
3、代码开发
1、首先,为了方便后续集成。开发了一个FTP的单独模块,用于集成。其中该模块的结构图如下所示:
2、具体的工具类代码如下所示:
FtpVo .java
package com.entity;
public class FtpVo {
private String host;
private int port;
private String username;
private String password;
private boolean binaryTransfer = true;
private boolean passiveMode = true;
private String encoding = "UTF-8";
private int clientTimeout = 1000 * 30;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isBinaryTransfer() {
return binaryTransfer;
}
public void setBinaryTransfer(boolean binaryTransfer) {
this.binaryTransfer = binaryTransfer;
}
public boolean isPassiveMode() {
return passiveMode;
}
public void setPassiveMode(boolean passiveMode) {
this.passiveMode = passiveMode;
}
public String getEncoding() {
return encoding;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public int getClientTimeout() {
return clientTimeout;
}
public void setClientTimeout(int clientTimeout) {
this.clientTimeout = clientTimeout;
}
}
DeleteServer.java
package com.main;
import java.util.List;
import com.util.FTPUload;
public class DeleteServer {
public static boolean deleteFile(String url, String projectName) {
boolean falg = true;
try {
FTPUload ftpUload = new FTPUload();
falg = ftpUload.deleteFile(url, projectName);
} catch (Exception e) {
falg = false;
e.printStackTrace();
}
return falg;
}
public static boolean deleteFile(List<String> list, String projectName) {
boolean falg = true;
try {
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
FTPUload ftpUload = new FTPUload();
falg = ftpUload.deleteFile(list.get(i), projectName);
}
}
} catch (Exception e) {
falg = false;
e.printStackTrace();
}
return falg;
}
}
DownloadToLocal.java
package com.main;
import java.io.File;
import java.net.URL;
import org.apache.commons.io.FileUtils;
import com.util.DateUtil;
import com.util.FTPUload;
import com.util.ProperManagerFTP;
public class DownloadToLocal {
/**
* @description 下载图片后,nginx 做映射
* @param url
* @return
*/
public static String downloadFromUrl(String url, String projectName) {
String result = ProperManagerFTP.getString("webpath");
try {
URL httpurl = new URL(url);
String extName = getFileExtName(url);
String fileName = System.currentTimeMillis() + "." + extName;
System.out.println(result + fileName);
String webpath = DateUtil.getFilePath();
result = result + projectName + "/" + webpath + fileName;
File f = new File(
System.getProperty("user.dir").replace("\\", "/") + "/" + projectName + "/" + webpath + fileName);
FileUtils.copyURLToFile(httpurl, f);
FTPUload ftpUload = new FTPUload();
ftpUload.ftpUpload(f.getPath());
} catch (Exception e) {
e.printStackTrace();
return "error";
}
return result;
}
/**
* @description 保留原有的名称
* @param url
* @return
*/
public static String getFileNameFromUrl(String url) {
String name = new Long(System.currentTimeMillis()).toString() + ".X";
int index = url.lastIndexOf("/");
if (index > 0) {
name = url.substring(index + 1);
if (name.trim().length() > 0) {
return name;
}
}
return name;
}
public static String getFileExtName(String fileName) {
String extName = "";
if (fileName != null && !"".equals(fileName)) {
int i = fileName.lastIndexOf(".");
if (i > 0) {
extName = fileName.substring(i + 1, fileName.length());
}
}
return extName;
}
}
UploadServer.java
package com.main;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.imageio.ImageIO;
import org.springframework.web.multipart.MultipartFile;
import com.util.DateUtil;
import com.util.FTPUload;
import com.util.GlobalVars;
public class UploadServer {
/**
* 保存本地再上传
*
* @param multipartFile
* @param projectName
* @return
*/
public static Map<String, String> getUploadPathMap(MultipartFile multipartFile, String projectName) {
boolean falg = true;
Map<String, String> map = new HashMap<String, String>();
String path = System.getProperty("user.dir") + "/";
String webpath = DateUtil.getFilePath();
try {
if (projectName == null || projectName.equals("") || projectName.equals("/")) {
path = path + "/images/" + webpath;
} else {
path = path + "/" + projectName + "/" + webpath;
}
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
String extName = getFileExtName(multipartFile.getOriginalFilename());
String fileName = System.currentTimeMillis() + "." + extName;
webpath = webpath + fileName;
String uploadPath = path + "/" + fileName;
File files = new File(uploadPath);
multipartFile.transferTo(files);
BufferedImage sourceImg = ImageIO.read(new FileInputStream(files));
FTPUload ftpUload = new FTPUload();
ftpUload.ftpUpload(uploadPath);
map.put("width", sourceImg.getWidth() + "");
map.put("height", sourceImg.getHeight() + "");
String r = "";
if (projectName == null || projectName.equals("") || projectName.equals("/")) {
r = "images/" + webpath;
} else {
r = projectName + "/" + webpath;
}
if (falg == false) {
map.put("url", GlobalVars.WEBPATH + "/error.jpg");
} else {
map.put("url", GlobalVars.WEBPATH + r);
}
Thread.sleep(2000);
} catch (Exception e) {
map.put("url", GlobalVars.WEBPATH + "/error.jpg");
e.printStackTrace();
}
return map;
}
/**
* 不保存本地通过流上传
*
* @param multipartFile
* @param projectName
* @return
*/
public static Map<String, String> getUploadPathMapInputSteam(MultipartFile multipartFile, String projectName) {
boolean falg = true;
Map<String, String> map = new HashMap<String, String>();
String path = System.getProperty("user.dir") + "/";
String webpath = DateUtil.getFilePath();
try {
if (projectName == null || projectName.equals("") || projectName.equals("/")) {
path = path + "/images/" + webpath;
} else {
path = path + "/" + projectName + "/" + webpath;
}
String extName = getFileExtName(multipartFile.getOriginalFilename());
String fileName = System.currentTimeMillis() + "." + extName;
webpath = webpath + fileName;
String uploadPath = path + "/" + fileName;
BufferedImage sourceImg = ImageIO.read(multipartFile.getInputStream());
FTPUload ftpUload = new FTPUload();
ftpUload.ftpUpload(multipartFile.getInputStream(), uploadPath);
map.put("width", sourceImg.getWidth() + "");
map.put("height", sourceImg.getHeight() + "");
String r = "";
if (projectName == null || projectName.equals("") || projectName.equals("/")) {
r = "images/" + webpath;
} else {
r = projectName + "/" + webpath;
}
if (falg == false) {
map.put("url", GlobalVars.WEBPATH + "/error.jpg");
} else {
map.put("url", GlobalVars.WEBPATH + r);
}
Thread.sleep(2000);
} catch (Exception e) {
map.put("url", GlobalVars.WEBPATH + "/error.jpg");
e.printStackTrace();
}
return map;
}
/**
*
* @Title: getUploadPath @Description: 保存本地再上传 @param
* multipartFile @return @return String @throws
*/
public static String getUploadPath(MultipartFile multipartFile, String projectName) {
boolean falg = true;
String reStr = "";
String webpath = DateUtil.getFilePath();
try {
String path = System.getProperty("user.dir") + "/";
if (projectName == null || projectName.equals("") || projectName.equals("/")) {
path = path + "/images/" + webpath;
} else {
path = path + "/" + projectName + "/" + webpath;
}
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
String extName = getFileExtName(multipartFile.getOriginalFilename());
String fileName = System.currentTimeMillis() + "." + extName;
webpath = webpath + fileName;
String uploadPath = path + "/" + fileName;
File files = new File(uploadPath);
multipartFile.transferTo(files);
FTPUload ftpUload = new FTPUload();
falg = ftpUload.ftpUpload(uploadPath);
if (falg == false) {
reStr = GlobalVars.WEBPATH + "/error.jpg";
} else {
if (projectName == null || projectName.equals("") || projectName.equals("/")) {
reStr = "images/" + webpath;
} else {
reStr = projectName + "/" + webpath;
}
reStr = GlobalVars.WEBPATH + reStr;
}
Thread.sleep(2000);
} catch (Exception e) {
reStr = GlobalVars.WEBPATH + "/error.jpg";
e.printStackTrace();
}
return reStr;
}
/**
*
* @Title: getUploadPath @Description: 不保存本地通过流上传 @param
* multipartFile @return @return String @throws
*/
public static String getUploadPathInputSteam(MultipartFile multipartFile, String projectName) {
boolean falg = true;
String reStr = "";
String webpath = "marketdatas/";
try {
String path = "/marketdatas";
String fileName = UUID.randomUUID().toString().replace("-", "");
String originalName = multipartFile.getOriginalFilename();
String extName = getFileExtName(originalName);
if ("png".equals(extName) || "jpg".equals(extName)) {
path = path + "/images";
} else if ("apk".equals(extName)) {
path = path + "/apk";
} else {
path = path + "/others";
}
webpath = webpath + fileName + "." + extName;
String uploadPath = path + "/" + fileName + "." + extName;
FTPUload ftpUload = new FTPUload();
falg = ftpUload.ftpUpload(multipartFile.getInputStream(), uploadPath);
if (falg == false) {
reStr = GlobalVars.WEBPATH + "/error.jpg";
} else {
if (projectName == null || projectName.equals("") || projectName.equals("/")) {
reStr = uploadPath;
} else {
reStr = uploadPath;
}
reStr = GlobalVars.WEBPATH + reStr;
}
Thread.sleep(2000);
} catch (Exception e) {
reStr = GlobalVars.WEBPATH + "/error.jpg";
}
return reStr;
}
public static String getUploadPath(String filePaht, String projectName) {
String path = "";
try {
File file = new File(filePaht);
if (!file.isFile()) {
return path = "error";
}
FTPUload ftpUload = new FTPUload();
path = ftpUload.ftpUpload(filePaht.replace("\\", "/"), projectName);
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
return path;
}
public static String getUploadPathInputSteam(File filePaht, String projectName) {
String path = "";
try {
if (filePaht != null && !filePaht.isFile()) {
return path = "error";
}
FTPUload ftpUload = new FTPUload();
path = ftpUload.ftpUploadFile(filePaht, projectName);
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
return path;
}
public static String getFileExtName(String fileName) {
String extName = "";
if (fileName != null && !"".equals(fileName)) {
int i = fileName.lastIndexOf(".");
if (i > 0) {
extName = fileName.substring(i + 1, fileName.length());
}
}
return extName;
}
}
DateUtil.java
package com.util;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateUtil {
private static ThreadLocal<DateFormat> fullDateFormatter = new ThreadLocal<DateFormat>();
private static ThreadLocal<DateFormat> shortDateFormatter = new ThreadLocal<DateFormat>();
private static ThreadLocal<DateFormat> dateFormatter = new ThreadLocal<DateFormat>();
private static ThreadLocal<DateFormat> yearFormatter = new ThreadLocal<DateFormat>();
private static ThreadLocal<DateFormat> uploadFormatter = new ThreadLocal<DateFormat>();
/**
*
* @Title: dateToMin @Description: 转化到分 @param date @return @return
* String @throws
*/
public static String dateToMin(final Date date) {
DateFormat df = fullDateFormatter.get();
if (df == null) {
df = new SimpleDateFormat("yyyyMMddHHmm");
fullDateFormatter.set(df);
}
return df.format(date);
}
/**
*
* @Title: dateToHou @Description: 转化到时 @param date @return @return
* String @throws
*/
public static String dateToHou(final Date date) {
DateFormat df = shortDateFormatter.get();
if (df == null) {
df = new SimpleDateFormat("yyyyMMddHH");
shortDateFormatter.set(df);
}
return df.format(date);
}
/**
*
* @Title: dateToDay @Description: 转化到天 @param date @return @return
* String @throws
*/
public static String dateToDay(final Date date) {
DateFormat df = dateFormatter.get();
if (df == null) {
df = new SimpleDateFormat("yyyyMMdd");
dateFormatter.set(df);
}
return df.format(date);
}
/**
*
* @Title: dateToYear @Description: 转化到年 @param date @return @return
* String @throws
*/
public static String dateToYear(final Date date) {
DateFormat df = yearFormatter.get();
if (df == null) {
df = new SimpleDateFormat("yyyy");
yearFormatter.set(df);
}
return df.format(date);
}
/**
*
*
* @Title: getYear @Description: 获取年,公元纪年 @return @return Integer @throws
*/
public static Integer getYear() {
return Integer.parseInt(DateUtil.dateToYear(new Date()));
}
public static String getFilePath() {
DateFormat df = uploadFormatter.get();
if (df == null) {
df = new SimpleDateFormat("yyyy/MM/dd/HH/mm/ss/");
uploadFormatter.set(df);
}
return df.format(new Date());
}
public static Date date2Str(String Str) {
Date date = null;
try {
date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(Str);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
public static void main(String[] args) {
System.out.println(DateUtil.date2Str("2018-12-31 23:59:59"));
}
}
FTPClientException.java
package com.util;
public class FTPClientException extends Exception {
private static final long serialVersionUID = 1L;
public FTPClientException(String s, Exception e) {
System.out.println(s + e);
}
public FTPClientException(String s) {
System.out.println(s);
}
}
FtpConnect.java
package com.util;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import com.entity.FtpVo;
public class FtpConnect {
private ThreadLocal<FTPClient> ftpClientThreadLocal = new ThreadLocal<FTPClient>();
private static final String ftppath = ProperManagerFTP.getString("ftppath");
private FtpVo ftpVo;
public FtpConnect() {
}
public FtpConnect(FtpVo ftpVo) {
this.ftpVo = ftpVo;
}
public FTPClient getFTPClient() throws FTPClientException {
if (ftpClientThreadLocal.get() != null && ftpClientThreadLocal.get().isConnected()) {
return ftpClientThreadLocal.get();
} else {
FTPClient ftpClient = new FTPClient(); // 构造一个FtpClient实例
ftpClient.setControlEncoding(ftpVo.getEncoding()); // 设置字符集
connect(ftpClient); // 连接到ftp服务器
// 设置为passive模式
if (ftpVo.isPassiveMode()) {
ftpClient.enterLocalPassiveMode();
}
setFileType(ftpClient); // 设置文件传输类型
try {
ftpClient.setSoTimeout(ftpVo.getClientTimeout());
} catch (SocketException e) {
throw new FTPClientException("Ftp 连接超时", e);
}
ftpClientThreadLocal.set(ftpClient);
return ftpClient;
}
}
/**
* 设置文件传输类型
*
* @throws FTPClientException
* @throws java.io.IOException
*/
private void setFileType(FTPClient ftpClient) throws FTPClientException {
try {
if (ftpVo.isBinaryTransfer()) {
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
} else {
ftpClient.setFileType(FTPClient.ASCII_FILE_TYPE);
}
} catch (IOException e) {
throw new FTPClientException("Could not to set file type.", e);
}
}
/**
* 连接到ftp服务器
*
* @param ftpClient
* @return 连接成功返回true,否则返回false
* @throws FTPClientException
*/
private boolean connect(FTPClient ftpClient) throws FTPClientException {
try {
ftpClient.connect(ftpVo.getHost(), ftpVo.getPort());
// 连接后检测返回码来校验连接是否成功
int reply = ftpClient.getReplyCode();
if (FTPReply.isPositiveCompletion(reply)) {
// 登陆到ftp服务器
if (ftpClient.login(ftpVo.getUsername(), ftpVo.getPassword())) {
setFileType(ftpClient);
return true;
}
} else {
ftpClient.disconnect();
throw new FTPClientException("FTP 连接服务失败");
}
} catch (IOException e) {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect(); // 断开连接
} catch (IOException e1) {
throw new FTPClientException("Could not disconnect from server.", e1);
}
}
throw new FTPClientException("FTP 服务连接异常", e);
}
return false;
}
public void disconnect() throws FTPClientException {
try {
FTPClient ftpClient = getFTPClient();
ftpClient.logout();
if (ftpClient.isConnected()) {
ftpClient.disconnect();
ftpClient = null;
}
} catch (IOException e) {
throw new FTPClientException("FTP 服务关闭异常", e);
}
}
/**
* 上传一个本地文件到远程指定文件
*
* @param remoteAbsoluteFile
* 远程文件名(包括完整路径)
* @param localAbsoluteFile
* 本地文件名(包括完整路径)
* @return 成功时,返回true,失败返回false
* @throws FTPClientException
*/
public boolean put(String remoteAbsoluteFile, String localAbsoluteFile) throws FTPClientException {
return put(remoteAbsoluteFile, localAbsoluteFile, true);
}
/**
* 上传一个本地文件到远程指定文件
*
* @param remoteAbsoluteFile
* 远程文件名(包括完整路径)
* @param localAbsoluteFile
* 本地文件名(包括完整路径)
* @return 成功时,返回true,失败返回false
* @throws FTPClientException
*/
public boolean put(String remoteAbsoluteFile, InputStream localAbsoluteFile) throws FTPClientException {
return put(remoteAbsoluteFile, localAbsoluteFile, true);
}
/**
* 上传一个本地文件到远程指定文件
*
* @param remoteAbsoluteFile
* 远程文件名(包括完整路径)
* @param localAbsoluteFile
* 本地文件名(包括完整路径)
* @param autoClose
* 是否自动关闭当前连接
* @return 成功时,返回true,失败返回false
* @throws FTPClientException
*/
public boolean put(String remoteAbsoluteFile, String localAbsoluteFile, boolean autoClose)
throws FTPClientException {
InputStream input = null;
try {
boolean filemk = false;
// 截取远程路径最后一个/
int fnum = remoteAbsoluteFile.lastIndexOf("/");
String folderPath = remoteAbsoluteFile.substring(0, fnum);
System.out.println(folderPath);
// 根据截取的字段判断路径是否存在
boolean falg = getFTPClient().changeWorkingDirectory(folderPath);
// false为路径不存在调用CeateDirecroty创建文件夹
if (falg == false) {
// 创建文件夹
CreateDirecroty(folderPath, "");
}
// 检查文件是否正确
filemk = getFTPClient().changeWorkingDirectory("/" + folderPath);
if (filemk == true) {
// 处理传输
input = new FileInputStream(localAbsoluteFile);
// 上传 如果返回false 注意上传模式 二进制还是文本
boolean b = getFTPClient().storeFile(remoteAbsoluteFile, input);
// 删除本地文件
File file = new File(localAbsoluteFile);
// 如果判断是文件夹不操作
if (!file.isDirectory()) {
if (file.isFile()) {
// 关闭文件流避免删除失败
DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));
dos.close();
boolean f = file.delete();
if (f = false) {
throw new FTPClientException("delete error file:" + localAbsoluteFile);
}
}
}
System.out.println(b);
} else {
return false;
}
return true;
} catch (FileNotFoundException e) {
throw new FTPClientException("local file not found.", e);
} catch (IOException e) {
throw new FTPClientException("Could not put file to server.", e);
} finally {
try {
if (input != null) {
input.close();
}
} catch (Exception e) {
throw new FTPClientException("Couldn't close FileInputStream.", e);
}
if (autoClose) {
disconnect(); // 断开连接
}
}
}
/**
* 上传一个本地文件到远程指定文件
*
* @param remoteAbsoluteFile
* 远程文件名(包括完整路径)
* @param localAbsoluteFile
* 本地文件名(包括完整路径)
* @param autoClose
* 是否自动关闭当前连接
* @return 成功时,返回true,失败返回false
* @throws FTPClientException
*/
public boolean put(String remoteAbsoluteFile, InputStream localAbsoluteFile, boolean autoClose)
throws FTPClientException {
InputStream input = null;
try {
boolean filemk = false;
// 截取远程路径最后一个/
int fnum = remoteAbsoluteFile.lastIndexOf("/");
String folderPath = remoteAbsoluteFile.substring(0, fnum);
System.out.println(folderPath);
// 根据截取的字段判断路径是否存在
boolean falg = getFTPClient().changeWorkingDirectory(folderPath);
// false为路径不存在调用CeateDirecroty创建文件夹
if (falg == false) {
// 创建文件夹
CreateDirecroty(folderPath, "");
}
// 检查文件是否正确
filemk = getFTPClient().changeWorkingDirectory("/" + folderPath);
if (filemk == true) {
// 处理传输
if (localAbsoluteFile != null) {
input = localAbsoluteFile;
// 上传 如果返回false 注意上传模式 二进制还是文本
boolean b = getFTPClient().storeFile(remoteAbsoluteFile, input);
if (b = false) {
throw new FTPClientException("update error file:" + remoteAbsoluteFile);
}
} else {
throw new FTPClientException("上传文件流为空" + localAbsoluteFile);
}
} else {
return false;
}
return true;
} catch (FileNotFoundException e) {
throw new FTPClientException("local file not found.", e);
} catch (IOException e) {
throw new FTPClientException("Could not put file to server.", e);
} finally {
try {
if (input != null) {
input.close();
}
} catch (Exception e) {
throw new FTPClientException("Couldn't close FileInputStream.", e);
}
if (autoClose) {
disconnect(); // 断开连接
}
}
}
/**
* 创建文件夹
*
* @param remotePath
* //需要创建文件夹的路径
* @param pwdstr
* //创建后的路径 主要用于进入路径
* @return
*/
public boolean CreateDirecroty(String remotePath, String pwdstr) throws FTPClientException {
try {
// FTP根目录
String nofile = ftppath;
if (remotePath == null || "".equals(remotePath)) {
return true;
}
int startnum = remotePath.indexOf("/");
String crpath = "";
String endpath = "";
if (startnum > 0) {
crpath = remotePath.substring(0, startnum);
endpath = remotePath.substring(startnum, remotePath.length());
} else if (startnum == 0) {
remotePath = remotePath.substring(1, remotePath.length());
startnum = remotePath.indexOf("/");
crpath = remotePath.substring(0, startnum);
endpath = remotePath.substring(startnum, remotePath.length());
} else {
crpath = remotePath;
}
pwdstr = pwdstr + "/" + crpath;
// 检查文件夹是否存在
boolean falg = getFTPClient().changeWorkingDirectory(pwdstr);
// 不存在创建文件夹进入 存在直接进入
if (falg == false) {
getFTPClient().makeDirectory(crpath);
getFTPClient().changeWorkingDirectory(pwdstr);
} else {
getFTPClient().changeWorkingDirectory(pwdstr);
}
// endpath的长度=0表示需要创建的文件夹没有了
if (endpath.length() == 0) {
return true;
} else {
// 减1去掉/线
endpath = endpath.substring(1, endpath.length());
// 递归
CreateDirecroty(endpath, pwdstr);
}
} catch (Exception e) {
e.printStackTrace();
throw new FTPClientException("Ftp 创建文件夹失败", e);
} finally {
try {
if (true) {
// 创建完后关闭连接
disconnect(); // 断开连接
}
} catch (Exception e) {
e.printStackTrace();
}
}
return true;
}
/**
* 下载一个远程文件到本地的指定文件
*
* @param remoteAbsoluteFile
* 远程文件名(包括完整路径)
* @param localAbsoluteFile
* 本地文件名(包括完整路径)
* @return 成功时,返回true,失败返回false
* @throws FTPClientException
*/
public boolean get(String remoteAbsoluteFile, String localAbsoluteFile) throws FTPClientException {
return get(remoteAbsoluteFile, localAbsoluteFile, true);
}
/**
* 下载一个远程文件到本地的指定文件
*
* @param remoteAbsoluteFile
* 远程文件名(包括完整路径)
* @param localAbsoluteFile
* 本地文件名(包括完整路径)
* @param autoClose
* 是否自动关闭当前连接
*
* @return 成功时,返回true,失败返回false
* @throws FTPClientException
*/
public boolean get(String remoteAbsoluteFile, String localAbsoluteFile, boolean autoClose)
throws FTPClientException {
OutputStream output = null;
try {
output = new FileOutputStream(localAbsoluteFile);
return get(remoteAbsoluteFile, output, autoClose);
} catch (FileNotFoundException e) {
throw new FTPClientException("local file not found.", e);
} finally {
try {
if (output != null) {
output.close();
}
} catch (IOException e) {
throw new FTPClientException("Couldn't close FileOutputStream.", e);
}
}
}
/**
* 下载一个远程文件到指定的流 处理完后记得关闭流
*
* @param remoteAbsoluteFile
* @param output
* @return
* @throws FTPClientException
*/
public boolean get(String remoteAbsoluteFile, OutputStream output) throws FTPClientException {
return get(remoteAbsoluteFile, output, true);
}
/**
* 下载一个远程文件到指定的流 处理完后记得关闭流
*
* @param remoteAbsoluteFile
* @param output
* @return
* @throws FTPClientException
*/
public boolean get(String remoteAbsoluteFile, OutputStream output, boolean autoClose) throws FTPClientException {
try {
FTPClient ftpClient = getFTPClient();
// 处理传输
return ftpClient.retrieveFile(remoteAbsoluteFile, output);
} catch (IOException e) {
throw new FTPClientException("Couldn't get file from server.", e);
} finally {
if (autoClose) {
disconnect(); // 关闭链接
}
}
}
/**
* 从ftp服务器上删除一个文件
*
* @param delFile
* @param autoClose
* 是否自动关闭当前连接
*
* @return
* @throws FTPClientException
*/
public boolean delete(String delFile, boolean autoClose) throws FTPClientException {
try {
getFTPClient().deleteFile(delFile);
return true;
} catch (IOException e) {
throw new FTPClientException("Couldn't delete file from server.", e);
} finally {
if (autoClose) {
disconnect(); // 关闭链接
}
}
}
/**
* 批量删除 该方法将自动关闭当前连接
*
* @param delFiles
* @return
* @throws FTPClientException
*/
public boolean delete(String[] delFiles) throws FTPClientException {
return delete(delFiles, true);
}
/**
* 批量删除
*
* @param delFiles
* @param autoClose
* 是否自动关闭当前连接
*
* @return
* @throws FTPClientException
*/
public boolean delete(String[] delFiles, boolean autoClose) throws FTPClientException {
try {
FTPClient ftpClient = getFTPClient();
for (String s : delFiles) {
ftpClient.deleteFile(s);
}
return true;
} catch (IOException e) {
throw new FTPClientException("Couldn't delete file from server.", e);
} finally {
if (autoClose) {
disconnect(); // 关闭链接
}
}
}
/**
* 列出远程默认目录下所有的文件
*
* @return 远程默认目录下所有文件名的列表,目录不存在或者目录下没有文件时返回0长度的数组
* @throws FTPClientException
*/
public String[] listNames() throws FTPClientException {
return listNames(null, true);
}
public String[] listNames(boolean autoClose) throws FTPClientException {
return listNames(null, autoClose);
}
/**
* 列出远程目录下所有的文件
*
* @param remotePath
* 远程目录名
* @param autoClose
* 是否自动关闭当前连接
*
* @return 远程目录下所有文件名的列表,目录不存在或者目录下没有文件时返回0长度的数组
* @throws FTPClientException
*/
public String[] listNames(String remotePath, boolean autoClose) throws FTPClientException {
try {
String[] listNames = getFTPClient().listNames(remotePath);
return listNames;
} catch (IOException e) {
throw new FTPClientException("列出远程目录下所有的文件时出现异常", e);
} finally {
if (autoClose) {
disconnect(); // 关闭链接
}
}
}
}
FTPUload.java
package com.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import com.entity.FtpVo;
import com.main.UploadServer;
public class FTPUload {
protected final Logger log = Logger.getLogger(this.getClass());
private static final String ftpip = PropertiesUtil.get("ftpip");
private static final String ftpuser = PropertiesUtil.get("ftpname");
private static final String ftppass = PropertiesUtil.get("ftppassword");
private static final String ftpprot = PropertiesUtil.get("ftpprot");
private static final String ftppath = PropertiesUtil.get("ftppath");
public static void main(String[] args) throws FTPClientException, InterruptedException, Exception {
FtpVo ftp = new FtpVo();
ftp.setHost("192.168.1.11");
ftp.setPort(21);
ftp.setUsername("testftp");
ftp.setPassword("123456");
ftp.setBinaryTransfer(true);
ftp.setPassiveMode(true);
ftp.setEncoding("utf-8");
FtpConnect ftpConnect = new FtpConnect(ftp);
// ftpConnect.ftpUpload("D:\\文档\\123456789.xlsx".replace("\\","/"),"execl");
// ftp.deleteFile("http://192.168.1.11:8060/app_store/2016/12/14/16/47/01/1481705221029.jpg","app_store");
}
/**
* 从ftp服务器上删除一个文件 该方法将自动关闭当前连接
*
* @param delFile
* @return
* @throws FTPClientException
*/
public boolean deleteFile(String delFile, String projectName) throws FTPClientException {
boolean falg = false;
try {
String rmpath = ftppath;
int indexnum = delFile.indexOf(projectName);
String locapath = "";
if (indexnum >= 0) {
locapath = rmpath + delFile.substring(indexnum, delFile.length());
} else {
throw new FTPClientException("项目文件夹名称不存在" + projectName);
}
locapath = locapath.replace("\\", "/");
List<FtpVo> list = getFtpUload();
for (int i = 0; i < list.size(); i++) {
FtpConnect ftpConnect = new FtpConnect(list.get(i));
falg = ftpConnect.delete(locapath, true);
if (falg == false) {
throw new FTPClientException("FTP删除失败 文件地址" + locapath);
}
}
} catch (Exception e) {
falg = false;
throw new FTPClientException("删除异常", e);
}
return falg;
}
public boolean ftpUpload(String local) throws FTPClientException {
boolean ret = true;
try {
List<FtpVo> list = getFtpUload();
for (int i = 0; i < list.size(); i++) {
if (list.get(i) == null) {
throw new FTPClientException("读取ftp配置文件失败 ip:" + list.get(i).getHost());
}
FtpConnect ftpConnect = new FtpConnect(list.get(i));
ftpConnect.getFTPClient();
String rmpath = ftppath;
String locapath = local;
String substr = System.getProperty("user.dir").replace("\\", "/") + "/";
locapath = locapath.replace("\\", "/").replaceAll("//", "/");
int numc = locapath.indexOf(substr);
if (numc >= 0) {
rmpath = rmpath + locapath.substring(numc + substr.length(), locapath.length());
} else {
System.out.println(numc + ":" + substr + ":" + locapath);
throw new FTPClientException("error:路径截取为空");
}
System.out.println(rmpath);
ret = ftpConnect.put(rmpath, locapath);
}
} catch (FTPClientException e) {
throw new FTPClientException("FTP上传失败", e);
}
return ret;
}
public boolean ftpUpload(InputStream local, String filename) throws FTPClientException {
boolean ret = true;
try {
List<FtpVo> list = getFtpUload();
for (int i = 0; i < list.size(); i++) {
if (list.get(i) == null) {
throw new FTPClientException("读取ftp配置文件失败 ip:" + list.get(i).getHost());
}
FtpConnect ftpConnect = new FtpConnect(list.get(i));
ftpConnect.getFTPClient();
// String rmpath=ftppath;
// String locapath=filename;
// String
// substr=System.getProperty("user.dir").replace("\\","/")+"/";
// locapath=locapath.replace("\\","/").replaceAll("//","/");
// int numc=locapath.indexOf(substr);
// if(numc>=0){
// rmpath=rmpath+locapath.substring(numc+substr.length(),locapath.length());
// }else{
// System.out.println(numc+":"+substr+":"+locapath);
// throw new FTPClientException("error:路径截取为空");
//// }
// System.out.println(rmpath);
ret = ftpConnect.put(filename, local);
}
} catch (FTPClientException e) {
e.printStackTrace();
throw new FTPClientException("FTP上传失败", e);
}
return ret;
}
public String ftpUpload(String local, String projectName) throws FTPClientException {
String rpath = "";
try {
List<FtpVo> list = getFtpUload();
for (int i = 0; i < list.size(); i++) {
FtpConnect ftpConnect = new FtpConnect(list.get(i));
String rmpath = ftppath;
int num = local.lastIndexOf("/");
int leg = local.length();
if (num > 0 && num != leg) {
rmpath = rmpath + projectName + "/" + local.substring(num, leg);
} else {
throw new FTPClientException("地址不正确" + local);
}
boolean ret = ftpConnect.put(rmpath, local);
if (ret == false) {
rpath = ProperManagerFTP.getString("webpath") + "/error.jpg";
log.debug("FTP upload fail for FTP ip:" + list.get(i).getHost());
} else {
rpath = ProperManagerFTP.getString("webpath") + "/" + projectName + "/" + local.substring(num, leg);
}
}
} catch (FTPClientException e) {
throw new FTPClientException("FTP上传失败", e);
}
return rpath;
}
public String ftpUploadFile(File file, String projectName) throws FTPClientException {
String rpath = "";
try {
List<FtpVo> list = getFtpUload();
for (int i = 0; i < list.size(); i++) {
FtpConnect ftpConnect = new FtpConnect(list.get(i));
String rmpath = ftppath;
String webpath = DateUtil.getFilePath();
String extName = UploadServer.getFileExtName(file.getName());
String fileName = System.currentTimeMillis() + "." + extName;
rmpath = rmpath + "/" + projectName + "/" + webpath + "/" + fileName;
InputStream inputStream = new FileInputStream(file);
boolean ret = ftpConnect.put(rmpath, inputStream);
if (ret == false) {
rpath = ProperManagerFTP.getString("webpath") + "/error.jpg";
log.debug("FTP upload fail for FTP ip:" + list.get(i).getHost());
} else {
rpath = ProperManagerFTP.getString("webpath") + "/" + projectName + "/" + webpath + "/" + fileName;
}
}
} catch (FTPClientException e) {
throw new FTPClientException("FTP上传失败", e);
} catch (FileNotFoundException ex) {
throw new FTPClientException("文件流不存在", ex);
}
return rpath;
}
/**
* 读取FTP配置文件信息
*
* @return
* @throws FTPClientException
*/
public List<FtpVo> getFtpUload() throws FTPClientException {
List<FtpVo> list = new ArrayList<FtpVo>();
try {
// 判断ip是否有多个
String[][][] ftplog;
String[] ip = ftpip.split(",");
// 多个FTP连接
if (ip.length > 1) {
ftplog = new String[ip.length][ip.length][ip.length];
for (int i = 0; i < ip.length; i++) {
ftplog[i][0][0] = ip[i];
}
String[] username = ftpuser.split(",");
// 当用户分割的数组长度有多个并且和ip长度一样,则一一对应否则默认为第一个
if (username.length > 1 && username.length == ip.length) {
for (int i = 0; i < ip.length; i++) {
ftplog[i][1][1] = username[i];
}
} else {
for (int i = 0; i < ip.length; i++) {
ftplog[i][1][1] = username[0];
}
}
String[] password = ftppass.split(",");
// 当用户分割的数组长度有多个并且和ip长度一样,则一一对应否则默认为第一个
if (password.length > 1 && password.length == ip.length) {
for (int i = 0; i < ip.length; i++) {
ftplog[i][2][2] = password[i];
}
} else {
for (int i = 0; i < ip.length; i++) {
ftplog[i][2][2] = password[0];
}
}
for (int i = 0; i < ftplog.length; i++) {
FtpVo ftp = new FtpVo();
ftp.setHost(ftplog[i][0][0]);
ftp.setPort(Integer.parseInt(ftpprot));
ftp.setUsername(ftplog[i][1][1]);
ftp.setPassword(ftplog[i][2][2]);
ftp.setBinaryTransfer(true);
ftp.setPassiveMode(true);
ftp.setEncoding("utf-8");
list.add(ftp);
}
} else {
// 一个FTP连接
FtpVo ftp = new FtpVo();
ftp.setHost(ftpip);
ftp.setPort(Integer.parseInt(ftpprot));
ftp.setUsername(ftpuser);
ftp.setPassword(ftppass);
// 文件上传模式
ftp.setBinaryTransfer(true);
ftp.setPassiveMode(true);
ftp.setEncoding("utf-8");
list.add(ftp);
}
} catch (Exception e) {
throw new FTPClientException("FTP 连接读取配置错误");
}
return list;
}
}
GlobalVars.java
package com.util;
public class GlobalVars {
// ************************************配置文件读取***********************//
public static String WEBPATH = PropertiesUtil.get("webpath");
/**
* 应用管理
*/
public static String APP_MANAGE_API = "app_manage/api";
public static String APP_MANAGE_WEB = "app_manage/web";
}
ProperManagerFTP.java
package com.util;
import java.util.MissingResourceException;
public class ProperManagerFTP {
public static String getString(String key) {
try {
return PropertiesUtil.get(key);
} catch (MissingResourceException e) {
throw new RuntimeException("! config : " + key + '!');
}
}
}
PropertiesUtil.java
package com.util;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
public class PropertiesUtil extends PropertyPlaceholderConfigurer {
private static Map<String, Object> ctxPropertiesMap;
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props)
throws BeansException {
super.processProperties(beanFactoryToProcess, props);
ctxPropertiesMap = new HashMap<String, Object>();
for (Object key : props.keySet()) {
String keyStr = key.toString();
String value = props.getProperty(keyStr);
ctxPropertiesMap.put(keyStr, value);
}
}
public static Object getContextProperty(String name) {
return ctxPropertiesMap.get(name);
}
/**
* 根据key读取对应的value
*
* @param key
* @return
*/
public static String get(String key) {
return (String) ctxPropertiesMap.get(key);
}
}
pom.xml
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<artifactId>dc-upload</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>com.xxl.dc</groupId>
<artifactId>dc-parent</artifactId>
<version>1.0.3</version><!--$NO-MVN-MAN-VER$ -->
<relativePath>../dc-parent/</relativePath>
</parent>
<properties>
<maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
</dependencies>
<build>
<finalName>dc-upload</finalName>
<plugins>
<!-- define the project compile level -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version><!--$NO-MVN-MAN-VER$ -->
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
2、实际接口:
package com.xxl.dc.upload;
import java.io.IOException;
import java.util.Iterator;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import com.main.UploadServer;
import com.xxl.dc.common.util.CommonConsts;
@Controller
@RequestMapping(CommonConsts.API_DC)
public class UploadController {
private static final Logger logger = Logger.getLogger(UploadController.class.getName());
@RequestMapping(value = "/fileUpload")
public void upload(HttpServletRequest request, HttpServletResponse respones) {
// 解析器解析request的上下文
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
request.getSession().getServletContext());
// 保存图片文件名
String path = "";
// 先判断request中是否包涵multipart类型的数据,
if (multipartResolver.isMultipart(request)) {
// 再将request中的数据转化成multipart类型的数据
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
Iterator iter = multiRequest.getFileNames();
while (iter.hasNext()) {
// 这里的name为fileItem的alias属性值,相当于form表单中name
String name = (String) iter.next();
// 根据name值拿取文件
MultipartFile file = multiRequest.getFile(name);
if (null != file) {
path = UploadServer.getUploadPathInputSteam(file, "app_store");
}
}
}
try {
// 指定允许其他域名访问
respones.setHeader("Access-Control-Allow-Origin", "*");
// 响应类型
respones.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
// 响应头设置
respones.setHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with, X-Custom-Header");
respones.getWriter().write(path);
} catch (IOException e) {
logger.error(e);
}
}
}
配置文件如下所示:
同时还需要在你的springmvc.xml配置文件中配置如下:
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="314572800" />
<property name="maxInMemorySize" value="40960000" />
</bean>
<bean id="propertyConfigurer" class="com.util.PropertiesUtil">
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>classpath:config.properties</value>
</list>
</property>
</bean>
3、效果演示
在浏览器中上传图片,返回的结果为一个图片的地址。
至于为什么在浏览器访问http://192.168.10.101:8066/marketdatas/images/a81edfddb83047cc8b0d7198c4ae6a22.png时,能看到这张图片,是因为8066是配置的一个nginx服务器。
而图片上传后保存的地址为:所以就能直接下载到该文件了。