Java上传文件到服务器

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;/*** 重新上传的次数*/@NotNull(message = "重新上传次数不能为空")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 {@Autowiredprivate 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 {@Autowiredprivate SFTPConfig sftpConfig;@Autowiredprivate 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文件上传,目录不存在开始创建");try {sftp.mkdir(sftpConfig.getServerStorageDir());sftp.cd(sftpConfig.getServerStorageDir());} catch (SftpException e1) {log.info("sftp文件上传,目录创建失败,错误信息:" + e1.fillInStackTrace());}}else{log.info("sftp连接已经失效");return result;}}try {sftp.put(fileIs, fileName, new FileProgressMonitor(fileIs.available()), ChannelSftp.OVERWRITE);// 用下面的方法不会调用进度监控//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文件上传失败,超过重试次数结束重试,错误信息" + e.fillInStackTrace());return result;}try {TimeUnit.MILLISECONDS.sleep(sftpConfig.getUploadSleep());} catch (InterruptedException e1) {sftpConnection.logout();e1.printStackTrace();log.error("sftp文件上传失败,系统检测出异常:" + 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));// 用下面的方法不会调用进度监控//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 上传到的目录,服务器上没有会自动创建,有则不创建,例如 /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文件上传,目录不存在开始创建");
//                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文件上传,目录创建失败,错误信息:" + e1.fillInStackTrace());
//                        }
//                    }
//                }
//            }
//            try {
//                sftp.put(fileIs, fileName, new FileProgressMonitor(fileIs.available()), ChannelSftp.OVERWRITE);
//                // 用下面的方法不会调用进度监控
//                //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文件上传失败,超过重试次数结束重试,错误信息" + e.fillInStackTrace());
//                    return result;
//                }
//                try {
//                    TimeUnit.MILLISECONDS.sleep(uploadSleep);
//                } catch (InterruptedException e1) {
//                    SFTPConnectionFactory.logout();
//                    e1.printStackTrace();
//                    log.error("sftp文件上传失败,系统检测出异常:" + 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));
//            // 用下面的方法不会调用进度监控
//            //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; // 记录已传输的数据总大小public FileProgressMonitor(long fileSize) {if (fileSize != 0) {this.fileSize = fileSize;log.info("数据大小: " + fileSize + " bytes");} else {log.info("文件错误");}}@Overridepublic void init(int op, String src, String dest, long max) {log.info("开始");}/*** 实现了SftpProgressMonitor接口的count方法*/@Overridepublic boolean count(long count) {add(count);return true;}/*** 实现了SftpProgressMonitor接口的end方法*/@Overridepublic void end() {log.info("结束");}private synchronized void add(long count) {transfered = transfered + count;log.info("已传输数据大小: " + transfered + " bytes");double d = ((double) transfered * 100) / (double) fileSize;DecimalFormat df = new DecimalFormat("#.##");log.info("已传输数据占比: " + df.format(d) + "%");}}

6、配置文件

sftp:ip: 192.168.1.111port: 22username: rootpassword: rootuploadSleep: 1000 #上传失败隔1秒重新上传uploadRettry: 1 #重新上传的次数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();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/824551.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

牛客 NC205 跳跃游戏(三)【中等 贪心 Java,Go,PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/14abdfaf0ec4419cbc722decc709938b 思路 参考答案Java import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可*** …

Go 单元测试之Mysql数据库集成测试

文章目录 一、 sqlmock介绍二、安装三、基本用法四、一个小案例五、Gorm 初始化注意点 一、 sqlmock介绍 sqlmock 是一个用于测试数据库交互的 Go 模拟库。它可以模拟 SQL 查询、插入、更新等操作&#xff0c;并且可以验证 SQL 语句的执行情况&#xff0c;非常适合用于单元测试…

基于SpringBoot+Vue社区医院服务平台(源码+文档+包运行)

一.系统概述 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了社区医院信息平台的开发全过程。通过分析社区医院信息平台管理的不足&#xff0c;创建了一个计算机管理社区医院信息平台的方案。文章介绍了社区医院信息…

如何在Linux CentOS部署宝塔面板并实现固定公网地址访问内网宝塔

文章目录 一、使用官网一键安装命令安装宝塔二、简单配置宝塔&#xff0c;内网穿透三、使用固定公网地址访问宝塔 宝塔面板作为建站运维工具&#xff0c;适合新手&#xff0c;简单好用。当我们在家里/公司搭建了宝塔&#xff0c;没有公网IP&#xff0c;但是想要在外也可以访问内…

QAnything部署Mac m1环境

本次安装时Qanything已经更新到了v1.3.3&#xff0c;支持纯python安装。安装过程比较简单&#xff0c;如下&#xff1a; QAnything/README_zh.md at qanything-python-v1.3.1 netease-youdao/QAnything GitHub 首先需要用Anaconda3创建隔离环境&#xff0c;简要说明下Anaco…

春藤实业启动SAP S/4HANA Cloud Public Edition项目,与工博科技携手数字化转型之路

3月11日&#xff0c;广东省春藤实业有限公司&#xff08;以下简称“春藤实业”&#xff09;SAP S/4HANA Cloud Public Edition&#xff08;以下简称“SAP ERP公有云”&#xff09;项目正式启动。春藤实业董事长陈董、联络协调项目经理慕总、内部推行项目经理陈总以及工博董事长…

酒店水电能源计量管理系统

