思路
1.首先連接ftp服務器
2.連接到服務器之後如何上傳文件
3.上傳後如何獲取文件
4.文件格式是圖片如何展示到客戶端瀏覽器
5.服務端代碼如何接收客戶端的文件以及如何返回響應信息給瀏覽器
主要jar包依賴文件
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
<!-- jsch 所依賴的jar包 -->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jzlib</artifactId>
<version>1.1.1</version>
</dependency>
public class SftpUtils {
private static final Logger log = LoggerFactory.getLogger(SftpUtils.class);
private static ChannelSftp sftp;
public static Properties properties = LoadProperties.getProperties("/config/sftp.properties");
private static Channel channel;
private static Session sshSession;
/**
* 登陸SFTP服務器
* @return
*/
public static boolean getConnect() throws Exception{
log.info("進入SFTP====");
boolean result = false;
JSch jsch = new JSch();
//獲取sshSession 賬號-ip-端口,從properties文件中獲取連接ftp服務器的相關信息
sshSession =jsch.getSession(properties.getProperty("user"), properties.getProperty("ip"), Integer.parseInt(properties.getProperty("port")));
//添加密碼
sshSession.setPassword(properties.getProperty("password"));
Properties sshConfig = new Properties();
//嚴格主機密鑰檢查
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
//開啓sshSession鏈接
sshSession.connect();
//獲取sftp通道
channel = sshSession.openChannel("sftp");
//開啓
channel.connect();
sftp = (ChannelSftp) channel;
result = true;
return result;
}
/**
* 文件上傳
* @param inputStream 上傳的文件輸入流
* @param fileCategory 存儲文件目錄分類
* @return
*/
public static String upload(InputStream inputStream, String fileCategory, String fileName) throws Exception{
String destinationPath = properties.getProperty("destinationPath")+fileCategory;
try {
sftp.cd(destinationPath);
//獲取隨機文件名
fileName = UUID.randomUUID().toString().replace("-", "") + fileName;
//文件名是 隨機數加文件名的後5位
sftp.put(inputStream, fileName);
}finally {
sftp.disconnect();
}
return fileName;
}
/**
* 下載文件
*
* @param downloadFilePath 下載的文件完整目錄
* @param saveFile 保存在本地的文件路徑
* @return 返回的是文件
*/
public static File download(String downloadFilePath, String saveFile) {
FileOutputStream fileOutputStream = null;
try {
int i = downloadFilePath.lastIndexOf('/');
if (i == -1)
return null;
sftp.cd(downloadFilePath.substring(0, i));
File file = new File(saveFile);
fileOutputStream = new FileOutputStream(file);
sftp.get(downloadFilePath.substring(i + 1), fileOutputStream);
return file;
} catch (Exception e) {
log.error(e.getMessage());
return null;
}finally {
sftp.disconnect();
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 獲取ftp服務器 (圖片)文件流
* @param downloadFilePath ftp文件上的文件全路徑,包括具體文件名 a/b/c.png
* @return 返回的是文件流
*/
public static InputStream download(String downloadFilePath) {
int i = downloadFilePath.lastIndexOf('/');
InputStream inputStream = null;
if (i == -1)
return null;
try {
sftp.cd(downloadFilePath.substring(0, i));
inputStream = sftp.get(downloadFilePath.substring(i + 1));
} catch (SftpException e) {
log.error("獲取ftp服務文件流發生異常!");
e.printStackTrace();
}
return inputStream;
}
/* * 斷開SFTP Channel、Session連接
* @throws Exception
*
*/
public static void disconnect() {
if (SftpUtils.sftp != null) {
if (sftp.isConnected()) {
sftp.disconnect();
log.info("sftp is closed already");
}
}
if (SftpUtils.sshSession != null) {
if (SftpUtils.sshSession.isConnected()) {
SftpUtils.sshSession.disconnect();
log.info("sshSession is closed already");
}
}
}
/**
* 文件流轉爲base64字節碼
* @param in
* @return
*/
public static String inputStreamtoBase64(InputStream in) throws Exception{
byte[] bytes = IOUtils.toByteArray(in);
String base64str = Base64.getEncoder().encodeToString(bytes);
return base64str;
}
/** 刪除sftp文件
* @param directPath 需要刪除的文件目錄
* @param fileName 需要刪除的文件
* @return
**/
public static void deleteFile(String directPath, String fileName) throws Exception{
//進入需要刪除的文件目錄下
sftp.cd(directPath);
sftp.rm(fileName);
}
/**
* 列出某目錄下的文件名
* @param directory 需要列出的文件目錄(sftp服務器目錄下的)
* @return List<String> 返回的文件名列表
* @throws Exception
*/
public static List<String> listFiles(String directory) throws Exception {
Vector fileList;
List<String> fileNameList = new ArrayList<String>();
fileList = sftp.ls(directory);
Iterator it = fileList.iterator();
while(it.hasNext())
{
String fileName = ((LsEntry)it.next()).getFilename();
if(".".equals(fileName) || "..".equals(fileName)){
continue;
}
fileNameList.add(fileName);
}
return fileNameList;
}
總結:上面是一個ftp工具類,包括ftp連接,文件上傳,文件下載,ftp服務硬盤目錄下的文件查詢
二,服務端後臺代碼
/**
* 上傳文件
* @param multipartFile 客戶端上傳的文件
* @param request
* @param response
* @return
*/
@PostMapping("uploadFile")
@ResponseBody
public String uploadFile(@RequestParam("multipartFile") MultipartFile multipartFile, HttpServletRequest request, HttpServletResponse response) {
//連接sftp服務
String fileName = null;
try {
SftpUtils.getConnect();
//上傳的文件所屬類型 banner, mobile, pc, share四種
//如果未明確默認存放在ftp服務器的share文件目錄下
String fileCategory = request.getParameter("fileCategory")== null ? "share" : request.getParameter("fileCategory");
//上傳的文件名
fileName = multipartFile.getOriginalFilename();
int index = fileName.lastIndexOf(".");
String nameSuffix = fileName.substring(index, fileName.length());
//禁止上傳.exe文件
if(".exe".equalsIgnoreCase(nameSuffix)) {
return renderResult(Global.FALSE, text("上傳的文件格式不支持!"));
}
InputStream inputStream = multipartFile.getInputStream();
String filePath = SftpUtils.upload(inputStream, fileCategory, fileName);
SftpUtils.disconnect();
//需要保存到數據庫的文件名稱
fileName = fileCategory+"/"+filePath;
} catch (Exception e) {
e.printStackTrace();
logger.error("文件上傳過程中發生異常!");
return renderResult(Global.FALSE, text("上傳失敗!"));
}
return renderResult(Global.TRUE, text(fileName));
}
/**
* 下載文件
* @param request
* @param response
* @return
*/
@RequestMapping("downLoad")
@ResponseBody
public Map<String, String> downLoad(HttpServletRequest request, HttpServletResponse response) {
Map<String, String> paraMap = new HashMap<String, String>();
paraMap.put("result", "true");
paraMap.put("msg", "文件下載成功");
//獲取需要下載的文件名稱
//正式情況下是從表中獲取,文件格式,文件名稱,存入數據庫中
//測試某文件名稱
String fileName = "share/eae3b1a4a6fe4bb48af11381add03c59textJGY.jpg";
//判斷需要下載的文件是否是圖片格式,如果是圖片則傳Base64格式給瀏覽器
String fileType = "jpg";
String oldName = "JGY.jpg";
String [] imagesTypes = {"jpg", "JPG", "png", "PNG", "bmp", "BMP", "gif", "GIF"};
boolean flag = false;
for (int i = 0; i < imagesTypes.length; i++) {
if(fileType.equalsIgnoreCase(imagesTypes[i])) {
flag = true;
break;
}
}
try {
SftpUtils.getConnect();
} catch (Exception ftpexp) {
logger.error("ftp連接時發生異常!");
ftpexp.printStackTrace();
paraMap.put("result", "false");
paraMap.put("msg", "ftp連接時發生異常!");
return paraMap;
}
//獲取properties文件中ftp服務器存放的路徑
String direct = SftpUtils.properties.getProperty("destinationPath");
//獲取下載文件的文件流
String downloadFilePath = direct+fileName;
InputStream inputStream = SftpUtils.download(downloadFilePath);
//圖片轉爲base64
if(flag) {
try {
//文件流轉爲base64
String base64String = SftpUtils.inputStreamtoBase64(inputStream);
paraMap.put("base64", base64String);
} catch (Exception e) {
logger.error("文件下載出現異常!");
e.printStackTrace();
paraMap.put("result", "false");
paraMap.put("msg", "文件下載失敗!");
return paraMap;
}
//非圖片文件就直接瀏覽器下載
} else {
String agent = request.getHeader("user-agent");
try {
if(StringUtils.contains(agent, "MSIE")||StringUtils.contains(agent,"Trident")){//IE瀏覽器
oldName = URLEncoder.encode(oldName,"UTF8");
System.out.println("IE瀏覽器");
}else if(StringUtils.contains(agent, "Mozilla")) {//google,火狐瀏覽器
oldName = new String(oldName.getBytes(), "ISO8859-1");
}else {
oldName = URLEncoder.encode(oldName,"UTF8");//其他瀏覽器
}
response.reset();//重置 響應頭
response.setContentType("application/x-download");//告知瀏覽器下載文件,而不是直接打開,瀏覽器默認爲打開
response.addHeader("Content-Disposition" ,"attachment;filename=\"" +oldName+ "\"");//下載文件的名稱
byte[] b = new byte[1024];
int len;
while((len = inputStream.read(b)) > 0) {
response.getOutputStream().write(b, 0, len);;
}
}catch (Exception e) {
e.printStackTrace();
paraMap.put("result", "false");
paraMap.put("msg", "文件下載失敗!");
return paraMap;
}finally {
try {
response.getOutputStream().close();
} catch (IOException e) {
logger.error("文件輸出流關閉發生異常!");
e.printStackTrace();
}
SftpUtils.disconnect();
}
}
return paraMap;
}