Java の interface method に public や abstract を宣言してもよいか
interface MyInterface { public abstract void myMethod(); // public と abstract の宣言 }
Oracle の Docs より
「してもよいが、冗長なので奨められない」
意訳(一部)
interface のメソッドは暗黙のうちに public である interface のメソッドは暗黙のうちに abstract である, なのでブロックは持たずセミコロンで表現されている必要がある public と abstract どちらか/両方 を interface のメソッドで宣言してもよいが、 冗長なので奨められるされるやり方ではない
意訳(一部)元
Every method declaration in the body of an interface is implicitly public. Every method declaration in the body of an interface is implicitly abstract, so its body is always represented by a semicolon, not a block. It is permitted, but discouraged as a matter of style, to redundantly specify the public and/or abstract modifier for a method declared in an interface.
struts.xml の global-exception-mappings とは何か
struts2-core v2.3.28
global-exception-mappings とは
はじめに、Struts2 には Exception mappings
という機能がある
これは Action
内で throw
された例外を自動的に catch
し
あらかじめ用意された result
へマッピングする機能である
この Exception mappings
で
どの result
へマッピングするかを定義する xml 属性が
global-exception-mappings
である
2 点注意が必要
1(X)
ローカルのマッピング(action.exception-mapping
)を定義できるが
これを有効化した時、グローバルのマッピング(global-exception-mappings
)は無効化される
2(Y)
あくまで action#class
の execute
内で発生した例外をマッピングするもので
action#class
のコンストラクタ内で throw
された例外はマッピングされない
具体的に
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <constant name="struts.devMode" value="true" /> <constant name="struts.ui.theme" value="simple" /> <package name="top" extends="struts-default"> <global-results> <result name="myException">/Exception.jsp</result> </global-results> <global-exception-mappings> <exception-mapping exception="java.lang.Exception" result="myException" /> </global-exception-mappings> <action name="index" class="jp.ymatsukawa.top.Index"> <result name="success">/index.jsp</result> </action> </package> </struts>
/top/index.action
へ GET リクエストされたとする
action#class=jp.ymatsukawa.top.Index
で Exception
が throw
された場合
global-exception-mappings
が Exception
を捕捉する
この時 exception-mapping#result
に対応する result
を実行する
上の場合だと result
は myException
なので
global-results.result#name="myException"
が実行される
(/Exception.jsp
が dispatch
される)
(X)
(動作確認より)
global-exception-mappings.exception-mapping
を定義後
action.exceptoin-mapping
を用いて
個々の action
に exception-mapping
を定義することができる
ただし、その場合は global-exception-mapping
の設定は無効になる
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <constant name="struts.devMode" value="true" /> <constant name="struts.ui.theme" value="simple" /> <package name="top" extends="struts-default"> <global-results> <result name="myException">/Exception.jsp</result> </global-results> <global-exception-mappings> <exception-mapping exception="java.sql.SQLException" result="myException" /> </global-exception-mappings> <action name="index" class="jp.ymatsukawa.top.Index"> <exception-mapping exception="java.lang.RuntimeException" result="error" /> <result name="success">/index.jsp</result> <result name="error">/myError.jsp></result> </action> </package> </struts>
もし jp.ymatsukawa.top.Index
で
java.sql.SQLException
が throw
されても
/Exception.jsp
は dispatch
されず
/myError.jsp
が dispatch
される
(global-exception-mappings.exception-mapping#exception=java.lang.Exception
でハンドリングをまとめておき、個々の action
で
Exception
以外の例外捕捉を必要に応じて追加するのが良いか...)
(Y)
jp.ymatsukawa.top.Index
のコンストラクタが 例外を throw
し得る場合
global-exception-mappings
はこの例外をマッピングしない
極端な例
package jp.ymatsukawa.top.Index; import com.opensymphony.xwork2.ActionSupport; public class Index extends ActionSupport { public Index() throws Exception { throw new Exception; } @Override public String execute() { return SUCCESS; } }
この場合、Struts2 は例外マッピング、例外ハンドリングすることなく、エラー処理を実行する
[参考元]
struts.xml global-results 要素とは何か
struts2-core v2.3.24.1
struts.xml global-results 要素とは何か
action
間で共有したい result
がある時、これを定義する為の要素
package
ごとにglobal-results
を定義できる- Struts2 は先ず ローカルの
result
(package.action.result
)を走査する- ローカルで
result
が見つからない場合、global-results
を走査する
- ローカルで
(要素の設置順序が決まっているようなので設定ミスしないように)(X)
具体的に
或る package の result#name="error"
を共通化する
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <constant name="struts.devMode" value="true" /> <constant name="struts.ui.theme" value="simple" /> <package name="top" extends="struts-default"> <global-results> <result name="error">/error.jsp</result> </global-results> <action name="index" class="jp.ymatsukawa.top.Index"> <result name="success">/index.jsp</result> </action> </package> </struts>
action
要素の前に global-results
を設定する
global-results
の下に共通化したい result
を設定する
global-results.result を action.result で上書きできるか
できる
上の例より result#name="error"
の時
/error.jsp
ではなく, /myError.jsp
を render させたい場合は
下のように設定する
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <constant name="struts.devMode" value="true" /> <constant name="struts.ui.theme" value="simple" /> <package name="top" extends="struts-default"> <global-results> <result name="error">/error.jsp</result> </global-results> <action name="index" class="jp.ymatsukawa.top.Index"> <result name="error">/myError.jsp</result> <result name="success">/index.jsp</result> </action> </package> </struts>
(X)要素の設定順序に注意
action
の前に global-results
を設定する
要素は上から順に以下の通りである
result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, default-class-ref?, global-results?, global-allowed-methods?, global-exception-mappings?, action*
[参考元]
https://struts.apache.org/docs/result-configuration.html#ResultConfiguration-GlobalResults
http://stackoverflow.com/questions/3742379/struts2-global-results-configuration-error
struts.xml default-interceptor-ref 要素とは何か
default-interceptor-stack 要素とは何か
package
内で定義した interceptor-stack
の内
package
の各アクションにてデフォルトで参照させたい
interceptor
を定義する
具体的に
下記 struts.xml より interceptor-stack
に ロギングが定義されている
(action はまだ interceptor
を参照していない)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <constant name="struts.devMode" value="true" /> <constant name="struts.ui.theme" value="simple" /> <package name="top" extends="struts-default"> <interceptors> <interceptor name="myLogging" class="jp.ymatsukawa.interceptors.Logger" /> <interceptor-stack name="myStackLogging"> <interceptor-ref name="myLogging" /> </interceptor-stack> </interceptors> <action name="index" class="jp.ymatsukawa.top.Index"> <result name="success">/index.jsp</result> </action> </package> </struts>
全 action
で package.interceptors.interceptor-stack#name="mystackLogging"
が参照されることになったので default-interceptor-ref
を使い、目的を達成する
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <constant name="struts.devMode" value="true" /> <constant name="struts.ui.theme" value="simple" /> <package name="top" extends="struts-default"> <interceptors> <interceptor name="myLogging" class="jp.ymatsukawa.interceptors.Logger" /> <interceptor-stack name="myStackLogging"> <interceptor-ref name="myLogging" /> </interceptor-stack> </interceptors> <default-interceptor-ref name="myStackLogging" /> <action name="index" class="jp.ymatsukawa.top.Index"> <result name="success">/index.jsp</result> </action> </package> </struts>
interceptors
を定義した後に
default-interceptor-ref#name="共通参照したい interceptor-stack"
を定義する
action
要素の下には interceptor-ref
の記載は入れない
default-interceptor-ref 定義後に
各 action で interceptor-ref を定義した時の挙動
default-interceptor-ref
を定義した後、各 action
で
interceptor-ref
を定義するとどうなるか
先に要約すると default-interceptor-ref
は実行されず
各 action
で定義された interceptor-ref
が実行される
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <constant name="struts.devMode" value="true" /> <constant name="struts.ui.theme" value="simple" /> <package name="top" extends="struts-default"> <interceptors> <interceptor name="myLogging" class="jp.ymatsukawa.interceptors.Logger" /> <interceptor name="myOtherLogging" class="jp.ymatsukawa.interceptors.OtherLogger" /> <interceptor-stack name="myStackLogging"> <interceptor-ref name="myLogging" /> </interceptor-stack> </interceptors> <default-interceptor-ref name="myStackLogging" /> <action name="index" class="jp.ymatsukawa.top.Index"> <interceptor-ref name="myOtherLogging" /> <result name="success">/index.jsp</result> </action> </package> </struts>
default-interceptor-ref(myLogging)
> action.interceptor-ref(myOtherLogging)
が実行されると思いきや
action.interceptor-ref(myOtherLogging)
のみ実行される
[参考元]
https://struts.apache.org/docs/how-do-we-configure-an-interceptor-to-be-used-with-every-action.html
struts.xml interceptor-stack 要素とは何か
interceptor-stack 要素とは何か
interceptors.interceptor
をひとまとまり に定義したもの
利用により、汎用的に interceptor
を interceptor-ref
で参照できる
具体的に
- interceptor が
- ロギング
- DB コネクション処理
の 2 つで定義されているとする
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <constant name="struts.devMode" value="true" /> <constant name="struts.ui.theme" value="simple" /> <package name="top" extends="struts-default"> <interceptors> <interceptor name="myLogging" class="jp.ymatsukawa.interceptors.Logger" /> <interceptor name="myDBConnection" class="jp.ymatsukawa.interceptors.DBConnection" /> </interceptors> <action name="index" class="jp.ymatsukawa.top.Index"> <interceptor-ref name="myLogging" /> <interceptor-ref name="myDBConnection" /> <result name="success">/index.jsp</result> </action> </package> </struts>
action
が新規追加されるごとに action#name="index"
の
interceptor-ref
がコピペされそうである
汎用的に これらまとまり(interceptors.interceptor
) を参照できる形式にしよう
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <constant name="struts.devMode" value="true" /> <constant name="struts.ui.theme" value="simple" /> <package name="top" extends="struts-default"> <interceptors> <interceptor name="myLogging" class="jp.ymatsukawa.interceptors.Logger" /> <interceptor name="myDBConnection" class="jp.ymatsukawa.interceptors.DBConnection" /> <interceptor-stack name="myStackDBCon"> <interceptor-ref name="myLogging" /> <interceptor-ref name="myDBConnection" /> </interceptor-stack> </interceptors> <action name="index" class="jp.ymatsukawa.top.Index"> <interceptor-ref name="myStackDBCon" /> <result name="success">/index.jsp</result> </action> </package> </struts>
struts.package.interceptors.interceptor
の下に
interceptor-stack
を追加interceptor-stack#name
に 各action
のinterceptor-ref
が参照する名前を命名
[参考元]
https://struts.apache.org/docs/interceptors.html#Interceptors-StackingInterceptors