Solon は異なるアプローチを取ります。i18n モジュール全体は 3 つのリゾルバー、1 つのアノテーション、そしてユーティリティクラスを中心に構築されています — XML 不要、インターセプター登録不要、ボイラープレート設定不要。
どのように動作するのか見てみましょう。
リソースの規約
メッセージファイルを resources/i18n/ に配置します:
resources/i18n/messages.properties # デフォルト (例: 中国語)
resources/i18n/messages_en_US.properties # 米語
resources/i18n/messages_ja_JP.properties # 日本語
Enter fullscreen mode Exit fullscreen mode
ファイル形式は標準的な Java プロパティです:
# messages_en_US.properties
login.title=Sign In
login.welcome=Welcome, {0}!
app.name=Solon Application
Enter fullscreen mode Exit fullscreen mode
これだけです。Bean 宣言も、場所の設定も必要ありません。Solon が自動的に検出します。
3 つのロケールリゾルバー、1 つのスイッチ
Solon には 3 つの組み込みロケールリゾルバーが用意されています。デフォルトは ヘッダーベース ですが、1 行で切り替え可能です。
1. ヘッダーリゾルバー (デフォルト)
Content-Language ヘッダーを読み取り、Accept-Language にフォールバックします:
# app.yml — 設定は不要で、すぐに動作します
Enter fullscreen mode Exit fullscreen mode
ヘッダー名をカスタマイズする場合:
@Configuration
public class I18nConfig {
@Bean
public LocaleResolver localeInit() {
LocaleResolverHeader resolver = new LocaleResolverHeader();
resolver.setHeaderName("lang"); // "lang" ヘッダーを読み取るようになります
return resolver;
}
}
Enter fullscreen mode Exit fullscreen mode
2. クッキーリゾルバー
デフォルトで SOLON.LOCALE という名前のクッキーからロケールを読み取ります:
@Configuration
public class I18nConfig {
@Bean
public LocaleResolver localeInit() {
return new LocaleResolverCookie();
}
}
Enter fullscreen mode Exit fullscreen mode
クッキー名をカスタマイズする場合:
resolver.setCookieName("lang");
Enter fullscreen mode Exit fullscreen mode
3. セッションリゾルバー
セッション属性からロケールを読み取ります:
@Configuration
public class I18nConfig {
@Bean
public LocaleResolver localeInit() {
return new LocaleResolverSession();
}
}
Enter fullscreen mode Exit fullscreen mode
属性名をカスタマイズする場合:
resolver.setAttrName("lang");
Enter fullscreen mode Exit fullscreen mode
4. カスタムリゾルバー
3 つのいずれもユースケースに合わない場合は、LocaleResolver を直接実装します:
@Component
public class QueryParamResolver implements LocaleResolver {
@Override
public Locale getLocale(Context ctx) {
String lang = ctx.param("lang");
if (lang != null) {
return LocaleUtil.toLocale(lang);
}
return Locale.getDefault();
}
@Override
public void setLocale(Context ctx, Locale locale) {
ctx.setLocale(locale);
}
}
Enter fullscreen mode Exit fullscreen mode
メッセージの読み取り方法は 3 通り
1. I18nUtil — クイックアクセス
どこでも使える静的メソッドでワンオフのルックアップ:
// 現在のリクエストコンテキストから (ロケールは自動的に解決されます)
String title = I18nUtil.getMessage("login.title");
// 特定の Locale を指定
String welcome = I18nUtil.getMessage(locale, "login.welcome", "Alice");
// Context オブジェクトを指定
I18nUtil.getMessage(ctx, "app.name");
Enter fullscreen mode Exit fullscreen mode
2. I18nService — 名前付きバンドルアクセス
特定のバンドルからメッセージが必要な場合:
I18nService loginI18n = new I18nService("i18n.login");
@Mapping("/greet")
public String greet(Locale locale) {
return loginI18n.get(locale, "login.welcome", "Alice");
}
Enter fullscreen mode Exit fullscreen mode
3. I18nBundle — プログラムによるバンドル
高度な用途では生のバンドルを取得します:
I18nBundle bundle = I18nUtil.getBundle("i18n.messages", locale);
String value = bundle.get("login.title");
String formatted = bundle.getAndFormat("login.welcome", "Alice");
Enter fullscreen mode Exit fullscreen mode
@I18n — テンプレート統合
コントローラーに @I18n を追加すると、すべてのテンプレートで i18n 変数が利用可能になります:
@I18n("i18n.login")
@Controller
public class LoginController {
@Mapping("/login")
public ModelAndView login() {
return new ModelAndView("login.ftl");
}
}
Enter fullscreen mode Exit fullscreen mode
バンドル名を指定しない場合、デフォルトで i18n.messages になります。
テンプレート構文の例
Freemarker (login.ftl):
<h1>${i18n["login.title"]}</h1>
<p>${i18n.getAndFormat("login.welcome", session.user.name)}</p>
Enter fullscreen mode Exit fullscreen mode
Thymeleaf:
<h1 th:text="${i18n.get('login.title')}">Sign In<h1>
<p th:text="${i18n.getAndFormat('login.welcome', 'Alice')}">Welcome!<p>
Enter fullscreen mode Exit fullscreen mode
Beetl:
<h1>${i18n["login.title"]}<h1>
<p>${@i18n.getAndFormat("login.welcome", "Alice")}<p>
Enter fullscreen mode Exit fullscreen mode
Enjoy:
<h1>#(i18n.get("login.title"))<h1>
<p>#(i18n.getAndFormat("login.welcome", "Alice"))<p>
Enter fullscreen mode Exit fullscreen mode
分散環境向けの拡張
翻訳を構成センターや CMS で管理するチーム向けに、I18nBundleFactory を実装します:
@Component
public class RemoteBundleFactory implements I18nBundleFactory {
@Override
public I18nBundle create(String bundleName, Locale locale) {
// リモート構成センターから取得
Props props = getRemoteProps(bundleName, locale);
return new I18nBundleImpl(props, locale);
}
}
Enter fullscreen mode Exit fullscreen mode
登録します:
I18nUtil.setBundleFactory(new RemoteBundleFactory());
Enter fullscreen mode Exit fullscreen mode
Solon の組み込み I18nBundleFactoryLocal は resources/i18n/ から読み取ります。ファクトリーアプローチにより、アプリケーションコードを変更せずに Redis、Nacos など任意のソースに切り替えることができます。
最小限の依存関係
solon-i18n モジュールは solon-core 以外の推移的依存関係がありません。solon-web を使用している場合、すでに含まれています。
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-i18n</artifactId>
</dependency>
Enter fullscreen mode Exit fullscreen mode
トレードオフ
得られないもの:
MessageSourceスタイルの階層はありません (Solon は名前ごとにフラットなバンドルを使用)- 開発モードでの自動リロードはありません (変更を反映するには再起動するか、ホットリロード付きのカスタム
I18nBundleFactoryを実装してください) - 組み込みの言語切り替えエンドポイントはありません (意図的にリゾルバーに委ねられています — クエリパラメータによる切り替えにはカスタム
LocaleResolverが必要です)
得られるもの:
- 60 秒以内で動作する i18n
- 3 つの本番対応リゾルバー戦略
- 5 つのエンジンにわたるファーストクラスのテンプレート統合
- 分散構成向けの拡張可能なファクトリーパターン
- XML ゼロ、インターセプターゼロ、手続きゼロ
まとめ
Solon の i18n モデルはフレームワークの哲学に従っています: 設定より規約、ただし必要に応じて切り替え可能。1 つの依存関係、テンプレート用に 1 つのアノテーション、プログラムによるアクセス用に 1 つのユーティリティ、そして 3 つのドロップインリゾルバーで、ほとんどの実世界のシナリオをカバーします。
MessageSource の設定で苦労している方は、ぜひ試してみてください — 意外と爽快です。
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.