所需要的jar包有:jsch-0.1.50.jar;log4j-1.2.13.jar;
SftpDomain
package sftp;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.Session;
/**
* SFTP 实体对象
*
*/
public class SftpDomain {
private Session session;
private Channel channel;
private SftpDomain (){
}
/**
* 获取SFtpDoamin实例
*
* @return
*/
public static SftpDomain getInstance(){
return new SftpDomain();
}
public Session getSession() {
return session;
}
public void setSession(Session session) {
this.session = session;
}
public Channel getChannel() {
return channel;
}
public void setChannel(Channel channel) {
this.channel = channel;
}
}
SftpService
package sftp;
import java.io.File;
import java.util.Properties;
import org.apache.log4j.Logger;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
/**
* Ftp 服务类,对JSCH进行了包装<br>
* 依赖库文件:jsch-0.1.50.jar
*
*/
public class SftpService {
private static Logger logger = Logger.getLogger(SftpService.class);
/**
* SFTP 服务器地址
*/
private String ftpServerAddress = null;
/**
* SFTP 服务端口
*/
private int port = 22;
/**
* SFTP 用户名
*/
private String user = null;
/**
* SFTP 密码
*/
private String password = null;
/**
* SFTP 数据传输超时时间
*/
private int timeout = 0;
/** 是否使用代理 */
private boolean proxy = false;
/** 代理IP */
private String proxyIP;
/** 代理端口 */
private String proxyPort;
// 主动判断是否使用代理
public SftpService(String ftpServerAddress, String user, String password,boolean proxy) {
this.ftpServerAddress = ftpServerAddress;
this.user = user;
this.password = password;
this.proxy = proxy;
}
// 主动判断是否使用代理
public SftpService(String ftpServerAddress,String port, String user, String password,boolean proxy) {
this.ftpServerAddress = ftpServerAddress;
this.user = user;
this.password = password;
this.proxy = proxy;
this.setPort(port);
}
// 使用代理
public SftpService(String ftpServerAddress, String user, String password) {
this(ftpServerAddress,user,password,true);
}
// 使用代理
public SftpService(String ftpServerAddress,String port, String user, String password) {
this(ftpServerAddress,port,user,password,true);
}
/**
* 初始化SFTP连接,并进行用户登录
*
* @return FTPClient
* @throws Exception
*/
public SftpDomain initConnection() throws Exception
{
Session session = null;
Channel channel = null;
JSch jsch = new JSch(); // 创建JSch对象
try{
session = jsch.getSession(user,ftpServerAddress,port); // 根据用户名,主机ip,端口获取一个Session对象
logger.info("SFTP Server Session created.");
if (password != null) {
session.setPassword(password); // 设置密码
}
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config); // 为Session对象设置properties
session.setTimeout(timeout); // 设置timeout时间
session.connect(); // 通过Session建立链接
logger.info("SFTP Server Session connected." );
logger.info("SFTP Server Opening Channel." );
channel = session.openChannel("sftp"); // 打开SFTP通道
channel.connect(); // 建立SFTP通道的连接
logger.info("Connected successfully to SFTP Server = " + ftpServerAddress + ",as userName = " + user);
}catch (JSchException e){
logger.error(parseExceptionMsg(e), e );
throw e;
}catch (Exception e ){
logger.error( "SFTP服务器登录失败" ,e);
throw e;
}
SftpDomain sftpDomain=SftpDomain.getInstance();
sftpDomain.setChannel(channel);
sftpDomain.setSession(session);
return sftpDomain;
}
/**
* 解析JSchException的错误信息
* @param e
* @return
*/
private String parseExceptionMsg(Exception e){
String errorMsg=e.getMessage();
errorMsg=(errorMsg==null?"":errorMsg);
if(errorMsg.contains("SocketTimeoutException")){
return "SFTP Server port is not established";
}else if(errorMsg.contains("socket is not established")){
return "SFTP Server address is not established";
}else if(errorMsg.contains("socket is not established")){
return "No such file";
}else{
return e.getMessage();
}
}
/**
* 释放Sftp资源
* @param sftpDomain
*/
public void closeSftpResource(SftpDomain sftpDomain){
if(sftpDomain==null){
return;
}
Session session=sftpDomain.getSession();
Channel channel=sftpDomain.getChannel();
if (channel != null) {
channel.disconnect();
}
if (session != null) {
session.disconnect();
}
}
/**
* 在当前工作目录下建立多级目录结构
*
* @param ftp
* @param dir
* @throws Exception
*/
public void makeMultiDirectory( ChannelSftp ftp, String dir ) throws Exception
{
try
{
if(dir.equals("/")){
return;
}
try{
ftp.cd(dir);
}catch (Exception e) {
if(dir.lastIndexOf("/")+1==dir.length() && dir.length()>1){
dir=dir.substring(0,dir.lastIndexOf("/"));
makeMultiDirectory(ftp,dir.substring(0,dir.lastIndexOf("/")+1));
}else if(dir.length()>1){
makeMultiDirectory(ftp,dir.substring(0,dir.lastIndexOf("/")+1));
}
try{
logger.info( "目录[ " + dir + "]不存在,创建目录");
ftp.mkdir(dir);
}catch (Exception ex) {
logger.error( "创建目录[ "+dir+" ]失败",ex);
}
}
}
catch ( Exception ex )
{
logger.error( "SFTP IO异常",ex);
throw ex;
}
}
/**
* 更改服务器当前路径
*
* @param ftp
* @param dir
* @throws Exception
*/
public void changeWorkingDirectory( ChannelSftp ftp, String dir ) throws Exception
{
try
{
ftp.cd( dir );
}
catch (Exception e )
{
logger.error( "目录[ " + dir + "]进入失败", e );
throw e;
}
}
/**
* 上传文件到FTP服务器
*
* @param ftp
* @param localFilePath
* @param remoteFilePath
* @throws Exception
*/
public void uploadFile( ChannelSftp ftp, String localFilePath, String remoteFilePath ) throws Exception
{
try
{
try{
ftp.ls(remoteFilePath); //首先查看下目录,如果不存在,系统会被错,捕获这个错,生成新的目录。
}catch(Exception e){
makeMultiDirectory(ftp,remoteFilePath);
}
ftp.put(localFilePath, remoteFilePath, ChannelSftp.OVERWRITE);
logger.info( "文件成功上传到SFTP服务器" );
}catch (Exception ex ){
logger.error( "文件传输失败" ,ex);
throw ex;
}
}
/**
* 下载文件到本地
*
* @param ftp
* @param remoteFilePath
* @param localFilePath
* @throws Exception
*/
public void downloadFile( ChannelSftp ftp, String remoteFilePath, String localFilePath ) throws Exception
{
try
{
if(!new File(localFilePath).exists()){
new File(localFilePath).mkdirs();
}
logger.info("SFTP服务器地址文件"+remoteFilePath+"\n localFilePath"+localFilePath);
ftp.get(remoteFilePath,localFilePath);
logger.info( "文件成功从SFTP服务器下载" );
}catch (Exception ex ){
logger.error( "文件传输失败" ,ex);
throw ex;
}
}
/**
* Method setFtpServerAddress.
*
* @param ftpServerAddress
* String
*/
public void setFtpServerAddress( String ftpServerAddress )
{
this.ftpServerAddress = ftpServerAddress;
}
/**
* Method setUser.
*
* @param user
* String
*/
public void setUser( String user )
{
this.user = user;
}
/**
* Method setPassword.
*
* @param password
* String
*/
public void setPassword( String password )
{
this.password = password;
}
/**
* Method setTimeout.
*
* @param timeout
* String
*/
public void setTimeout( String timeout )
{
try
{
this.timeout = Integer.parseInt( timeout );
}
catch ( NumberFormatException ex )
{
// 默认超时时间 2000毫秒
this.timeout = 2000;
}
}
/**
* Method setPort.
*
* @param port
* String
*/
public void setPort( String port )
{
try
{
this.port = Integer.parseInt( port );
}
catch ( NumberFormatException ex )
{
// 默认端口21
this.port = 22;
}
}
public void setProxyIP(String proxyIP) {
this.proxyIP = proxyIP;
}
public void setProxyPort(String proxyPort) {
this.proxyPort = proxyPort;
}
}
SftpAction
package sftp;
import java.io.File;
import org.apache.log4j.Logger;
import com.jcraft.jsch.ChannelSftp;
/**
* 将用户文件从SFTP服务器下载到应用服务器的Action<br>
* 下载的文件按照SFTP服务器上相同的路径保存在本地
*
*/
public class SftpAction {
public static final String ERROR_CODE = "errorCode";
public static final String ERROR_MSG = "errorMsg";
/**
* 保存在SFTP服务器上的文件绝对路径
* 文件上传,可以是文件的目录,保存的文件名则与本地的文件名称一致
* 文件下载,需要是服务器文件的绝对路径
*/
private String ftpFilePath;
/**
* 保存在本地的文件绝对路径或目录,
*
* 文件上传,需要是文件的绝对路径
* 文件下载,可以是文件的目录,保存的文件名则与服务器的文件名称一致
*/
private String localFilePath;
/**
* 文件操作类型 "0":文件上传,默认端口22;"1":文件下载,默认端口22;"2":文件上传,配置端口;"3":文件下载,配置端口
*/
private String doType;
/**
* Sftp服务名称
*/
private String sftpServiceName="SFtpService";
/** 服务器IP */
private String serversIP;
/** 端口*/
private String port;
/** 用户名 */
private String username;
/** 密码 */
private String password;
/** 代理IP */
private String httpProxyIP = "httpProxyIP";
/** 代理端口 */
private String httpProxyProt = "httpProxyProt";
private static Logger logger=Logger.getLogger(SftpAction.class);
public String execute() throws Exception {
// 获取服务器上文件绝对路径
// String ftpFilePathName = (String) context.getDataValue( ftpFilePath );
String ftpFilePathName ="/upload/vue1.js";
// 获取本地上文件绝对路径
// String localFilePathName = (String) context.getDataValue( localFilePath );
String localFilePathName ="/Users/partner/Downloads/";
logger.info("获取远程服务器上文件绝对路径: "+ftpFilePathName+"获取本地服务器上文件绝对路径: "+localFilePathName);
SftpService sftpService = null;
SftpDomain sftpDomain=null;
String ftpServerAddress = "192.168.174.150";// 获得服务器IP
String user = "demo1";// 获得服务器用户名
String password = "YuLiang127";// 获得密码
doType="3";
try{
// ftpServerAddress = (String)context.get(serversIP);// 获得服务器IP
// user = (String)context.get(username);// 获得服务器用户名
// password = (String)context.get(this.password);// 获得密码
//SFTP服务名称
if("2".equals(doType)||"3".equals(doType)){
// String strPort = (String) context.getDataValue( port );
String strPort ="22";
sftpService = new SftpService(ftpServerAddress,strPort,user,password);
}else{
sftpService = new SftpService(ftpServerAddress,user,password);
}
//文件上传,校验本地文件是否存在
if("0".equals(doType)){
File file=new File(localFilePathName);
if(!file.isFile()){
logger.error("文件["+localFilePathName+"]不存在或不是文件");
return "-1";
}
}
sftpDomain=sftpService.initConnection();//得到Sftp实体对象
ChannelSftp channelSftp=(ChannelSftp)sftpDomain.getChannel();
if("1".equals(doType)||"3".equals(doType)){//文件下载
logger.info("开始下载,下载地址为: "+ftpFilePathName+"下载的文件: "+localFilePathName);
sftpService.downloadFile(channelSftp, ftpFilePathName, localFilePathName);
// context.put(localFilePath, localFilePathName);
logger.info("下载完成 ");
}else {
logger.info("开始上传,上传地址为: "+ftpFilePathName+"上传的文件: "+localFilePathName);
sftpService.uploadFile(channelSftp, localFilePathName, ftpFilePathName);
logger.info("上传完成 ");
}
}catch (Exception e) {
logger.error("文件["+localFilePathName+"]不存在或不是文件");
// context.put(ERROR_CODE, "11");
// context.put(ERROR_MSG,
// "文件[localFilePathName="+localFilePathName+" ftpFilePathName="+ftpFilePathName+"]不存在或不是文件" +
// "[serversIp=" +ftpServerAddress + "]" +
// "[accreditUsername=" +user + "]" +
// "[accreditUsernamecreditPassowrd=" +password + "]");
return "-1";
}finally{
//关闭SFTP资源
sftpService.closeSftpResource(sftpDomain);
}
return "0";
}
public void setFtpFilePath(String ftpFilePath) {
this.ftpFilePath = ftpFilePath;
}
public void setLocalFilePath(String localFilePath) {
this.localFilePath = localFilePath;
}
public void setDoType(String doType) {
this.doType = doType;
}
public void setSftpServiceName(String sftpServiceName) {
this.sftpServiceName = sftpServiceName;
}
public void setServersIP(String serversIP) {
this.serversIP = serversIP;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setPort(String port) {
this.port = port;
}
public void setHttpProxyIP(String httpProxyIP) {
this.httpProxyIP = httpProxyIP;
}
public void setHttpProxyProt(String httpProxyProt) {
this.httpProxyProt = httpProxyProt;
}
public static void main(String[] args) throws Exception{
SftpAction action=new SftpAction();
System.out.println(action.execute());
}
}