Javaリフレクションを使ってみた
リフレクションって慣れないけれど面白い。
いくつかメモメモ。
こんな感じでクラスを作り、リフレクションで情報を取得してみました。
【作ったクラス】
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
static class ADto implements BaseDto{
private static String q ="hoge";
public String s=null;
public int i=10;
BDto b=new BDto();
final String qa ="hogehoge";
}static class BDto implements BaseDto{
public static String q ="hogeb";
public String s=" bb ";
public int i=20;
}
【調べたメソッド】
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
for(Field f : returnObject.getClass().getDeclaredFields()){
System.out.println(f.toString());
System.out.println(f.getDeclaringClass());
System.out.println(f.getType());
System.out.println(f.getClass());
}
【結果】
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
hoge
private static java.lang.String kkk.comon.interceptor.SqlCheckInterceptor$ADto.q
class kkk.comon.interceptor.SqlCheckInterceptor$ADto
class java.lang.String
class java.lang.reflect.Field
10
public int kkk.comon.interceptor.SqlCheckInterceptor$ADto.i
class kkk.comon.interceptor.SqlCheckInterceptor$ADto
int
class java.lang.reflect.Field
kkk.comon.interceptor.SqlCheckInterceptor$BDto@e09713
kkk.comon.interceptor.SqlCheckInterceptor$BDto kkk.comon.interceptor.SqlCheckInterceptor$ADto.b
class kkk.comon.interceptor.SqlCheckInterceptor$ADto
class kkk.comon.interceptor.SqlCheckInterceptor$BDto
class java.lang.reflect.Field
hogeb
public static java.lang.String kkk.comon.interceptor.SqlCheckInterceptor$BDto.q
class kkk.comon.interceptor.SqlCheckInterceptor$BDto
class java.lang.String
class java.lang.reflect.Field
bb
public java.lang.String kkk.comon.interceptor.SqlCheckInterceptor$BDto.s
class kkk.comon.interceptor.SqlCheckInterceptor$BDto
class java.lang.String
class java.lang.reflect.Field
20
public int kkk.comon.interceptor.SqlCheckInterceptor$BDto.i
class kkk.comon.interceptor.SqlCheckInterceptor$BDto
int
class java.lang.reflect.Field
hogehoge
final java.lang.String kkk.comon.interceptor.SqlCheckInterceptor$ADto.qa
class kkk.comon.interceptor.SqlCheckInterceptor$ADto
class java.lang.String
class java.lang.reflect.Field
S2StrutsでFormをSessionに格納する
Sessionへの格納は、
@ExportToSessionを書くと実行できます。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
ですがFormはこうかいても、Sessionに格納とはなりません。
下記S2Strutsリファレンスを元に、Actionクラスのアノテーション、
@StrutsActionの書き方を変えないといけません。
デフォルトではリクエストで生成されるようです。
@StrutsAction(name="HogeForm",scope=ScopeType.SESSION)
public interface HogeAction extends Root{
【参考URL】
http://s2struts.seasar.org/ja/1.2/s2struts.html#ZeroConfigReference
Seasarで、独自Interceptorを複数使用する
ログインチェックを行うInterceptorと、
実行Actionクラス名を開始と終了のタイミングで出力するTraceInterceptorを作成。
TraceInterceptorは、プロパティファイルから該当する名前を取ってこれるようにしました。
【TraceInterceptor】--------------------------------------------
public class TraceInterceptor extends AbstractInterceptor {private static final long serialVersionUID = 1L;
public Object invoke(MethodInvocation methodinvocation) throws Throwable {
// logicNameプロパティファイルを取得
MessageResources mr = MessageResources
.getMessageResources("hoge.comon.file.logicName");
//実行ActionImplクラス名を取得
String className = getTargetClass(methodinvocation).getSimpleName();
//logicName.propertiesファイルから該当する処理名を取得
String logicName = mr.getMessage(className);
//Action開始をログ出力
System.out.println("----" + logicName + "(" + className
+ ") を開始しました----");
//対象メソッドを実行
Object returnObject = methodinvocation.proceed();
//Action終了をログ出力
System.out.println("----" + logicName + "(" + className
+ ") を終了しました----");
return returnObject;
}}
【diconファイル】--------------------------------------------
AspectAutoRegisterへの登録は、別々に書きます。
<!-- LoginInterceperを適用 -->
<component name="loginInterceptor" class="hoge.comon.interceptor.LoginInterceptor"/>
<!-- TraceInterceptorを適用 -->
<component name="traceInterceptor" class="hoge.comon.interceptor.TraceInterceptor"/><component class="org.seasar.framework.container.autoregister.AspectAutoRegister">
<property name="interceptor">traceInterceptor</property>
<initMethod name="addClassPattern">
<arg>"hoge"</arg>
<arg>".*ActionImpl"</arg>
</initMethod>
</component>
<component class="org.seasar.framework.container.autoregister.AspectAutoRegister">
<property name="interceptor">loginInterceptor</property>
<initMethod name="addClassPattern">
<arg>"hoge"</arg>
<arg>".*ActionImpl"</arg>
</initMethod>
<initMethod name="addIgnoreClassPattern">
<arg>"hoge"</arg>
<arg>"TopActionImpl"</arg>
</initMethod>
</component>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Topページは、ログインチェックから除外しています。
Seasarでトランザクション制御
S2daoでは、どのタイミングでロールバックするのか調べてみました。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
ActionImpl内で、下記2つのSQLを続けて実行します。
2つ目でエラーが出る仕様ですが、
エラーが出た後も1つ目のUPDATEがロールバックされることはありません。
これでは困ってしまいます。。
1Action1トランザクションにするためにはどうすればいいか。。
下記URLを参考に学習。
今回は、実行メソッドが
「innerProc」であること、
AspectAutoRegisterを利用していることから、diconファイルは以下のようになります。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
<component class="org.seasar.framework.container.autoregister.AspectAutoRegister">
<property name="interceptor">j2ee.requiredTx</property>
<property name="pointcut">"innerProc"</property>
<initMethod name="addClassPattern">
<arg>"hoge"</arg>
<arg>".*ActionImpl"</arg>
</initMethod>
</component>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
これで見事、1Action1トランザクションが実行できました!
★ログの感じ
DEBUG 2010-04-15 16:23:29,328 [http-8080-2] トランザクションを開始しました
DEBUG 2010-04-15 16:23:29,343 [http-8080-2] 論理的なコネクションを取得しました
DEBUG 2010-04-15 16:23:29,343 [http-8080-2] UPDATE TABLE1 SET name = 'yhohoa', dep_code = 100, address_code = '11200001' WHERE name_id = 1
DEBUG 2010-04-15 16:23:29,343 [http-8080-2] 論理的なコネクションを閉じました
DEBUG 2010-04-15 16:23:29,359 [http-8080-2] 論理的なコネクションを取得しました
DEBUG 2010-04-15 16:23:29,359 [http-8080-2] UPDATE TABLE1 SET name = null, dep_code = 100, address_code = '11200001' WHERE name_id = 1
DEBUG 2010-04-15 16:23:29,390 [http-8080-2] 論理的なコネクションを閉じました
DEBUG 2010-04-15 16:23:29,421 [http-8080-2] トランザクションをロールバックしました
2010-04-15 16:23:29,421 [http-8080-2] ERROR org.apache.struts.action.RequestProcessor - Execute action
org.seasar.framework.exception.SQLRuntimeException: [ESSR0071]SQLで例外・・・(以下省略)
【参考URL】
http://ml.seasar.org/archives/seasar-user/2006-March/003405.html
seasar2.4.41 とS2-struts1.2.12 を一緒に使う時の注意点
S2-struts1.2.12のブランクプロジェクトをDLして、そこにS2.4.41
を入れると色々問題がありました
【1】
S2-struts1.2.12は2.3系
⇒2.4系に変更すると色々エラーでる
(Ⅰ)Servletは2.3⇒2.4に上げる必要があります
(Ⅱ)javassist-3.0.jar⇒javassist-3.4.ga
【2】geronimo-jta_1.1_spec-1.0.jar をいれる
【3】
jdbc.dicon を作る
※j2ee.diconを自力で作らない。JAR内にあるものを利用します。
※2.4系から、j2ee.diconを3分割したそうです。
【参考URL】http://ml.seasar.org/archives/seasar-user/2007-December/012085.html
<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container//EN"
"http://www.seasar.org/dtd/components.dtd">
<components namespace="jdbc">
<include path="jta.dicon"/>
<component class="org.seasar.extension.jdbc.impl.BasicResultSetFactory"/>
<component class="org.seasar.extension.jdbc.impl.BasicStatementFactory"/>
<component name="xaDataSource"
class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
<property name="driverClassName">
"com.ibm.db2.jcc.DB2Driver"
</property>
<property name="URL">
"jdbc:db2://localhost:50000/SAMPLE"
</property>
<property name="user">"db2admin"</property>
<property name="password">"zaq12wsx"</property>
<initMethod name="addProperty">
<arg>"currentSchema"</arg>
<arg>"AA000000"</arg>
</initMethod>
</component><component name="connectionPool"
class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
<property name="timeout">600</property>
<property name="maxPoolSize">10</property>
<!-- JTAトランザクションが開始されていない場合にコネクションを
取得できないようにするには次のプロパティをfalseにしてください.-->
<property name="allowLocalTx">true</property>
<destroyMethod name="close"/>
</component>
<component name="dataSource"
class="org.seasar.extension.dbcp.impl.DataSourceImpl"/>
</components>