Java如何实现上传文件到服务器指定目录

 更新时间:2020年04月16日 15:04:34   投稿:yaominghui  
这篇文章主要介绍了Java如何实现上传文件到服务器指定目录,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

前言需求

使用freemarker生成的静态文件,统一存储在某个服务器上。本来一开始打算使用ftp实现的,奈何老连接不上,改用jsch。毕竟有现成的就很舒服,在此介绍给大家。

具体实现

引入的pom

<dependency>
	<groupId>ch.ethz.ganymed</groupId>
	<artifactId>ganymed-ssh2</artifactId>
	<version>262</version>
</dependency>

<dependency>
	<groupId>com.jcraft</groupId>
	<artifactId>jsch</artifactId>
	<version>0.1.55</version>
</dependency>

建立实体类

public class ResultEntity {

  private String code;

  private String message;

  private File file;
  
  public ResultEntity(){}
  
	public ResultEntity(String code, String message, File file) {
		super();
		this.code = code;
		this.message = message;
		this.file = file;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public File getFile() {
		return file;
	}

	public void setFile(File file) {
		this.file = file;
	}
  
}

public class ScpConnectEntity {
  private String userName;
  private String passWord;
  private String url;
  private String targetPath;

  public String getTargetPath() {
    return targetPath;
  }

  public void setTargetPath(String targetPath) {
    this.targetPath = targetPath;
  }

  public String getUserName() {
    return userName;
  }

  public void setUserName(String userName) {
    this.userName = userName;
  }

  public String getPassWord() {
    return passWord;
  }

  public void setPassWord(String passWord) {
    this.passWord = passWord;
  }

  public String getUrl() {
    return url;
  }

  public void setUrl(String url) {
    this.url = url;
  }

}

建立文件上传工具类

@Configuration

@Configuration
public class FileUploadUtil {

  @Value("${remoteServer.url}")
  private String url;

  @Value("${remoteServer.password}")
  private String passWord;

  @Value("${remoteServer.username}")
  private String userName;

  @Async
  public ResultEntity uploadFile(File file, String targetPath, String remoteFileName) throws Exception{
    ScpConnectEntity scpConnectEntity=new ScpConnectEntity();
    scpConnectEntity.setTargetPath(targetPath);
    scpConnectEntity.setUrl(url);
    scpConnectEntity.setPassWord(passWord);
    scpConnectEntity.setUserName(userName);

    String code = null;
    String message = null;
    try {
      if (file == null || !file.exists()) {
        throw new IllegalArgumentException("请确保上传文件不为空且存在!");
      }
      if(remoteFileName==null || "".equals(remoteFileName.trim())){
        throw new IllegalArgumentException("远程服务器新建文件名不能为空!");
      }
      remoteUploadFile(scpConnectEntity, file, remoteFileName);
      code = "ok";
      message = remoteFileName;
    } catch (IllegalArgumentException e) {
      code = "Exception";
      message = e.getMessage();
    } catch (JSchException e) {
      code = "Exception";
      message = e.getMessage();
    } catch (IOException e) {
      code = "Exception";
      message = e.getMessage();
    } catch (Exception e) {
      throw e;
    } catch (Error e) {
      code = "Error";
      message = e.getMessage();
    }
    return new ResultEntity(code, message, null);
  }


