javaee:@Resource注释不注入JNDI资源

时间:2015-04-03 20:59:41

标签: java-ee annotations tomcat7 jndi java-ee-7

以下是我的环境设置:
1. Apache Tomcat EE 1.6.2(Java EE 6认证)
2. Java 1.7.0_65
3. JAAS

A)WEB-INF / context.xml

<?xml version="1.0" encoding="UTF-8"?>
<context>
<!-- Use JAASRealm -->
<Realm className="org.apache.catalina.realm.JAASRealm" appName="JAASLoginModule"
    userClassNames="com.jaas.login.module.UserPrincipal" roleClassNames="com.jaas.login.module.RolePrincipal" />

<Resource name="ldapRes" 
          auth="Application"
          type="org.apache.directory.ldap.client.api.LdapNetworkConnection"
          factory="com.ldap.factory.services.LdapContextFactory"
          singleton="true" 
          java.naming.provider.url="ldap://127.0.0.1:389"
          java.naming.security.authentication="simple"
          java.naming.security.principal="cn=admin,dc=example,dc=com,dc=au"
          java.naming.security.credentials="a0120733@OPENLDAP" />
</context>

B)web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">

:

<resource-ref>
    <description>
        LDAP Resource
    </description>
    <res-ref-name>
        ldapResRef
    </res-ref-name>
    <lookup-name>
        java:comp/env/ldapRes
    </lookup-name>
  </resource-ref>

</web-app>

C)LdapContextFactory类

public class LdapContextFactory implements ObjectFactory {

public Object getObjectInstance(Object obj, Name name, Context nameCtx,
        Hashtable<?, ?> environment) throws Exception {

    System.out.println("getObjectInstance");
    Hashtable<Object, String> configurations = new Hashtable<Object, String>();
    Reference reference = (Reference) obj;
    Enumeration<RefAddr> references = reference.getAll();

    while (references.hasMoreElements()) {
        RefAddr address = references.nextElement();
        String type = address.getType();
        String content = (String) address.getContent();

        switch (type) {
        case Context.PROVIDER_URL:
            configurations.put(Context.PROVIDER_URL, content);
            break;
        case Context.SECURITY_AUTHENTICATION:
            configurations.put(Context.SECURITY_AUTHENTICATION, content);
            break;
        case Context.SECURITY_PRINCIPAL:
            configurations.put(Context.SECURITY_PRINCIPAL, content);
            break;
        case Context.SECURITY_CREDENTIALS:
            configurations.put(Context.SECURITY_CREDENTIALS, content);
            break;
        default:
            break;
        }
    }

    int startIndexIP = ((String) configurations.get(Context.PROVIDER_URL))
            .lastIndexOf("//") + 2;
    int lastIndexIP = ((String) configurations.get(Context.PROVIDER_URL))
            .lastIndexOf(':');
    String ldapHost = ((String) configurations.get(Context.PROVIDER_URL))
            .substring(startIndexIP, lastIndexIP);
    int ldapPort = Integer.parseInt(((String) configurations
            .get(Context.PROVIDER_URL)).substring(lastIndexIP + 1));

    return new LdapNetworkConnection(ldapHost, ldapPort);

}

}

D)JAASLoginModule类

public class JAASLoginModule implements LoginModule {
 :
public boolean login() throws LoginException {
    if (callbackHandler == null)
        throw new LoginException("no handler");

    NameCallback nameCall = new NameCallback("username: ");
    PasswordCallback passCall = new PasswordCallback("password: ", false);
    try {
        callbackHandler.handle(new Callback[]{nameCall, passCall});
    } catch (UnsupportedCallbackException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    System.out.println(nameCall.getName());
    System.out.println(passCall.getPassword());

    LdapConnection connection = new LdapResourceConnection().getLdapConnection();

    try {
        System.out.println(connection);
          :

 }

E)LdapResourceConnection类

public class LdapResourceConnection {

private LdapNetworkConnection ldapConnection;

public LdapConnection getLdapConnection() {
    System.out.println("GET ..");
    return ldapConnection;
}

@Resource(lookup="java:comp/env/ldapResRef")
public void setLdapConnection(LdapNetworkConnection ldapConnection) {
    System.out.println("SET ..");
    this.ldapConnection = ldapConnection;
}

}

问题:
在登录模块

LdapConnection connection = new LdapResourceConnection().getLdapConnection();

这无法运行LdapResourceConnection setLdapConnection()方法。我在这个命令上得到的只是“GET ..”被打印但不是“SET ..”。

请帮助。
感谢。

1 个答案:

答案 0 :(得分:1)

您的问题是您自己正在创建LdapResourceConnection,因此容器(应用程序服务器/ CDI)无法注入任何内容。

为了能够在bean中使用注入,这个bean应该由容器管理(创建/处理)。

要在登录模块上更正此问题,您应该注入LdapResourceConnection

@Inject
LdapResourceConnection ldapResourceConnection;
...
LdapConnection connection = ldapResourceConnection.getLdapConnection()