Localeによるdispatch先の選択2
この記事のコードには問題があります。正しくは Localeによるリソース選択Interceptorの問題解消 - Struts 2+Spring 2+Tiles+Acegi+iBatis+GWT+JUnit 4+JMockit でフルスタックJAVAフレームワークを参照してください。
Localeの設定によって選択可能にはなったけど、言語対応のファイルが無い場合は fallback用の場所へdispatchできるようにする。
こうすると、国際化で全く違うページだけそれぞれ用意して、メッセージが完全に外部リソース化されていてJSPが言語に依存しない共用できるページは共用部においておく事ができる。
LocaleResourceInterceptor.java
package jp.co.hershe.struts2.util; import java.net.URL; import java.text.MessageFormat; import java.util.Locale; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; import com.opensymphony.xwork2.util.ValueStack; /** * 国際化対応アプリケーション用のインターセプタ * * 結果を Locale 設定に従いそれぞれ固有のページで表示をする場合に * 利用する。 * * <result>$( localed.resource( "{0}/edit.jsp" ) }</result> * とすると Locale の Language が ja の場合 /ja/edit.jsp を探し * あればそちら、無ければ /edit.jsp を表示する。 * @author mikuni * */ public class LocaleResourceInterceptor extends AbstractInterceptor { public void destroy() { // TODO 自動生成されたメソッド・スタブ } public void init() { // TODO 自動生成されたメソッド・スタブ } // スタックに localed として自分を登録 public String intercept(ActionInvocation invocation) throws Exception { final ValueStack stack = invocation.getStack(); stack.set( "localed", this ); return invocation.invoke(); } // 置き換え処理を行う public String resource( String url ) throws Exception { Locale loc = ActionContext.getContext().getLocale(); String ans = MessageFormat.format(url, new Object[]{ "/"+loc.getLanguage(), "/"+loc.getCountry() } ); HttpServletRequest request = ServletActionContext.getRequest(); URL u = ServletActionContext.getServletContext().getResource(ans); if (u!=null) { return ans; } ans = MessageFormat.format(url, new Object[]{ "", "" } ); return ans; } }
こうして、Struts.xml に Interceptorを登録して
<interceptor name="locale" class="jp.co.hershe.struts2.util.LocaleResourceInterceptor"/>
さらにアクションで参照すると
<interceptor-ref name="locale" />
resultには次のように書く事で、 fallback付きでLocaleに応じたリソース選択ができる
<result>$( localed.resource( "{0}/list.jsp" )</result>
なので、TemplateResultと併せて result typeに次のように登録して
<result-types> <result-type name="templ" class="jp.co.hershe.struts2.util.TemplateResult" default="true"> <param name="template">${ localed.resource( "{0}#file#" ) }</param> <param name="key">#file#</param> </result-type> </result-types>
次のように書くと、 Localeが ja で /ja/list.jsp が存在する場合は /ja/list.jsp 無い場合は /list.jsp に dispatch する。
<result>/list.jsp</result>
2007-12-25: 問題が発覚したため、注意書きを加えました