Java實現(xiàn)上傳文件到服務器的示例代碼
更新時間:2024年04月23日 09:50:06 作者:abc_xian
這篇文章主要為大家詳細介紹了如何使用Java實現(xiàn)上傳文件到服務器,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
1、使用jsch
<!--sftp文件上傳--> <dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.55</version> </dependency>
2、配置類
package com.base.jsch; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @Data @Component @ConfigurationProperties(prefix = "sftp") public class SFTPConfig { /** * SFTP 服務器地址IP地址 */ @NotBlank(message = "IP地址不能為空") private String ip; /** * SFTP 端口 */ @NotNull(message = "端口不能為空") private int port; /** * SFTP 登錄用戶名 */ @NotBlank(message = "用戶名不能為空") private String username; /** * SFTP 登錄密碼 */ @NotBlank(message = "密碼不能為空") private String password; /** * SFTP 私鑰 */ private String privateKey; /** * 上傳失敗隔多長時間重新上傳 */ @NotNull(message = "上傳失敗重試間隔不能為空") private int uploadSleep; /** * 重新上傳的次數(shù) */ @NotNull(message = "重新上傳次數(shù)不能為空") private int uploadRetry; /** * 服務器路徑 */ @NotBlank(message = "服務器路徑不能為空") private String serverStorageDir; @NotNull(message = "文件名是否需要中文編碼") private Boolean isFileNameGBK; }
3、獲取連接
package com.base.jsch; import java.lang.reflect.Field; import java.util.Properties; import com.jcraft.jsch.*; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * SFTP工廠類,用于獲取SFTP的連接和關閉SFTP的連接 */ @Slf4j @Component public class SFTPConnection { @Autowired private SFTPConfig sftpConfig; private static ChannelSftp client; private static Session session; /** * 建立連接 * * @return client */ public synchronized ChannelSftp makeConnection() { if (client == null || session == null || !client.isConnected() || !session.isConnected()) { try { JSch jsch = new JSch(); if (sftpConfig.getPrivateKey() != null) { jsch.addIdentity(sftpConfig.getPrivateKey());// 設置私鑰 } session = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getIp(), sftpConfig.getPort()); if (sftpConfig.getPassword() != null) { session.setPassword(sftpConfig.getPassword()); } Properties config = new Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); session.connect(); client = (ChannelSftp)session.openChannel("sftp"); client.connect(); log.info("sftp服務器連接成功"); // 文件名中文亂碼 if(Boolean.TRUE.equals(sftpConfig.getIsFileNameGBK())){ try{ Class<ChannelSftp> cl = ChannelSftp.class; Field f1 =cl.getDeclaredField("server_version"); f1.setAccessible(true); f1.set(client, 2); client.setFilenameEncoding("gbk"); log.info("設置中文編碼"); }catch (NoSuchFieldException | SftpException | IllegalAccessException e) { log.error("設置中文編碼" + e.getMessage()); throw new RuntimeException(e); } } } catch (JSchException e) { log.error("主機sftp登錄失敗,檢測登錄ip,端口號,用戶名密碼是否正確,錯誤信息為" + e.getMessage()); } } return client; } /** * 關閉連接 */ public void logout() { if (client != null) { if (client.isConnected()) { client.disconnect(); } } if (session != null) { if (session.isConnected()) { session.disconnect(); } } } }
4、上傳工具類
package com.base.jsch; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.concurrent.TimeUnit; import com.jcraft.jsch.SftpATTRS; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.SftpException; /** * 工具類 */ @Slf4j @Component public class SFTPClientUtils { @Autowired private SFTPConfig sftpConfig; @Autowired private SFTPConnection sftpConnection; public synchronized boolean upload(InputStream fileIs, String fileName) { boolean result = false; int i = 0; while (!result) { log.info("*****開始登陸*****"); ChannelSftp sftp = sftpConnection.makeConnection(); if(null == sftp || !sftp.isConnected() || sftp.isClosed()){ log.info("連接無效"); return result; } log.info("******登陸成功*****"); try { sftp.cd(sftpConfig.getServerStorageDir()); } catch (SftpException e) { if(sftp.isConnected()){ log.info("sftp文件上傳,目錄不存在開始創(chuàng)建"); try { sftp.mkdir(sftpConfig.getServerStorageDir()); sftp.cd(sftpConfig.getServerStorageDir()); } catch (SftpException e1) { log.info("sftp文件上傳,目錄創(chuàng)建失敗,錯誤信息:" + e1.fillInStackTrace()); } }else{ log.info("sftp連接已經(jīng)失效"); return result; } } try { sftp.put(fileIs, fileName, new FileProgressMonitor(fileIs.available()), ChannelSftp.OVERWRITE); // 用下面的方法不會調(diào)用進度監(jiān)控 //sftp.put(fileIs, fileName); if (i > 0) { log.info("sftp重試文件上傳成功,ftp路徑:" + sftpConfig.getServerStorageDir() + ",文件名稱:" + fileName); } else { log.info("sftp文件上傳成功,ftp路徑為" + sftpConfig.getServerStorageDir() + ",文件名稱:" + fileName); } result = true; } catch (Exception e) { i++; log.error("sftp文件上傳失敗,重試中。。。第" + i + "次,錯誤信息" + e.fillInStackTrace()); if (i > sftpConfig.getUploadRetry()) { sftpConnection.logout(); log.error("sftp文件上傳失敗,超過重試次數(shù)結束重試,錯誤信息" + e.fillInStackTrace()); return result; } try { TimeUnit.MILLISECONDS.sleep(sftpConfig.getUploadSleep()); } catch (InterruptedException e1) { sftpConnection.logout(); e1.printStackTrace(); log.error("sftp文件上傳失敗,系統(tǒng)檢測出異常:" + e); } } } sftpConnection.logout(); log.info("sftp上傳:" + result); try { fileIs.close(); } catch (IOException e) { throw new RuntimeException(e); } return result; } public synchronized void download(String directory, String downloadFile, String localDir) { log.info("*****開始登陸*****"); ChannelSftp sftp = sftpConnection.makeConnection(); log.info("******登陸成功*****"); if (directory != null && !"".equals(directory)) { try { sftp.cd(directory); } catch (SftpException e) { log.error("sftp文件下載,目錄不存在,錯誤信息" + e.fillInStackTrace()); } } String src = directory + "/" + downloadFile; try { SftpATTRS attr = sftp.stat(src); long fileSize = attr.getSize(); InputStream inputStream = sftp.get(src, new FileProgressMonitor(fileSize)); // 用下面的方法不會調(diào)用進度監(jiān)控 //InputStream inputStream = sftp.get(src); String tempFile = localDir + "/" + downloadFile; File file = new File(tempFile); File fileParent = file.getParentFile(); if (!fileParent.exists()) { fileParent.mkdirs(); } if (!file.exists()) { writeToLocal(tempFile, inputStream); } } catch (SftpException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } sftpConnection.logout(); } // /** // * 文件上傳 將文件對象上傳到sftp作為文件。文件完整路徑=basePath+directory 目錄不存在則會上傳文件夾 // * // * @param basePath 服務器的基礎路徑,服務器上必須有該目錄,例如 /home // * @param directory 上傳到的目錄,服務器上沒有會自動創(chuàng)建,有則不創(chuàng)建,例如 /test // * @param fileIs 文件流 // * @param fileName 放到服務器上要保存的名字,例如 碼海無際.txt // * @return // */ // public synchronized static boolean upload(String basePath, String directory, InputStream fileIs, String fileName) { // boolean result = false; // Integer i = 0; // while (!result) { // log.info("*****開始登陸*****"); // ChannelSftp sftp = SFTPConnectionFactory.makeConnection(); // log.info("******登陸成功*****"); // try { // sftp.cd(basePath); // sftp.cd(directory); // } catch (SftpException e) { // log.info("sftp文件上傳,目錄不存在開始創(chuàng)建"); // String[] dirs = directory.split("/"); // String tempPath = basePath; // for (String dir : dirs) { // if (null == dir || "".equals(dir)) { // continue; // } // tempPath += "/" + dir; // try { // sftp.cd(tempPath); // } catch (SftpException ex) { // try { // sftp.mkdir(tempPath); // sftp.cd(tempPath); // } catch (SftpException e1) { // log.info("sftp文件上傳,目錄創(chuàng)建失敗,錯誤信息:" + e1.fillInStackTrace()); // } // } // } // } // try { // sftp.put(fileIs, fileName, new FileProgressMonitor(fileIs.available()), ChannelSftp.OVERWRITE); // // 用下面的方法不會調(diào)用進度監(jiān)控 // //sftp.put(fileIs, fileName); // if (i > 0) { // log.info("sftp重試文件上傳成功,ftp路徑:" + basePath + directory + ",文件名稱:" + fileName); // } else { // log.info("sftp文件上傳成功,ftp路徑為" + basePath + directory + ",文件名稱:" + fileName); // } // result = true; // } catch (Exception e) { // i++; // log.error("sftp文件上傳失敗,重試中。。。第" + i + "次,錯誤信息" + e.fillInStackTrace()); // if (i > uploadRettry) { // SFTPConnectionFactory.logout(); // log.error("sftp文件上傳失敗,超過重試次數(shù)結束重試,錯誤信息" + e.fillInStackTrace()); // return result; // } // try { // TimeUnit.MILLISECONDS.sleep(uploadSleep); // } catch (InterruptedException e1) { // SFTPConnectionFactory.logout(); // e1.printStackTrace(); // log.error("sftp文件上傳失敗,系統(tǒng)檢測出異常:" + e); // } // } // // } // SFTPConnectionFactory.logout(); // log.info("sftp上傳:" + result); // try { // fileIs.close(); // } catch (IOException e) { // throw new RuntimeException(e); // } // return result; // } // /** // * 下載文件至本地 // * // * @param directory 要下載文件所在目錄,例如 /home // * @param downloadFile 要下載的文件,例如 碼海無際.txt // * @param localDir 本地路徑,例如 D:\\home // * @return // */ // public synchronized static void download(String directory, String downloadFile, String localDir) { // log.info("*****開始登陸*****"); // ChannelSftp sftp = SFTPConnectionFactory.makeConnection(); // log.info("******登陸成功*****"); // if (directory != null && !"".equals(directory)) { // try { // sftp.cd(directory); // } catch (SftpException e) { // log.error("sftp文件下載,目錄不存在,錯誤信息" + e.fillInStackTrace()); // } // } // String src = directory + "/" + downloadFile; // try { // SftpATTRS attr = sftp.stat(src); // long fileSize = attr.getSize(); // InputStream inputStream = sftp.get(src, new FileProgressMonitor(fileSize)); // // 用下面的方法不會調(diào)用進度監(jiān)控 // //InputStream inputStream = sftp.get(src); // String tempFile = localDir + "/" + downloadFile; // File file = new File(tempFile); // File fileParent = file.getParentFile(); // if (!fileParent.exists()) { // fileParent.mkdirs(); // } // if (!file.exists()) { // writeToLocal(tempFile, inputStream); // } // } catch (SftpException e) { // e.printStackTrace(); // } catch (IOException e) { // e.printStackTrace(); // } // SFTPConnectionFactory.logout(); // } /** * 將InputStream寫入本地文件 * * @param destination 寫入本地目錄 * @param input 輸入流 * @throws IOException 異常 */ public static void writeToLocal(String destination, InputStream input) throws IOException { int index; byte[] bytes = new byte[1024]; FileOutputStream downloadFile = new FileOutputStream(destination); while ((index = input.read(bytes)) != -1) { downloadFile.write(bytes, 0, index); downloadFile.flush(); } downloadFile.close(); input.close(); } /** * 刪除文件 * * @param directory 要刪除文件所在目錄,例如 /home * @param deleteFile 要刪除的文件,例如 碼海無際.txt */ public synchronized boolean delete(String directory, String deleteFile) { boolean result = false; ChannelSftp sftp = sftpConnection.makeConnection(); try { sftp.cd(directory); sftp.rm(deleteFile); } catch (SftpException e) { e.printStackTrace(); } result = true; sftpConnection.logout(); return result; } }
5、上傳進度
package com.base.jsch; import com.jcraft.jsch.SftpProgressMonitor; import lombok.extern.slf4j.Slf4j; import java.text.DecimalFormat; @Slf4j public class FileProgressMonitor implements SftpProgressMonitor { private long fileSize; // 記錄文件總大小 private long transfered; // 記錄已傳輸?shù)臄?shù)據(jù)總大小 public FileProgressMonitor(long fileSize) { if (fileSize != 0) { this.fileSize = fileSize; log.info("數(shù)據(jù)大小: " + fileSize + " bytes"); } else { log.info("文件錯誤"); } } @Override public void init(int op, String src, String dest, long max) { log.info("開始"); } /** * 實現(xiàn)了SftpProgressMonitor接口的count方法 */ @Override public boolean count(long count) { add(count); return true; } /** * 實現(xiàn)了SftpProgressMonitor接口的end方法 */ @Override public void end() { log.info("結束"); } private synchronized void add(long count) { transfered = transfered + count; log.info("已傳輸數(shù)據(jù)大小: " + transfered + " bytes"); double d = ((double) transfered * 100) / (double) fileSize; DecimalFormat df = new DecimalFormat("#.##"); log.info("已傳輸數(shù)據(jù)占比: " + df.format(d) + "%"); } }
6、配置文件
sftp: ip: 192.168.1.111 port: 22 username: root password: root uploadSleep: 1000 #上傳失敗隔1秒重新上傳 uploadRettry: 1 #重新上傳的次數(shù) serverStorageDir: /opt/zzz #服務器路徑 isFileNameGBK: true #文件名是否gbk編碼
7、上傳測試
String src = "D:\\home\\test.xlsx"; // 本地文件名 File file = new File(src); try (FileInputStream fis = new FileInputStream(file)) { boolean upload = sftpClientUtils.upload(fis, ele.getName()); } catch (IOException e) { e.printStackTrace(); }
以上就是Java實現(xiàn)上傳文件到服務器的示例代碼的詳細內(nèi)容,更多關于Java上傳文件到服務器的資料請關注腳本之家其它相關文章!
相關文章
基于SpringBoot實現(xiàn)驗證碼功能的代碼及思路
SpringBoot技術是目前市面上從事JavaEE企業(yè)級開發(fā)過程中使用量最大的技術,下面這篇文章主要給大家介紹了如何基于SpringBoot實現(xiàn)驗證碼功能的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-07-07詳解SpringMVC中的@RequestMapping注解
這篇文章主要介紹了SpringMVC中@RequestMapping注解,@RequestMapping注解是一個用來處理請求地址映射的注解,可用于映射一個請求或一個方法,可以用在類或方法上,需要的朋友可以參考下2023-07-07Hibernate validator使用以及自定義校驗器注解
這篇文章主要介紹了Hibernate validator使用以及自定義校驗器注解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-01-01intellij idea14打包apk文件和查看sha1值
這篇文章主要為大家詳細介紹了intellij idea14打包apk文件和查看sha1值,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-10-10Java集合排序規(guī)則接口Comparator用法解析
這篇文章主要介紹了Java集合排序規(guī)則接口Comparator用法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-09-09