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容器。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
SpringBoot+MyBatisPlus对Map中Date格式转换处理的方法详解
在 SpringBoot 项目中, 如何统一 JSON 格式化中的日期格式。本文将为大家介绍一种方法:利用MyBatisPlus实现对Map中Date格式转换处理,需要的可以参考一下2022-10-10springBoot的事件机制GenericApplicationListener用法解析
这篇文章主要介绍了springBoot的事件机制GenericApplicationListener用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值的相关资料2019-09-09详解SpringSecurity中的Authentication信息与登录流程
这篇文章主要介绍了SpringSecurity中的Authentication信息与登录流程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2020-09-09IntelliJ IDEA下自动生成Hibernate映射文件以及实体类
这篇文章主要介绍了IntelliJ IDEA下自动生成Hibernate映射文件以及实体类,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2019-11-11SpringBoot+Quartz实现定时任务的代码模版分享
quartz 是一款开源且丰富特性的Java 任务调度库,用于实现任务调度和定时任务,本文主要和大家分享一个SpringBoot整合Quartz实现定时任务的代码模版,需要的可以参考一下2023-06-06
最新评论