使用freemarker生成的静态文件,统一存储在某个服务器上。本来一开始打算使用ftp实现的,奈何老连接不上,改用jsch。毕竟有现成的就很舒服,在此介绍给大家。
<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 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容器。
如果在普通类里面使用这个类,就需要看一下上篇博客了。哈哈。
在我们使用的时候,主要调uploadFile这个方法即可。传递File文件,目标路径及文件名称。