热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

javaweb实现Sftp文件上传下载

思路1.首先连接ftp服务器2.连接到服务器之后如何上传文件3.上传后如何获取文件4.文件格式是图片如何展示到客户端浏览器5.服务端代码如何接收客户端的文件以及如何返回响

思路

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


推荐阅读
  • Struts2+Sring+Hibernate简单配置
    2019独角兽企业重金招聘Python工程师标准Struts2SpringHibernate搭建全解!Struts2SpringHibernate是J2EE的最 ... [详细]
  • web.py开发web 第八章 Formalchemy 服务端验证方法
    本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 本文讨论了如何使用Web.Config进行自定义配置节的配置转换。作者提到,他将msbuild设置为详细模式,但转换却忽略了带有替换转换的自定义部分的存在。 ... [详细]
  • Servlet多用户登录时HttpSession会话信息覆盖问题的解决方案
    本文讨论了在Servlet多用户登录时可能出现的HttpSession会话信息覆盖问题,并提供了解决方案。通过分析JSESSIONID的作用机制和编码方式,我们可以得出每个HttpSession对象都是通过客户端发送的唯一JSESSIONID来识别的,因此无需担心会话信息被覆盖的问题。需要注意的是,本文讨论的是多个客户端级别上的多用户登录,而非同一个浏览器级别上的多用户登录。 ... [详细]
  • 本文介绍了一个Magento模块,其主要功能是实现前台用户利用表单给管理员发送邮件。通过阅读该模块的代码,可以了解到一些有关Magento的细节,例如如何获取系统标签id、如何使用Magento默认的提示信息以及如何使用smtp服务等。文章还提到了安装SMTP Pro插件的方法,并给出了前台页面的代码示例。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了在Linux下安装Perl的步骤,并提供了一个简单的Perl程序示例。同时,还展示了运行该程序的结果。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • Hibernate延迟加载深入分析-集合属性的延迟加载策略
    本文深入分析了Hibernate延迟加载的机制,特别是集合属性的延迟加载策略。通过延迟加载,可以降低系统的内存开销,提高Hibernate的运行性能。对于集合属性,推荐使用延迟加载策略,即在系统需要使用集合属性时才从数据库装载关联的数据,避免一次加载所有集合属性导致性能下降。 ... [详细]
author-avatar
SJ曹圭贤V
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有