java web 實現Sftp文件上傳下載

思路

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;
    }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章