リッチクライアント技術におけるJavaScriptスクリプトの国際化
7854 ワード
現在のリッチクライアントには、JSPページと、リッチクライアントjsコンポーネント(extjsなど)でレンダリングされたコンポーネント化ウィンドウページの2つのセクションがあります.この2つの部分についてそれぞれ以下の処理を行う:のような形式でJSPページの部分に対してJSTL標準ライブラリのfmtタグを用いて示す、ここでmessageに対応するテキストはサービス側に配置され、webにある.xmlでリソースファイルの場所を設定するには、springラベル、Structsラベルなど多くのメカニズムを採用することもできます.ただし、今後のプログラム修正互換性のため、JSTLでJSPページの国際化を行うことを推奨します.JavaScriptでは、効率を上げるために静的リソースであるため、クライアントブラウザでのキャッシュを一定周期で容易に行うことができ、ブラウザによってキャッシュメカニズムが異なり、IEではjsファイルが一定の期限切れを定義することで、C:「Documents and Settings」ユーザー名「Local Settings」Temporary Internet Filesの下でキャッシュされ、Firefoxは、C:"Documents and Settings"のユーザ名"Local Settings"Application Data"Mozilla"Firefox"Profiles"XXXXXXXXXXXXXXXXである.default"Cacheは、クライアントリッチを実現するために統合された大きなjsをダウンロードするたびにキャッシュするのではなく、動的なページで生成することはできません(JavaScriptをJSPページにパッケージし、最も簡単なのは、js拡張子をjspに変更し、jspのメカニズムを利用して国際化することです)..そのため、JavaScriptの国際化されたコンテンツを変数で個別にロードする必要があります.例えば、var Message=function(){this.title='中国語タイトル';......};var msg = new Message();/******************************** または:var msg={title:‘中国語タイトル’;};*************************/new Ext.Window({ title : msg.title, width : 265, height : 140 }); ここでmsgオブジェクトの定義は、別のJavaScriptファイルで参照されるローカライズされたファイルによって定義されてもよいし、AJAXがJSONオブジェクトに戻る形でサービス側生成を取得または動的に行うこともできる.
2つの方法の長所と短所は次のように定義されています.
方法
欠点
メリット
フロントプロアクティブ定義
大量のばらばらなファイル(M個のJavaScriptファイルはオブジェクトN言語のリソースファイルを必要とし、総数M×N,これらのリソースファイルを1つのJavaScriptファイルに定義すると,クライアントにとって不要なリソースをダウンロードしすぎる)
リソース定義は非常に柔軟で、必要なリソースのみを定義し、コンテンツをいつでも変更できることを保証します.
バックグラウンド自動取得
サーバの負担が重くなり、AJAXやdwrのようなサービス側の動的ロードが必要になります.一定の複雑さを有する
バックグラウンドおよびJSPページと同じリソース定義ファイルを共有し、リソース定義ファイルを動的に生成することで、開発者の負担を軽減
以上、以下の国際化方法を採用することができる.
JavaScriptファイルの国際化は、次の2つの部分に分けられます.
一般的なテキスト定義については、「OK」、「戻る」など、フロントのリソースファイルに配置し、JavaScriptファイルとともにロードし、特殊なテキスト定義についてはバックグラウンドで自動的に取得する形式で表示することで、2つの方法の利点を組み合わせることができます.
バックグラウンドでは、次のように実現されます.
名前付き規則に従ってページのテキスト要素を定義し、次のjsonオブジェクトを動的に生成します.
{
messageName : messageValue
……
}
次に、フロントページJavaScriptは、ロード時にこのjsonオブジェクトを取得し、Extjsの使用方法などのページテキスト要素の定義に適用します.
var msg = Ext.util.json.decode(jsonString); あるいはサーバが動的に生成されるとvar msg={...}と表記される.の形式で、ヘッダファイルで動的なアドレス(dwrのように動的に生成するメカニズム)を指し、msg.XXXはテキスト定義を取得しました.以下のコードについて説明します.
Spring構成:
Web.xml構成:
使用方法:htmlページに機能jsより先に対応する言語jsをインポートし、名前は同じで、パスは/i 18 n/xxxである.jsはルートclasspathのi 18 n/messagesリソースの下でpageを同時に定義する.xxx.xxx
2つの方法の長所と短所は次のように定義されています.
方法
欠点
メリット
フロントプロアクティブ定義
大量のばらばらなファイル(M個のJavaScriptファイルはオブジェクトN言語のリソースファイルを必要とし、総数M×N,これらのリソースファイルを1つのJavaScriptファイルに定義すると,クライアントにとって不要なリソースをダウンロードしすぎる)
リソース定義は非常に柔軟で、必要なリソースのみを定義し、コンテンツをいつでも変更できることを保証します.
バックグラウンド自動取得
サーバの負担が重くなり、AJAXやdwrのようなサービス側の動的ロードが必要になります.一定の複雑さを有する
バックグラウンドおよびJSPページと同じリソース定義ファイルを共有し、リソース定義ファイルを動的に生成することで、開発者の負担を軽減
以上、以下の国際化方法を採用することができる.
JavaScriptファイルの国際化は、次の2つの部分に分けられます.
一般的なテキスト定義については、「OK」、「戻る」など、フロントのリソースファイルに配置し、JavaScriptファイルとともにロードし、特殊なテキスト定義についてはバックグラウンドで自動的に取得する形式で表示することで、2つの方法の利点を組み合わせることができます.
バックグラウンドでは、次のように実現されます.
名前付き規則に従ってページのテキスト要素を定義し、次のjsonオブジェクトを動的に生成します.
{
messageName : messageValue
……
}
次に、フロントページJavaScriptは、ロード時にこのjsonオブジェクトを取得し、Extjsの使用方法などのページテキスト要素の定義に適用します.
var msg = Ext.util.json.decode(jsonString); あるいはサーバが動的に生成されるとvar msg={...}と表記される.の形式で、ヘッダファイルで動的なアドレス(dwrのように動的に生成するメカニズム)を指し、msg.XXXはテキスト定義を取得しました.以下のコードについて説明します.
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.ResourceBundle;
import net.sf.json.JSONObject;
/** *//**
* , JSON , ,
* 。 Spring , bean ,
*
*
* * @author
*/
public class HierarchicalMessage {
/** *//** */
private String bundleName;
/** *//** */
private String prefix;
/** *//** */
private HashMap<String, JSONObject> cachingMap = new HashMap<String, JSONObject>();
/** *//** */
public void setBundleName(String bundleName) {
this.bundleName = bundleName;
}
/** *//** */
public void setPrefix(String prefix) {
this.prefix = prefix;
}
/** *//** ,( , )*/
public JSONObject getMessagesWithPrefix(Locale localeName){
return getMessagesWithPrefix(this.bundleName,this.prefix,localeName);
}
/** *//**
* , JSON
* */
public JSONObject getMessagesWithPrefix(String bundleName, String prefix, Locale localeName){
JSONObject toReturn;
// :i18n/messages$page.login$zh_CN
String cachingString = new StringBuilder().append(bundleName).append("$").
append(prefix).append("$").append(localeName.toString()).toString();
toReturn = cachingMap.get(cachingString);
if(toReturn != null){
return toReturn;
}
toReturn = new JSONObject();
// , Java
ResourceBundle rb = ResourceBundle.getBundle(bundleName, localeName);
Enumeration<String> e = rb.getKeys();
String keyRef = null;
String componentPrefix = new StringBuilder().append(prefix).append(".").toString();
int shortNameStartIndex = prefix.length() + 1;
while(e.hasMoreElements()){
keyRef = e.nextElement();
if(keyRef.startsWith(componentPrefix)){
toReturn.put(keyRef.substring(shortNameStartIndex), rb.getString(keyRef));
}
}
cachingMap.put(cachingString, toReturn);
return toReturn;
}
}
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import HierarchicalMessage;
public class I18nServlet extends HttpServlet {
/** *//**
* JavaScript
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
HierarchicalMessage hm = getHierarchicalMessage();
hm.setPrefix(new StringBuilder().append("page.").append(getBizId(request)).toString());
// session
String json = hm.getMessagesWithPrefix(request.getLocale()).toString();
out.print(new StringBuilder().append("var msg=").append(json).append(";"));
out.close();
}
private HierarchicalMessage getHierarchicalMessage() {
WebApplicationContext wc = WebApplicationContextUtils
.getWebApplicationContext(getServletContext());
HierarchicalMessage hm = (HierarchicalMessage)wc.getBean("msgBean");
return hm;
}
private String getBizId(HttpServletRequest request) {
StringBuffer urlString = request.getRequestURL();
int start = urlString.lastIndexOf("/") + 1;
int end = urlString.lastIndexOf(".");
return urlString.substring(start, end);
}
}
Spring構成:
<bean id="msgBean" class="HierarchicalMessage" scope="singleton">
<property name="bundleName">
<value>i18n/messages</value>
</property>
<property name="prefix">
<value>sys</value>
</property>
</bean>
Web.xml構成:
<servlet>
<servlet-name>I18nServlet</servlet-name>
<servlet-class>I18nServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>I18nServlet</servlet-name>
<url-pattern>/i18n/*</url-pattern>
</servlet-mapping>
使用方法:htmlページに機能jsより先に対応する言語jsをインポートし、名前は同じで、パスは/i 18 n/xxxである.jsはルートclasspathのi 18 n/messagesリソースの下でpageを同時に定義する.xxx.xxx