sFTPによるファイル転送処理サンプル

JavaによるFTPのファイル転送を作ることになったのですが、セキュリティを考慮し、sFTPで通信経路を暗号化することになりました。
JavaによるsFTP通信に利用したのは、JCraftの「JSch – Java Secure Channel」というライブラリです。
また、今回は、ユーザー名とパスワードによる認証ではなく、privatekeyを読み込んでそれを利用して接続を行うという条件もありましたので、すこし手間取りました。

接続のサンプルはいくつか見つけたのですが、リモートサーバ側のシェルを実行するサンプルはあまり無かったので、備忘録的に上げておきたいと思います。

なお、ローカルの接続テストのために、フリーのSFTPサーバーを立てたのですが、「freeSSHd」を利用させていただきました。
リモートサーバのバッチファイルを実行するには、接続するユーザの「Shell」実行権限が付いていないといけないので、注意してください。freeSSHdの設定画面で「Shell」実行権限が付いている場合、緑になっています。

以下は、実際のJavaサンプルです。

UserInfoの実装クラス

package jp.koji.jsch;
 
import com.jcraft.jsch.UserInfo;
 
public class MyUserInfo implements UserInfo {
    public String getPassword() {
        return null;
    }
    //PASSFRASEは空
    public String getPassphrase() {
        return "";
    }
    public boolean promptPassword(String arg0) {
        return true;
    }
    public boolean promptPassphrase(String arg0) {
        return true;
    }
    public boolean promptYesNo(String arg0) {
        return true;
    }
    public void showMessage(String arg0) {
    }
}

SampleTestクラス

ackage jp.koji.batch;
 
 
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.List;
 
import jp.koji.jsch.MyUserInfo;
 
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
 
public class JschTest {
 
    private static final String hostname = "XXXXXX";
    private static final String userid = "XXXXXXX";
 
    public static void main(String[] arg) throws JSchException, SftpException ,Exception{
 
        JSch jsch = new JSch();
 
        jsch.addIdentity("C:\PRIVATEKEY\keyname_pk");
 
        Session session = jsch.getSession(userid, hostname, 22);
 
        session.setUserInfo(new MyUserInfo());
 
        session.connect();
 
        //sftp MODEでの接続
        ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
        channel.connect();
 
        List list = channel.ls(".");
        System.out.println("---- ls");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
 
        channel.disconnect();
 
        //COMMAND実行 MODEでの接続
        ChannelExec channel2=(ChannelExec)session.openChannel("exec");
        channel2.setCommand("C:XXXXXXXXXXXSAMPLE.bat");
        channel2.connect();
        InputStreamReader inputStreamReader = null;
        inputStreamReader = new InputStreamReader( channel2.getInputStream(), "SJIS" );
        BufferedReader bufferedReader = null;
        bufferedReader = new BufferedReader( inputStreamReader );
        StringBuffer sblog = new StringBuffer("");
        while( true )
        {
            // 1文字取得
            int i = bufferedReader.read();
            if( i == -1 )
            {
                //-1で終了
                break;
            }
 
            // 出力
            sblog.append( (char)i );
        }
        System.out.println(sblog.toString());
        if (channel2.isClosed()) {
            System.out.println("status: "+channel2.getExitStatus());
        }
 
        channel2.disconnect();
 
 
        session.disconnect();
    }
}