java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java上传文件到服务器

Java实现上传文件到服务器的示例代码

作者:abc_xian

这篇文章主要为大家详细介绍了如何使用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 {
 
    @Autowired
    private 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 {
 
    @Autowired
    private SFTPConfig sftpConfig;
 
    @Autowired
    private 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("文件错误");
        }
    }
 
    @Override
    public void init(int op, String src, String dest, long max) {
        log.info("开始");
    }
 
    /**
     * 实现了SftpProgressMonitor接口的count方法
     */
    @Override
    public boolean count(long count) {
        add(count);
        return true;
    }
 
    /**
     * 实现了SftpProgressMonitor接口的end方法
     */
    @Override
    public 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.111
  port: 22
  username: root
  password: root
  uploadSleep: 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();
}

以上就是Java实现上传文件到服务器的示例代码的详细内容,更多关于Java上传文件到服务器的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文