インターセプタのバインド定義、com.google.inject.AbstractModule を実装時の
configureメソッドで記述したインターセプトが使用するリフレクション対象クラスを
指定させる先日のFtpInterceptor は気持ちわるい。
そこで、インターセプタを抽象クラスにして、インタセプトされるメソッドを記述
するクラスはこの抽象クラスを継承した上で、インタセプトMatcher に渡す3番目の
インスタンスは、new 抽象クラス名(){} で渡すトリッキーなことが必要である。
binder().bindInterceptor(Matchers.any()
,FtpInterceptMatcher.annotatedWith(FtpMethod.class)
,new FtpInterceptor(対象の.class));
としていたのを
binder().bindInterceptor(Matchers.any()
,FtpInterceptMatcher.annotatedWith(FtpMethod.class)
,new AbstractFtpInterceptor(){});
として、bindInterceptorの実行文を固定化する。
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
public abstract class AbstractFtpInterceptor implements MethodInterceptor{
@FTPClientDefine private FTPClient _ftpclient;
public FTPClient FTPClient(){
return this._ftpclient;
}
@Override
public Object invoke(MethodInvocation m) throws Throwable{
// パラメータチェック
String hostname = null;
String user = null;
String passwd = null;
Object args = m.getArguments();
Annotation[] anos = m.getMethod().getParameterAnnotations();
for(int n=0;n < anos.length;n++){
for(int k=0;k < anos[n].length;k++){
if (anos[n][k].annotationType().equals(FtpHost.class)){
hostname = (String)args[n];
}else if(anos[n][k].annotationType().equals(FtpUser.class)){
user = (String)args[n];
}else if(anos[n][k].annotationType().equals(FtpPasswd.class)){
passwd = (String)args[n];
}
}
}
// FTPClientは、ここで生成して、ログイン後、実装に引き渡す!
FTPClient ftpClient = new FTPClient();
// コネクション
ftpClient.connect(hostname);
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
throw new Exception("FTPClient not Positive reply!! value = "+String.valueOf(reply));
}
// ログイン
if (!ftpClient.login(user,passwd)){
throw new Exception("FTPClient Login NG!! user = "+user);
}
// バイナリモード
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// 実装に引き渡す!
Field ftpclientField = AbstractFtpInterceptor.class.getDeclaredField("_ftpclient");
ftpclientField.setAccessible(true);
ftpclientField.set(m.getThis(),ftpClient);
// メソッド実行
Object rtn = m.proceed();
// ログアウト、切断
if (ftpClient.isConnected()){
//ftpClient.logout();
ftpClient.disconnect();
}
return rtn;
}
}
FTPClient() を呼び出すことで、インタセプトされるメソッド内で FTPClient を
取得できるようにしてある。