2

私は喜んで omnifacesFaces.getLocale()を使用して、現在ログインしているユーザーが使用するロケールを取得しています (これは、<f:view>定義から取得されます)。アプリケーションでのロケール選択の要件に適合するため、ビューからクライアント、システムのデフォルト ロケールへのフォールバック アプローチが非常に気に入っています。

  1. ユーザーがログインしている場合は、ユーザーの言語設定を使用します (バックエンド エンティティから取得)
  2. ユーザー設定が見つからない場合は、Accept-LanguagesHTTP ヘッダーから最高ランクの言語を使用します
  3. まだロケールを選択していない場合は、システムのデフォルトを使用してください。

今、私は JAX-RS (resteasy 実装) を使い始めましたが、バックエンド コードに現在のユーザーのロケールを提供するサービスを作成するのは非常に難しいと感じています。

は、 JAX-RS 要求処理中に存在しないFaces.getLocale()を必要とするため、使用できません。FacesContext

バックエンドコードがクラスをインスタンス化するときではなく、プロバイダー自体を使用するときにのみJAX-RSがそれらを注入するため、(ユーザーが優先するロケールを提供する)または(クライアントロケールへのアクセス)で@Context SecurityContext注釈を使用できません。@Provider@Context HttpHeaders

Localeまた、メソッド シグネチャにパラメータを散らかしたくありません。事実上、すべてにロケールが存在する必要があるからです。

具体的な例を挙げると、ユーザーの好みのロケールに応じて小さな NOTE フィールドを生成する vcard ジェネレーターがあります。JSF/EL 経由で vcard 生成メソッドを呼び出すことができます。

<h:commandLink action="#{vcfGenerator.forPerson(person)}" 
    value="Go" target="_blank" />

REST サービスを介して:

@GET @Path('person/{id:[1-9][0-9]*}/vcard')
@Produces('text/vcard')
String exportVcard(@PathParam('id') Long personId, @Context HttpHeaders headers) {
    VcfGenerator exporter = Component.getInstance(VcfGenerator) as VcfGenerator

    Person person = entityManager.find(Person, personId)
    if (! person)
        return Response.noContent().build()

    def locale = headers.acceptableLanguages[0] ?: Locale.ROOT
    return exporter.generateVCF(person, locale).toString()
}

これは動作します (VcfGeneratorを使用する一連の JSF 専用メソッドがありますFaces.getLocale()) が、維持するのは面倒です。したがって、オブジェクトを渡す代わりに、次のLocaleように言いたいと思います:

Vcard generateVCF(Person person) {
    Locale activeLocale = LocaleProvider.instance().getContext(VcfGenerator.class)
    ResourceBundle bundle = ResourceBundle.getBundle("messages", activeLocale, new MyControl())
    // use bundle to construct the vcard
}

誰かが同様の作業を行い、洞察を共有できますか?

4

1 に答える 1

0

これがしばらく前に投稿されたことは知っていますが、解決済みとしてマークされていないため、この特定のケースで機能する回避策を以下に示します。

  • @BalusC がここで説明しているように、最初にカスタム ResourceBundle が機能するようになりました
  • 次に、これから FacesContext が現在使用されているかどうかを検出するために、コンストラクターを更新しました。

    public Text() {
        setParent(ResourceBundle.getBundle(BUNDLE_NAME, 
        FacesContext.getCurrentInstance().getViewRoot().getLocale(), UTF8_CONTROL));
    }
    
  • これに:

    public Text() {
        FacesContext ctx = FacesContext.getCurrentInstance();
        setParent(ResourceBundle.getBundle(BUNDLE_NAME, 
        ctx != null ? ctx.getViewRoot().getLocale() : Locale.ENGLISH, UTF8_CONTROL));
    }
    

これは、JSF と JAX-RS の両方のコンテキストで機能するようになりました。

この助けを願って、

于 2014-04-23T14:31:50.213 に答える