1. 程式人生 > >spring boot將MultipartFile file圖片上傳到遠端伺服器;

spring boot將MultipartFile file圖片上傳到遠端伺服器;

1.controller

@Api(description = "圖片上傳介面")
@RestController
@RequestMapping("/uploadController")
public class UploadController {
	
	@ApiOperation(value = "上傳圖片")
	@RequestMapping(value="/uploadPic",method=RequestMethod.POST)
 	public String saveHeaderPic(@RequestParam("file") MultipartFile file) throws Exception { 
 		// 檔案儲存路徑 
 		String filePath = ""; //對映的地址

 		String filename = file.getOriginalFilename();//獲取file圖片名稱
		String uploadFile = FtpUtils.uploadFile(filePath, file.getBytes(), UUID.randomUUID().toString().replaceAll("-", "") + ".jpg");
		return uploadFile;
 	}

2.工具類


import java.io.ByteArrayInputStream;
import java.io.IOException;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

public class FtpUtils {

	/**
	 * 屬性集
	 */
	private static Property property = null;

	/**
	 * FTP 登入使用者名稱
	 */
	private static String userName;

	/**
	 * FTP 登入密碼
	 */
	private static String passWord;

	/**
	 * FTP 伺服器地址IP地址
	 */
	private static String hostName;

	/**
	 * FTP 埠
	 */
	private static int port;

	/**
	 * 檔案伺服器路徑
	 */
	private static String path;

	/**
	 * 檔案伺服器訪問地址
	 */
	private static String header;

	/**
	 * 配置檔案的路徑名
	 */
	private static String configFile = "application.properties";
	/**
	 * ftp檔案下載的地址,例如:模板
	 */
	private static String tmstctpFilePath;

