最近做了一個sftp服務器文件下載的功能,mark一下: 首先是一個SftpClientUtil 類,封裝了對sftp服務器文件上傳、下載、刪除的方法 import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Properties; import java.util.Vector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.ChannelSftp.LsEntry; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; public class SftpClientUtil { /** * 初始化日志引擎 */ private final Logger logger = LoggerFactory.getLogger(SftpClientUtil.class); /** Sftp */ ChannelSftp sftp = null; /** 主機 */ private String host = ""; /** 端口 */ private int port = 0; /** 用戶名 */ private String username = ""; /** 密碼 */ private String password = ""; /** * 構造函數 * * @param host * 主機 * @param port * 端口 * @param username * 用戶名 * @param password * 密碼 * */ public SftpClientUtil(String host, int port, String username, String password){ this.host = host; this.port = port; this.username = username; this.password = password; } /** * 連接sftp服務器 * * @throws Exception */ public void connect() throws Exception { JSch jsch = new JSch(); Session sshSession = jsch.getSession(this.username, this.host, this.port); logger.debug(SftpClientUtil.class + "Session created."); sshSession.setPassword(password); Properties sshConfig = new Properties(); sshConfig.put("StrictHostKeyChecking", "no"); sshSession.setConfig(sshConfig); sshSession.connect(20000); logger.debug(SftpClientUtil.class + " Session connected."); logger.debug(SftpClientUtil.class + " Opening Channel."); Channel channel = sshSession.openChannel("sftp"); channel.connect(); this.sftp = (ChannelSftp) channel; logger.debug(SftpClientUtil.class + " Connected to " + this.host + "."); } /** * Disconnect with server * * @throws Exception */ public void disconnect() throws Exception { if(this.sftp != null){ if(this.sftp.isConnected()){ this.sftp.disconnect(); }else if(this.sftp.isClosed()){ logger.debug(SftpClientUtil.class + " sftp is closed already"); } } } /** * 上傳單個文件 * * @param directory * 上傳的目錄 * @param uploadFile * 要上傳的文件 * * @throws Exception */ public void upload(String directory, String uploadFile) throws Exception { this.sftp.cd(directory); File file = new File(uploadFile); this.sftp.put(new FileInputStream(file), file.getName()); } /** * 上傳目錄下全部文件 * * @param directory * 上傳的目錄 * * @throws Exception */ public void uploadByDirectory(String directory) throws Exception { String uploadFile = ""; List<String> uploadFileList = this.listFiles(directory); Iterator<String> it = uploadFileList.iterator(); while(it.hasNext()) { uploadFile = it.next().toString(); this.upload(directory, uploadFile); } } /** * 下載單個文件 * * @param directory * 下載目錄 * @param downloadFile * 下載的文件 * @param saveDirectory * 存在本地的路徑 * * @throws Exception */ public void download(String directory, String downloadFile, String saveDirectory) throws Exception { String saveFile = saveDirectory + "//" + downloadFile; this.sftp.cd(directory); File file = new File(saveFile); this.sftp.get(downloadFile, new FileOutputStream(file)); } /** * 下載目錄下全部文件 * * @param directory * 下載目錄 * * @param saveDirectory * 存在本地的路徑 * * @throws Exception */ public void downloadByDirectory(String directory, String saveDirectory) throws Exception { String downloadFile = ""; List<String> downloadFileList = this.listFiles(directory); Iterator<String> it = downloadFileList.iterator(); while(it.hasNext()) { downloadFile = it.next().toString(); if(downloadFile.toString().indexOf(".")<0){ continue; } this.download(directory, downloadFile, saveDirectory); } } /** * 刪除文件 * * @param directory * 要刪除文件所在目錄 * @param deleteFile * 要刪除的文件 * * @throws Exception */ public void delete(String directory, String deleteFile) throws Exception { this.sftp.cd(directory); this.sftp.rm(deleteFile); } /** * 列出目錄下的文件 * * @param directory * 要列出的目錄 * * @return list 文件名列表 * * @throws Exception */ @SuppressWarnings("unchecked") public List<String> listFiles(String directory) throws Exception { Vector fileList; List<String> fileNameList = new ArrayList<String>(); fileList = this.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; } /** * 更改文件名 * * @param directory * 文件所在目錄 * @param oldFileNm * 原文件名 * @param newFileNm * 新文件名 * * @throws Exception */ public void rename(String directory, String oldFileNm, String newFileNm) throws Exception { this.sftp.cd(directory); this.sftp.rename(oldFileNm, newFileNm); } public void cd(String directory)throws Exception { this.sftp.cd(directory); } public InputStream get(String directory) throws Exception{ InputStream streatm=this.sftp.get(directory); return streatm; } } 其次是供jsp調用的的servlet類 public class DownloadApplyPersonServlet extends HttpServlet { /** 初始化日志引擎 * */ private final Logger logger = LoggerFactory .getLogger(DownloadApplyPersonServlet.class); public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { doPost(request, response); } // 在doPost()方法中,當servlet收到瀏覽器發出的Post請求后,實現文件下載 public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { logger.info("進入下載文件開始.........."); String host="";//主機地址 String port="";//主機端口 String username="";//服務器用戶名 String password ="";//服務器密碼 String planPath ="";//文件所在服務器路徑 BufferedInputStream bis = null; BufferedOutputStream bos = null; OutputStream fos = null; String fileName = "KJ_CUST_KBYJ";//KJ_CUST_KBYJ20140326.txt SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd"); String currentDate = formatter.format(new Date()); String downloadFile = fileName + currentDate + ".zip"; PrintWriter out=null; SftpClientUtil sftp = new SftpClientUtil(host, Integer.parseInt(port), username, password); try { sftp.connect(); String filename=""; // String[] strs=planUrl.split("/"); String filePath=planPath; //列出目錄下的文件 List<String> listFiles=sftp.listFiles(filePath); boolean isExists=listFiles.contains(downloadFile); if(isExists){ sftp.cd(filePath); if(sftp.get(downloadFile)!=null){ bis = new BufferedInputStream(sftp.get(downloadFile)); } filename=downloadFile; fos = response.getOutputStream(); bos = new BufferedOutputStream(fos); response.setCharacterEncoding("UTF-8"); response.setContentType("application/x-msdownload;charset=utf-8"); final String agent = request.getHeader("User-Agent"); String attachment = "attachment;fileName="; String outputFilename = null; if (agent.indexOf("Firefox") > 0) { attachment = "attachment;fileName*="; outputFilename = "=?UTF-8?B?" + (new String(Base64.encodeBase64(filename.getBytes("UTF-8")))) + "?=";; } else { if (agent.indexOf("MSIE") != -1) { outputFilename = new String(filename.getBytes("gbk"), "iso8859-1"); } else { outputFilename = new String(filename.getBytes("UTF-8"), "iso8859-1"); } } response.setHeader("Content-Disposition", attachment + outputFilename); int bytesRead = 0; //輸入流進行先讀,然后用輸出流去寫,下面用的是緩沖輸入輸出流 byte[] buffer = new byte[8192]; while ((bytesRead = bis.read(buffer)) != -1) { bos.write(buffer,0,bytesRead); } bos.flush(); logger.info("文件下載成功"); }else{ response.setCharacterEncoding("utf-8"); response.setContentType("text/html; charset=UTF-8"); out=response.getWriter(); out.println("<html >" + "<body>" + "沒有找到你要下載的文件" + "</body>" + "</html>"); } } catch (Exception e) { response.setCharacterEncoding("utf-8"); response.setContentType("text/html; charset=UTF-8"); out=response.getWriter(); out.println("<html >" + "<body>" + "沒有找到你要下載的文件" + "</body>" + "</html>"); }finally{ try { sftp.disconnect(); logger.info("SFTP連接已斷開"); } catch (Exception e) { e.printStackTrace(); } if(out!=null){ out.close(); } logger.info("out已關閉"); if(bis != null){ bis.close(); } logger.info("bis已關閉"); if(bos != null){ bos.close(); } logger.info("bos已關閉"); } } } 最后是對servlet的配置,具體可參考web.xml中servlet的配置。 附件中是需要用到餓jar包