  private void remoteUploadFile(ScpConnectEntity scpConnectEntity, File file,
                 String remoteFileName) throws JSchException, IOException {

    Connection connection = null;
    ch.ethz.ssh2.Session session = null;
    SCPOutputStream scpo = null;
    FileInputStream fis = null;

    try {
      createDir(scpConnectEntity);
    }catch (JSchException e) {
      throw e;
    }

    try {
      connection = new Connection(scpConnectEntity.getUrl());
      connection.connect();

      if(!connection.authenticateWithPassword(scpConnectEntity.getUserName(),scpConnectEntity.getPassWord())){
        throw new RuntimeException("SSH连接服务器失败");
      }
      session = connection.openSession();

      SCPClient scpClient = connection.createSCPClient();

      scpo = scpClient.put(remoteFileName, file.length(), scpConnectEntity.getTargetPath(), "0666");
      fis = new FileInputStream(file);

      byte[] buf = new byte[1024];
      int hasMore = fis.read(buf);

      while(hasMore != -1){
        scpo.write(buf);
        hasMore = fis.read(buf);
      }
    } catch (IOException e) {
      throw new IOException("SSH上传文件至服务器出错"+e.getMessage());
    }finally {
      if(null != fis){
        try {
          fis.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if(null != scpo){
        try {
          scpo.flush();
//          scpo.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if(null != session){
        session.close();
      }
      if(null != connection){
        connection.close();
      }
    }
  }


  private boolean createDir(ScpConnectEntity scpConnectEntity ) throws JSchException {

    JSch jsch = new JSch();
    com.jcraft.jsch.Session sshSession = null;
    Channel channel= null;
    try {
      sshSession = jsch.getSession(scpConnectEntity.getUserName(), scpConnectEntity.getUrl(), 22);
      sshSession.setPassword(scpConnectEntity.getPassWord());
      sshSession.setConfig("StrictHostKeyChecking", "no");
      sshSession.connect();
      channel = sshSession.openChannel("sftp");
      channel.connect();
    } catch (JSchException e) {
      e.printStackTrace();
      throw new JSchException("SFTP连接服务器失败"+e.getMessage());
    }
    ChannelSftp channelSftp=(ChannelSftp) channel;
    if (isDirExist(scpConnectEntity.getTargetPath(),channelSftp)) {
      channel.disconnect();
      channelSftp.disconnect();
      sshSession.disconnect();
      return true;
    }else {
      String pathArry[] = scpConnectEntity.getTargetPath().split("/");
      StringBuffer filePath=new StringBuffer("/");
      for (String path : pathArry) {
        if (path.equals("")) {
          continue;
        }
        filePath.append(path + "/");
        try {
          if (isDirExist(filePath.toString(),channelSftp)) {
            channelSftp.cd(filePath.toString());
          } else {
            // 建立目录
            channelSftp.mkdir(filePath.toString());
            // 进入并设置为当前目录
            channelSftp.cd(filePath.toString());
          }
        } catch (SftpException e) {
          e.printStackTrace();
          throw new JSchException("SFTP无法正常操作服务器"+e.getMessage());
        }
      }
    }
    channel.disconnect();
    channelSftp.disconnect();
    sshSession.disconnect();
    return true;
  }

  private boolean isDirExist(String directory,ChannelSftp channelSftp) {
    boolean isDirExistFlag = false;
    try {
      SftpATTRS sftpATTRS = channelSftp.lstat(directory);
      isDirExistFlag = true;
      return sftpATTRS.isDir();
    } catch (Exception e) {
      if (e.getMessage().toLowerCase().equals("no such file")) {
        isDirExistFlag = false;
      }
    }
    return isDirExistFlag;
  }
}

属性我都写在Spring的配置文件里面了。将这个类托管给spring容器。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • maven自动将源码打包并发布的实现步骤

    maven自动将源码打包并发布的实现步骤

    maven-source-plugin 提供项目自动将源码打包并发布的功能,在需要发布源码项目的 pom.xml 文件中添加即可,本文就来介绍一下如何设置,感兴趣的可以了解一下
    2023-11-11
  • 一文带你回顾Java中的垃圾回收机制

    一文带你回顾Java中的垃圾回收机制

    这篇文章主要给大家介绍了关于Java中垃圾回收机制的相关资料, Java 程序,内存是托管于 JVM 的,即对象的创建和内存的回收都是由 JVM 自行完成的,开发人员是无权干涉的,只能尽量去优化,需要的朋友可以参考下
    2021-08-08
  • Java从服务端下载Excel模板文件的两种方法

    Java从服务端下载Excel模板文件的两种方法

    这篇文章主要为大家详细介绍了Java从服务端下载Excel模板文件的两种方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • SpringBoot+MyBatisPlus对Map中Date格式转换处理的方法详解

    SpringBoot+MyBatisPlus对Map中Date格式转换处理的方法详解

    在 SpringBoot 项目中, 如何统一 JSON 格式化中的日期格式。本文将为大家介绍一种方法:利用MyBatisPlus实现对Map中Date格式转换处理,需要的可以参考一下
    2022-10-10
  • springBoot的事件机制GenericApplicationListener用法解析

    springBoot的事件机制GenericApplicationListener用法解析

    这篇文章主要介绍了springBoot的事件机制GenericApplicationListener用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值的相关资料
    2019-09-09
  • 详解SpringSecurity中的Authentication信息与登录流程

    详解SpringSecurity中的Authentication信息与登录流程

    这篇文章主要介绍了SpringSecurity中的Authentication信息与登录流程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • IntelliJ IDEA下自动生成Hibernate映射文件以及实体类

    IntelliJ IDEA下自动生成Hibernate映射文件以及实体类

    这篇文章主要介绍了IntelliJ IDEA下自动生成Hibernate映射文件以及实体类,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • SpringBoot+Quartz实现定时任务的代码模版分享

    SpringBoot+Quartz实现定时任务的代码模版分享

    quartz 是一款开源且丰富特性的Java 任务调度库,用于实现任务调度和定时任务,本文主要和大家分享一个SpringBoot整合Quartz实现定时任务的代码模版,需要的可以参考一下
    2023-06-06
  • Java中的ConcurrentHashMap原理详解

    Java中的ConcurrentHashMap原理详解

    这篇文章主要介绍了Java中的ConcurrentHashMap原理详解,ConcurrentHashMap和HashMap一样,是一个存放键值对的容器,使用hash算法来获取值的地址,因此时间复杂度是O(1),查询非常快,需要的朋友可以参考下
    2023-12-12
  • Java Map接口概述和常用方法详解

    Java Map接口概述和常用方法详解

    现实生活中,我们常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的关系,就叫做映射。Java提供了专门的集合类用来存放这种对象关系的对象,即java.util.Map接口。本文就来聊聊Map接口概述和常用方法
    2022-10-10

最新评论