酒店水电能源计量管理系统是一种针对酒店行业设计的能源管理系统&#xff0c;旨在实现对水电能源的计量、监测和管理。本文将从系统特点、构成以及带来的效益三个方面展开介绍。 系统特点 1.多元化计量&#xff1a;该系统能够对酒店内的水、电能源进行多元化计量&#xff0c;…

软件项目总体测试计划(Word原件2024)

一、 前言 &#xff08;一&#xff09; 背景 &#xff08;二&#xff09; 目的 &#xff08;三&#xff09; 测试目标 &#xff08;四&#xff09; 适用范围与读者对象 &#xff08;五&#xff09; 术语与缩写 二、 软件测试实施流程 &#xff08;一&#xff09; 测试工作总体流…

2024年MathorCup数学建模C题物流网络分拣中心货量预测及人员排班解题文档与程序

2024年第十四届MathorCup高校数学建模挑战赛 C题 物流网络分拣中心货量预测及人员排班 原题再现&#xff1a; 电商物流网络在订单履约中由多个环节组成&#xff0c;图1是一个简化的物流网络示意图。其中&#xff0c;分拣中心作为网络的中间环节&#xff0c;需要将包按照不同流…

【Python基础】MySQL

文章目录 [toc]创建数据库创建数据表数据插入数据查询数据更新 个人主页&#xff1a;丷从心 系列专栏&#xff1a;Python基础 学习指南&#xff1a;Python学习指南 创建数据库 import pymysqldef create_database():db pymysql.connect(hostlocalhost, userroot, passwordr…

Maven多模块管理

Maven多模块管理 在了解怎么进行Maven多模块管理之前&#xff0c;先聊聊为什么要进行Maven多模块管理 为什么要Maven多模块管理&#xff1f; 在传统的单体架构开发下&#xff0c;一个项目中的依赖只需要使用一个pom.xml文件管理即可。但是随着微服务的流行&#xff0c;将原有…

【IT运维入门(ITHW)系列】之「快速部署」第二期清单(持续更新)

ITHW是Information Technology Hello World的缩写简拼。意在提供IT领域的入门相关知识&#xff0c;近期给大家带来的是主流技术选型的快速部署系列&#xff0c;意在最大程度地简化部署过程&#xff0c;以便能快速体验或测试相关技术选型。 「快速部署」第一期清单 ITHW快捷部署…

Python零基础从小白打怪升级中~~~~~~~多线程

线程安全和锁 一、全局解释器锁 首先需要明确的一点是GIL并不是Python的特性&#xff0c;它是在实现Python解析器(CPython)时所引入的一个概念。 GIL全称global interpreter lock&#xff0c;全局解释器锁。 每个线程在执行的时候都需要先获取GIL&#xff0c;保证同一时刻只…

MR-JE-70A 三菱MR-JE伺服驱动器(750W通用型)

三菱MR-JE伺服驱动器(750W通用型) MR-JE-70A外部连接,MR-JE-70A用户手册,MR-JE-70A 三相或单相AC220V三菱通用型伺服放大器750W&#xff0c;配套电机HG-SN52J-S100、HG-KN73J-S100。 MR-JE-70A参数说明&#xff1a;伺服驱动器通用型750W&#xff0c;三相或单相AC200V~240V 三…

Dual-AMN论文阅读

Boosting the Speed of Entity Alignment 10: Dual Attention Matching Network with Normalized Hard Sample Mining 将实体对齐速度提高 10 倍&#xff1a;具有归一化硬样本挖掘的双重注意力匹配网络 ABSTRACT 寻找多源知识图谱(KG)中的等效实体是知识图谱集成的关键步骤&…

使用Flask和Flask-JWT-Extended保护API免受跨站请求攻击

在本文中&#xff0c;我们将探讨如何使用Flask和Flask-JWT-Extended库来保护您的API免受跨站请求攻击&#xff08;CSRF&#xff09;。我们将首先简要介绍CSRF攻击的概念&#xff0c;然后详细说明如何使用Flask-JWT-Extended库来保护您的API。 什么是跨站请求攻击&#xff08;C…

CSS文本属性与字体属性

目录 文本属性 文本颜色 文本对齐 修饰文本 文本缩进 行高 字体属性 字体系列 字体大小 字体粗细 字体样式 字体/文本综合属性写法 Chrome调试工具的使用 文本属性 文本颜色 在CSS中使用color 属性用于定义文本的颜色&#xff0c;使用background-color设置一个盒…

Adobe Acrobat PDF 2024

Adobe Acrobat PDF 2024正式发布&#xff01;支持Windows和macOS系统&#xff0c;新界面做了轻微调整。 下载地址 Windows客户端&#xff1a;https://www.123pan.com/s/f43eVv-GKZKd.html macOS客户端&#xff1a;https://www.123pan.com/s/f43eVv-PKZKd.html

带缓存的输入输出流(I/O)

文章目录 前言一、带缓冲的输入输出流是什么&#xff1f;二、使用方法 1.BufferedInputStream与BufferedOutputStream类2.BufferedReader与BufferedWriter类总结 前言 输入输出流可以视为&#xff0c;从A点把货物搬运至B点。那么带缓冲的意思可以视为用货车把A点的货物搬运至B点…

[ ROS入门]

00ROS实现流程大致分为5步 先创建一个工作空间&#xff1b;再创建一个功能包&#xff1b;编辑源文件&#xff1b;编辑配置文件&#xff1b;编译并执行。 01创建工作空间 02进入src创建ros包并添加依赖 上述命令&#xff0c;会在工作空间下生成一个功能包&#xff0c;该功能包依…