首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >从servlet获取DataSourceRealm实例

从servlet获取DataSourceRealm实例
EN

Stack Overflow用户
提问于 2015-05-19 07:59:39
回答 2查看 1.1K关注 0票数 0

我用的是Tomcat8.0。我在context.xml文件中配置了一个领域元素,它指定我将实现DataSourceRealm。此外,根据tomcat 8领域配置指令(https://tomcat.apache.org/tomcat-8.0-doc/realm-howto.html),我在王国元素中嵌套了一个CredentialHandler元素,以便指定属性,比如盐分长度和迭代。context.xml文件的相关部分如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<Realm className="org.apache.catalina.realm.DataSourceRealm" debug="99"
    dataSourceName="jdbc/board" localDataSource="true"
    userTable="test_user" userNameCol="Email" userCredCol="HashedPassword"
    userRoleTable="test_user_role" roleNameCol="Role">

        <CredentialHandler className="MessageDigestCredentialHandler" algorithm="SHA-1"
            iterations="1000" saltLength="48"/>

    </Realm>

当我在我的web应用程序中调用servlet时,我希望能够引用上面的领域对象,这样我就可以调用RealmBase类的非静态方法(例如:摘要()(而不是静态摘要()方法))。我想调用初始化的领域对象的摘要方法,因为它包含了我指定的所有属性(盐分长度等)。如何从servlet访问DataSourceRealm对象?(调用静态方法并手动指定哈希算法似乎不符合逻辑,更不用说静态方法中没有输入salt细节的参数这一事实了)。

我尝试在ServletContext和HttpServletRequest API中搜索检索RealmBase对象或容器对象的方法,但没有找到任何相关的方法。

编辑:我尝试获取InitialContext对象并使用lookup方法,因为这是我用来获取同样位于context.xml文件中的资源元素的方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
InitialContext ic = new InitialContext();
            DataSourceRealm realm = (DataSourceRealm) ic.lookup("org.apache.catalina.realm.DataSourceRealm");

但这也没用。

谢谢

EN

回答 2

Stack Overflow用户

发布于 2015-08-01 04:36:28

在上下文应用程序中,我们不使用类(等效),即不使用ic.lookup("org.apache.catalina.realm.DataSourceRealm")

但是命名为ic.lookup("jdbc/board")

(这是没有测试的,唯一的解决办法)

票数 0
EN

Stack Overflow用户

发布于 2016-02-11 10:18:37

这是一个古老的(呃)问题,但如果你愿意使用反射,这是可能的。下面的代码将从CredentialHandler中检索配置的ServletContext:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public CredentialHandler getCredentialHandler(ServletContext context) {

    Realm realm = getRealm(context);

    if (realm != null) {

        return realm.getCredentialHandler();
    }

    return null;
}

private Realm getRealm(ServletContext context) {

    if (context instanceof ApplicationContextFacade) {

        ApplicationContext applicationContext = getApplicationContext(
                (ApplicationContextFacade)context
        );

        if (applicationContext != null) {

            StandardContext standardContext = getStandardContext(
                    applicationContext
            );

            if (standardContext != null) {

                return standardContext.getRealm();
            }
        }
    }

    return null;
}

private ApplicationContext getApplicationContext(
        ApplicationContextFacade facade) {

    try {

        Field context = ApplicationContextFacade.class.getDeclaredField(
               "context"
        );

        if (context != null) {

            context.setAccessible(true);
            Object obj = context.get(facade);

            if (obj instanceof ApplicationContext) {

                return (ApplicationContext)obj;
            }
        }

    } catch (Exception ex) {
    }

    return null;
}

private StandardContext getStandardContext(
        ApplicationContext applicationContext) {

    try {

        Field context = ApplicationContext.class.getDeclaredField(
                "context"
        );

        if (context != null) {

            context.setAccessible(true);
            Object obj = context.get(applicationContext);

            if (obj instanceof StandardContext) {

                return (StandardContext)obj;
            }
        }

    } catch (Exception ex) {
    }

    return null;
}

您可以在应用程序的早期调用它,例如在ServletContextListener或ServletContainerInitializer中,并存储处理程序以供以后使用。

很丑,但我不认为还有别的办法。

戴夫

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30330576

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文