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() 来获取 servlet 上下文。只是为了解释一下,它使用会话属性 dataBaseManager 来告诉它应该使用哪个基础。对于实际的解决方案,它运行良好,但是通过 RESTEASY Web 服务的实现,当我们发出 get 请求时,FacesContext.getCurrentInstance() 显然返回 null 并崩溃。

我进行了很多搜索,但找不到从 @GET 参数之外获取 servlet-context 的方法。我想知道是否有任何方法可以得到它,或者我的动态数据源问题是否有另一种解决方案。

谢谢!

4

1 回答 1

1

就像魔术一样,可能没有多少人知道。

我深入研究了 Resteasy 文档,发现了 resteasy jar 附带的 springmvc 插件的一部分,它有一个名为 RequestUtil.class 的类。这样,我就可以在没有“@Context HttpServletRequest req”参数的情况下使用 getRequest() 方法。

使用它,我能够在请求属性上设置所需的数据库,并从另一个线程(由 spring 调用)获取它并从正确的位置加载内容!

我现在使用它一个星期,它就像一个魅力。我唯一需要做的就是将上面的 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 回答