Java实现上传文件到指定服务器指定目录
遇到了此类问题,网上找到一篇文章,基于此,转载此篇文章,如有版本不一致,我遇到的就是自己私服版本不一致,根据示例代码很容易修改,实际代码对upload方法封装了一层,支持文件list上传,在远处桌面开发,就不贴出来了
原文地址 https://www.cnblogs.com/jichi/p/12158537.html
前言需求
使用 freemarker 生成的静态文件,统一存储在某个服务器上。本来一开始打算使用 ftp 实现的,奈何老连接不上,改用 jsch。毕竟有现成的就很舒服,在此介绍给大家。
具体实现
引入的 pom
1 2 3 4 5 6 7 8 9 10 11
| <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>
|
建立实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| 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; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| 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; }
}
|
建立文件上传工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
| @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();
} 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 容器。
如果在普通类里面使用这个类,就需要看一下上篇博客了。哈哈。
总结
在我们使用的时候,主要调 uploadFile 这个方法即可。传递 File 文件,目标路径及文件名称。