0

プロジェクトの簡単な説明: JSF2 + Spring と動的データ ソースに基づいて構築されたアプリケーションがあります。データ参照コントロールは spring-config で作成されます:

<bean id="dataSource" class="com.xxxx.xxxx.CustomerRoutingDataSource">
....

およびクラス (上記参照):

public class CustomerRoutingDataSource extends AbstractRoutingDataSource {

@Override
protected Object determineCurrentLookupKey() {
    return CustomerContextHolder.getCustomerType();
}

public Logger getParentLogger() throws SQLFeatureNotSupportedException {
    return null;
}
}

上記で呼び出された CustomerContextHolder は次のとおりです。

public class CustomerContextHolder {

private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();

public static void setCustomerType(String customerType) {
    contextHolder.set(customerType);
}

public static String getCustomerType() {

    String manager = (String)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("dataBaseManager");

    if (manager != null) {
        contextHolder.set(manager);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("dataBaseManager", null);
    } else {
        String base =     (String)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("currentDatabBase");
        if (base != null)
            contextHolder.set(base);
    }
    return (String) contextHolder.get();
}

public static void clearCustomerType() {
    contextHolder.remove();
}
}

問題は、最後の人が FacesContext.getCurrentInstance() を呼び出してサーブレット コンテキストを取得していることです。説明するだけで、セッション属性 dataBaseManager を使用して、使用するベースを通知します。実際のソリューションでは問題なく動作していましたが、RESTEASY Web サービスの実装では、get リクエストを行うと FacesContext.getCurrentInstance() が明らかに null を返し、クラッシュします。

私はよく検索しましたが、@GET パラメータの外部からサーブレット コンテキストを取得する方法を見つけることができませんでした。それを取得する方法があるかどうか、または動的データソースの問題に対する別の解決策があるかどうかを知りたいです。

ありがとう!

4

1 に答える 1

1

魔法のようで、おそらくあまり知られていません。

Resteasy のドキュメントを詳しく調べたところ、resteasy jar に付属する springmvc プラグインの一部で、RequestUtil.class というクラスが含まれていることがわかりました。これで、「@Context HttpServletRequest req」パラメーターなしでメソッド getRequest() を使用できました。

それを使用して、要求属性に目的のデータベースを設定し、別のスレッド (Spring によって呼び出される) からそれを取得して、適切な場所からものをロードすることができました!

私は今それを1週間使用していますが、それは魅力のように機能します. 私がする必要があったのは、上記の determineLookupKey() を次のように変更することだけです。

    @Override
protected String determineCurrentLookupKey() {
    if (FacesContext.getCurrentInstance() == null) {
        //RESTEASY
        HttpServletRequest hsr = RequestUtil.getRequest();
        String lookUpKey = (String) hsr.getAttribute("dataBaseManager");
        return lookUpKey;
    }else{
        //JSF
        return CustomerContextHolder.getCustomerType();         
    }
}

これが他の人に役立つことを願っています!

チアゴ

于 2012-12-05T11:44:32.940 に答える