java web 实现Sftp文件上传下载

思路

1.首先连接ftp服务器

2.连接到服务器之后如何上传文件

3.上传后如何获取文件

4.文件格式是图片如何展示到客户端浏览器

5.服务端代码如何接收客户端的文件以及如何返回响应信息给浏览器

 主要jar包依赖文件


      com.jcraft
      jsch
      0.1.54
 

        

      com.jcraft
      jzlib
      1.1.1
 

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 返回的文件名列表
     * @throws Exception
     */
    public static List listFiles(String directory) throws Exception {
        Vector fileList;
        List fileNameList = new ArrayList();
        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 downLoad(HttpServletRequest request, HttpServletResponse response) {
        Map paraMap = new HashMap();
        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;
    }

你可能感兴趣的:(JAVA,FTP,Spring,web)