	/**
	 * 關閉連線-FTP方式
	 *
	 * @param ftp
	 *            FTPClient物件
	 * @return boolean
	 */
	public static boolean closeFTP(FTPClient ftp) {
		if (ftp.isConnected()) {
			try {
				ftp.disconnect();
				System.out.println("ftp已經關閉");
				return true;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return false;
	}

	/**
	 * 上傳檔案-FTP方式
	 *
	 * @param hostName
	 *            FTP伺服器地址
	 * @param port
	 *            FTP伺服器埠
	 * @param userName
	 *            FTP登入使用者名稱
	 * @param passWord
	 *            FTP登入密碼
	 * @param path
	 *            FTP伺服器上傳地址
	 * @param fileName
	 *            檔名稱
	 * @param inputStream
	 *            輸入流
	 * @return boolean
	 * @throws Exception
	 */
	public static String uploadFile(String partPath, byte[] decoderBytes,String imgName) throws Exception {
		FTPClient ftp = new FTPClient();
		try {
			setArg(configFile);
			// 連線FTP伺服器
			ftp.connect(hostName, port);
			// 下面三行程式碼必須要,而且不能改變編碼格式,否則不能正確下載中文檔案
			ftp.setControlEncoding("GBK");
			FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
			conf.setServerLanguageCode("zh");
			// 登入ftp
			ftp.login(userName, passWord);
			if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
				ftp.disconnect();
				System.out.println("連線伺服器失敗");
			}
			System.out.println("登陸伺服器成功");
			String realPath = path + "/" + partPath;
			boolean changeWD = ftp.changeWorkingDirectory(realPath);// 轉移到指定FTP伺服器目錄
			if (!changeWD) {
				if (!CreateDirecroty(realPath, ftp)) {
					throw new Exception("建立遠端資料夾失敗!");
				}
			}
			FTPFile[] fs = ftp.listFiles();// 得到目錄的相應檔案列表
			String fileName = imgName;
			fileName = FtpUtils.changeName(fileName, fs);
			fileName = new String(fileName.getBytes("GBK"), "ISO-8859-1");
			realPath = new String(realPath.getBytes("GBK"), "ISO-8859-1");
			// 轉到指定上傳目錄
			ftp.changeWorkingDirectory(realPath);
			// 將上傳檔案儲存到指定目錄
			ftp.setFileType(FTP.BINARY_FILE_TYPE);
			// 如果預設該句 傳輸txt正常 但圖片和其他格式的檔案傳輸出現亂碼
			ftp.storeFile(fileName, new ByteArrayInputStream(decoderBytes));
			// 退出ftp
			ftp.logout();
			System.out.println("上傳成功。。。。。。");
			return header + realPath + fileName;
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			// 關閉ftp連線
			closeFTP(ftp);
		}
	}

	/**
	 * 判斷是否有重名檔案
	 *
	 * @param fileName
	 * @param fs
	 * @return
	 */
	public static boolean isFileExist(String fileName, FTPFile[] fs) {
		for (int i = 0; i < fs.length; i++) {
			FTPFile ff = fs[i];
			if (ff.getName().equals(fileName)) {
				return true; // 如果存在返回 正確訊號
			}
		}
		return false; // 如果不存在返回錯誤訊號
	}

	/**
	 * 根據重名判斷的結果 生成新的檔案的名稱
	 *
	 * @param fileName
	 * @param fs
	 * @return
	 */
	public static String changeName(String fileName, FTPFile[] fs) {
		int n = 0;
		// fileName = fileName.append(fileName);
		while (isFileExist(fileName.toString(), fs)) {
			n++;
			String a = "[" + n + "]";
			int b = fileName.lastIndexOf(".");// 最後一出現小數點的位置
			int c = fileName.lastIndexOf("[");// 最後一次"["出現的位置
			if (c < 0) {
				c = b;
			}
			StringBuffer name = new StringBuffer(fileName.substring(0, c));// 檔案的名字
			StringBuffer suffix = new StringBuffer(fileName.substring(b + 1));// 字尾的名稱
			fileName = name.append(a) + "." + suffix;
		}
		return fileName.toString();
	}

	/**
	 * 遞迴建立遠端伺服器目錄
	 *
	 * @param remote
	 *            遠端伺服器檔案絕對路徑
	 *
	 * @return 目錄建立是否成功
	 * @throws IOException
	 */
	public static boolean CreateDirecroty(String remote, FTPClient ftp) throws IOException {
		boolean success = true;
		String directory = remote.substring(0, remote.lastIndexOf("/") + 1);
		// 如果遠端目錄不存在,則遞迴建立遠端伺服器目錄
		if (!directory.equalsIgnoreCase("/") && !ftp.changeWorkingDirectory(new String(directory))) {

			int start = 0;
			int end = 0;
			if (directory.startsWith("/")) {
				start = 1;
			} else {
				start = 0;
			}
			end = directory.indexOf("/", start);
			while (true) {
				String subDirectory = new String(remote.substring(start, end));
				if (!ftp.changeWorkingDirectory(subDirectory)) {
					if (ftp.makeDirectory(subDirectory)) {
						ftp.changeWorkingDirectory(subDirectory);
					} else {
						System.out.println("建立目錄失敗");
						success = false;
						return success;
					}
				}
				start = end + 1;
				end = directory.indexOf("/", start);
				// 檢查所有目錄是否建立完畢
				if (end <= start) {
					break;
				}
			}
		}
		return success;
	}

	/**
	 * 
	 * @param configFile
	 */
	private static void setArg(String configFile) {
		property = new Property(configFile);
		try {
			userName = property.getValue("ciftpUserName");
			passWord = property.getValue("ciftpPassword");
			hostName = property.getValue("ciftpHost");
			path = property.getValue("ciftpPath");
			port = Integer.parseInt(property.getValue("ciftpPort"));
			header = property.getValue("ciftpHeader");
			tmstctpFilePath=property.getValue("tmstctpFilePath");
		} catch (Exception e1) {
			System.out.println("配置檔案 【" + configFile + "】不存在!");
			e1.printStackTrace();
		}
	}