パスワード入力無しでscp
expect -c "spawn scp /home/user1/source1.txt user2@targetHost://home/user2/source1.txt ; expect password: ; send user2PASSWORD\r ; expect $ ; exit"
expect -c "spawn scp /home/user1/source2.txt user2@targetHost://home/user2/source2.txt ; expect password: ; send user2PASSWORD\r ; expect $ ; exit"
echo 'normal termination.'
exit 0
Fiddler で "The system proxy was changed. Click to reenable capturing" の回避
OnBoot() に処理追加、以下の function を追加する。
https://feedback.telerik.com/fiddler/1410460-the-system-proxy-was-changed-click-to-reenable-capturing
https://gist.github.com/ericlaw1979/decab196fe127cd9e548b7f675cf22c9
static function OnBoot() {
FiddlerApplication.oProxy.add_DetachedUnexpectedly(DoReattach);
}
// Just before the OnBoot function, add the following new functions:
static function DoReattach(o: Object, ea: EventArgs) {
FiddlerObject.UI.sbpInfo.Text = "Scheduling automatic reattach at " + new Date();
// Reattach after 1 second; waiting 1 second increases the odds that whatever
// process was messing with the system settings is done doing that.
ScheduledTasks.ScheduleWork("reattach", 1000, innerReattach);
}
static function innerReattach() {
FiddlerApplication.UI.actAttachProxy();
}
static function OnRetire() {
// Detach this event handler to avoid memory leaks and duplicate processing.
FiddlerApplication.oProxy.remove_DetachedUnexpectedly(DoReattach);
}
内側で例外、外側でcommitしたい場合。
[spring]10.5 Declarative transaction management
https://minokuba.hatenablog.com/entry/20110501/1304265347
内側で例外(rollbackしか出来ない状態)、外側で握ってcommitしたい場合。
TransactionStatus transactionStatus = TransactionAspectSupport.currentTransactionStatus();
if(transactionStatus.isRollbackOnly() && !transactionStatus.isCompleted()){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
Springでファイルダウンロード
ControllerからResponseEntityを戻す。
SqlMapに動的SQLを書く。
WHERE <dynamic> 1 = 1 <isNotNull prepend="AND" property="arg_1"> column_1 <![CDATA[>=]]> #arg_1# </isNotNull> <isNotEmpty prepend="AND" property="arglist_2"> column_2 IN <iterate open="(" close=")" property="arglist_2" conjunction=",">#arglist_2[]#</iterate> </isNotEmpty> </dynamic>
Orion SSH-2 を使用してput/get
APIにput/getがないので、bufferをread/writeすることになります。
import java.io.File; import java.io.IOException; import org.apache.log4j.Logger; import com.trilead.ssh2.Connection; import com.trilead.ssh2.ConnectionMonitor; /** * SSH-2接続をサポートするクラスです。<br> */ public class SshConnection implements ConnectionMonitor { private static final Logger log = Logger.getLogger(SftpOperator.class); /** 接続リトライ数 */ private int retry; /** 接続リトライ間隔(msec) */ private long waitMillis; // TODO どう使う? @Override public void connectionLost(Throwable throwable) { log.info("SSH: lost connection!"); } /** * コンストラクタです。 */ public SshConnection(int retry, long waitMillis) { this.retry = retry; this.waitMillis = waitMillis; } /** * IDパス認証で接続します。 */ public Connection connect(String host, int port, String user, String password) throws IOException { return connect(host, port, user, password, null, null); } /** * 鍵認証で接続します。 */ public Connection connect(String host, int port, String user, String keyfileName, String keyfilePass) throws IOException { return connect(host, port, user, null, keyfileName, keyfilePass); } /* * 接続します。 */ private Connection connect(String host, int port, String user, String password, String keyfileName, String keyfilePass) throws IOException { Exception returnException = null; boolean isAuthenticated = false; Connection connection = null; log.debug("connect to " + user + "@" + host + ", retry=" + this.retry + "times, wait=" + this.waitMillis + "msec"); for (int i = 0; i < this.retry; i++) { // リトライ処理 returnException = null; try { // connect時の ServerHostKeyVerifier は、nullのためHostKeyはチェックされない connection = new Connection(host, port); connection.connect(); if (keyfileName == null || keyfileName.isEmpty()) { log.debug("IDパス認証"); isAuthenticated = connection.authenticateWithPassword(user, password); } else { log.debug("鍵認証"); isAuthenticated = connection.authenticateWithPublicKey(user, new File(keyfileName), keyfilePass); } break; // 認証処理が行われた。 } catch (Exception e) { log.info("connect failed:" + e.toString()); returnException = e; } if (this.waitMillis > 0L && i < (this.retry - 1)) { try { log.trace("wait:" + this.waitMillis + "msec"); Thread.sleep(this.waitMillis); } catch (InterruptedException ie) {;} } } if (returnException != null) {throw new IOException("接続失敗:", returnException);} if (!isAuthenticated) {throw new IOException("認証失敗");} return connection; } }
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import org.apache.log4j.Logger; import com.trilead.ssh2.Connection; import com.trilead.ssh2.SFTPException; import com.trilead.ssh2.SFTPv3Client; import com.trilead.ssh2.SFTPv3FileAttributes; import com.trilead.ssh2.SFTPv3FileHandle; /** * SFTP クライアントクラスです。<br> */ public class SftpOperator { private static final Logger log = Logger.getLogger(SftpOperator.class); /** * SFTP クライアントを生成します。<br> */ public static SFTPv3Client creat(Connection connection) throws IOException { return new SFTPv3Client(connection); } /** * リモートファイルを取得します。<br> * ローカルファイルには受信可能であること。 * @param sftp SFTPv3Client * @param remoteFileName リモートファイル名(パス含む) * @param localFileName ローカルファイル名(パス含む) */ public static boolean get(final SFTPv3Client sftp, final String remoteFileName, final String localFileName) { // リモートファイルチェック long remoteFileLength = 0L; try { SFTPv3FileAttributes attributes = sftp.stat(remoteFileName); if (attributes.isDirectory()) { log.warn("リモートファイル(" + remoteFileName + ")はディレクトリ"); return false; } remoteFileLength = sftp.stat(remoteFileName).size.longValue(); } catch (IOException ioe) { log.warn("リモートファイル(" + remoteFileName + ")エラー:" + ioe.toString()); return false; } // open remote file with read only SFTPv3FileHandle sftpFileHandle = null; try { sftpFileHandle = sftp.openFileRO(remoteFileName); } catch (IOException ioe) { log.warn("リモートファイル(" + remoteFileName + ") open error:" + ioe); return false; } // remoteFile read -> localFile write BufferedOutputStream bos = null; try { bos = new BufferedOutputStream(new FileOutputStream(localFileName)); byte[] buffer = new byte[1024 * 8]; // No more than 32768 bytes may be read at once. long offset = 0; int readLength = 0; while ((readLength = sftp.read(sftpFileHandle, offset, buffer, 0, buffer.length)) != -1) { bos.write(buffer, 0, readLength); offset += readLength; } bos.flush(); } catch (IOException ioe) { log.warn("取得失敗:" + ioe); return false; } finally { silentClose(bos); try { if (sftp != null) {sftp.closeFile(sftpFileHandle);} } catch (IOException ioe) {log.warn(remoteFileName + " close 失敗:" + ioe.toString());} } // ファイルサイズチェック File localFile = new File(localFileName); if (localFile.length() != remoteFileLength) { log.warn("サイズ不正: リモート:" + remoteFileLength + ", ローカル:" + localFile.length()); localFile.delete(); return false; } log.debug("取得: " + remoteFileLength + "byte : " + remoteFileName + " --> " +localFileName); return true; } /** * ローカルファイルを転送します。<br> * ローカルファイルは送信可能であること。<br> * * @param sftp SFTPv3Client * @param remoteFileName リモートファイル名(パス含む) * @param localFileName ローカルファイル名(パス含む) */ public static boolean put(final SFTPv3Client sftp, final String remoteFileName, final String localFileName) { // リモートファイルチェック try { SFTPv3FileAttributes attributes = sftp.stat(remoteFileName); if (attributes.isDirectory()) { log.warn("リモートファイル(" + remoteFileName + ")はディレクトリ"); return false; } log.debug("リモートファイル(" + remoteFileName + ") " + "は存在します。上書きます。"); } catch (IOException ioe) { if (ioe instanceof SFTPException) { SFTPException sftpe = (SFTPException) ioe; // SFTPException.ErrorCode == 2(No such file) is OK. if (sftpe.getServerErrorCode() != 2) { log.warn("リモートファイル(" + remoteFileName + ") SFTPエラー:" + sftpe.toString()); return false; } } else { log.warn("リモートファイル(" + remoteFileName + ") 転送エラー:" + ioe.toString()); return false; } } SFTPv3FileHandle sftpFileHandle = null; try { // create remote file sftpFileHandle = sftp.createFile(remoteFileName); } catch (IOException e) { log.warn("リモートファイル(" + remoteFileName + ") " + "作成エラー:" + e.toString()); return false; } BufferedInputStream filein = null; try { // load local file. filein = new BufferedInputStream(new FileInputStream(localFileName)); // Write bytes to a file. If len > 32768, then the write operation // will be split into multiple writes. byte[] buffer = new byte[1024]; long offset = 0; int readLength = 0; while ((readLength = filein.read(buffer)) != -1) { sftp.write(sftpFileHandle, offset, buffer, 0, readLength); offset += readLength; } } catch (IOException ioe) { log.warn("送信失敗:" + ioe.toString()); return false; } finally { silentClose(filein); try { if (sftp != null) {sftp.closeFile(sftpFileHandle);} } catch (IOException ioe) { log.warn(remoteFileName + " close error:" + ioe.toString()); } } // compare size. try { long remoteFileLength = sftp.stat(remoteFileName).size.longValue(); File localFile = new File(localFileName); if (remoteFileLength != localFile.length()) { sftp.rm(remoteFileName); log.warn("サイズ不正: リモート:" + remoteFileLength + ", ローカル:" + localFile.length()); return false; } } catch (IOException ioe) { log.warn("転送エラー:" + ioe.toString()); return false; } log.debug("送信:" + localFileName); return true; } /** * 接続を閉じます。<br> * IOExceptionが発生してもthrowしません。<br> * @param closeable */ public static void silentClose(Closeable closeable) { try { if (closeable != null) {closeable.close();} } catch (IOException ioe) {log.warn("close error:" + ioe.toString());} } }
文字列16進ダンプ
public static String string2Hex(String src) { StringBuffer sb = new StringBuffer(); try { for (byte b : src.getBytes("Windows-31J")) { String s = Integer.toHexString(0xff & b); if (s.length() == 1) { sb.append("0"); } sb.append(s); sb.append(" "); } } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } return sb.toString(); }