同步LDAP和数据库的一个例子

这个博客展示了如何使用Java从LDAP获取数据,并同步到数据库。通过读取配置文件连接LDAP,进行分页搜索,然后将数据插入到数据库中,同时包含删除旧数据的逻辑。整个过程在一个定时任务中执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import  java.io.File;
import  java.io.FileInputStream;
import  java.io.IOException;
import  java.sql.CallableStatement;
import  java.sql.Connection;
import  java.util.ArrayList;
import  java.util.Date;
import  java.util.Hashtable;
import  java.util.List;
import  java.util.Properties;
import  java.util.Timer;
import  java.util.TimerTask;

import  javax.naming.Context;
import  javax.naming.NamingEnumeration;
import  javax.naming.directory.Attribute;
import  javax.naming.directory.SearchControls;
import  javax.naming.directory.SearchResult;
import  javax.naming.ldap.Control;
import  javax.naming.ldap.InitialLdapContext;
import  javax.naming.ldap.LdapContext;
import  javax.servlet.ServletException;

import  org.apache.log4j.Logger;

import  com.sun.jndi.ldap.ctl.PagedResultsControl;
import  com.sun.jndi.ldap.ctl.PagedResultsResponseControl;

/**
 * Servlet implementation class for Servlet: SyncLDAPServlet
 * 
 * @web.servlet name="SyncLDAPServlet" display-name="SyncLDAPServlet"
 * 
 * @web.servlet-mapping url-pattern="/SyncLDAPServlet"
 *  
 
*/

public   class  SyncLDAPServlet  extends  javax.servlet.http.HttpServlet  implements
        javax.servlet.Servlet 
{
    
/*
     * (non-Java-doc)
     * 
     * @see javax.servlet.http.HttpServlet#HttpServlet()
     
*/

    
private static Logger log = Logger.getLogger(SyncLDAPServlet.class);

    
private Connection con;
    
    
private static Hashtable env = null;

    List objList;

    
private String REMOVE_NEW_DATA = "";//Stored procedure name for removing data

    
private String INSERT_NEW_DATA = "";//Stored procedure name for insert new data

                     
private String LDAP_PROPERTY_FILE = "";//LDAP property file, which contains LDAP connection info


    
public void init() throws ServletException {
        
super.init();

        
this.con = null;
        
this.emeList = new ArrayList();

        
long interval = Long
                .valueOf(AppProperties.getProperty(
"LDAP.interval"))
                .longValue();
        Timer timer 
= new Timer();
        timer.schedule(
new TimerTask() {
            
public void run() {
                sncronizeEmployeeFromLDAP();
            }

        }
new Date(), interval);
    }


    
/**
     * This Servlet runs on WAS, so it get DB Connection from WAS
     * 
     * 
@param sql
     * 
@return
     
*/

    
private void setDBConnection() {
        
if (con == null{
            
try {
                     con 
= DataSourceFactory.getConnection();//Get DataSource con from appserver
                con.setAutoCommit(false);
                log.info(
"Connected to DB successfully!");
            }
 catch (Exception e) {
                log.error(
"Cannot connect to DB by AppServer", e);
            }

        }

    }


    
/**
     * 
     * 
@param sql
     * 
@return
     
*/

    
private CallableStatement getStatement(String sql) {
        CallableStatement smt 
= null;
        
if (con == null)
            
return null;
        
try {
            smt 
= con.prepareCall(sql);
        }
 catch (Exception ex) {
            log.error(
"Cannot create statement: " + sql, ex);
            
return null;
        }

        
return smt;
    }

        
    
/**
     * 
     *  
     
*/

    
private void getAllDataFromLDAP() {
        Properties ldapContextSettings 
= null;
        ldapContextSettings 
= new Properties();
        String filePath 
= null;
        
try {
            filePath 
= AppProperties.getProperty(this.LDAP_PROPERTY_FILE);
        }
 catch (NullPointerException e) {
            log.error(
"Cannot get LDAP Properties File.", e);
            
return;
        }

        FileInputStream in 
= null;
        
try {
            File file 
= new File(filePath);
            in 
= new FileInputStream(file);
            ldapContextSettings.load(in);
        }
 catch (IOException ioe) {
            log.error(
"Cannot open LDAP Property File: " + filePath, ioe);
            
return;
        }
 finally {
            
try {
                in.close();
            }
 catch (Exception excep) {
                log.error(
"Failed to close FileInputStream ", excep);
            }

        }
        
//         create LDAP Connection
        String INITIAL_CONTEXT_FACTORY = (String) ldapContextSettings
                .getProperty(
"INITIAL_CONTEXT_FACTORY");
        String PROVIDER_URL 
= (String) ldapContextSettings
                .getProperty(
"LDAP_SERVER_URL");        
        String userID 
= (String) ldapContextSettings
                .getProperty(
"LDAP_ACCOUNT_NAME");        
        
        String userPW 
= this.getPasswd(userID);//Replace this with your own password maker    
        
        Hashtable env 
= new Hashtable();
        env.put(Context.SECURITY_AUTHENTICATION, 
"simple");
        env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
        env.put(Context.PROVIDER_URL, PROVIDER_URL);
        env.put(Context.SECURITY_PRINCIPAL, userID);
        env.put(Context.SECURITY_CREDENTIALS, userPW);

        LdapContext ctx;
        
try {
            ctx 
= new InitialLdapContext(env, null);
        }
 catch (Exception othere) {
            log.error(
"User "" + userID+ "" cannot log on to LDAP with passwd ""
                    
+ userPW + "", so exit!",othere);
            
return;
        }

        log
                .info(
"User "" + userID
                        
+ "" has successfully logged on to LDAP Server at "
                        
+ new Date());

        objList 
= new ArrayList();
        
try {
            SearchControls controls 
= new SearchControls();
            String filter 
= "Your own filter";
            controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
            
int pageSize = 500;
            
try {
                ctx.setRequestControls(
new Control[] new PagedResultsControl(
                    pageSize) }
);//Paged Searching for >= 1000 records
            }
 catch (IOException e) {
                log.error(
"LDAP Context set request control error:", e);
            }

            
byte[] cookie = null;
            
int count = 0;
            
int pageCount = 0;
            NamingEnumeration results 
= null;
            SearchResult searchResult;
            javax.naming.directory.Attributes attrs;
            Attribute attr;
            
do {
                results 
= ctx.search("DC=your_own_name", filter,
                        controls);
                
if (results != null{
                    pageCount 
++;
                    
while (results.hasMore()) {
                        searchResult 
= (SearchResult) results.next();
                        attrs 
= searchResult.getAttributes();
                        
if (attrs != null{        
                        JavaBean jb 
= new JavaBean();
                        count
++;
                        
if ((attr = attrs.get("attName")) != null)
                                                                                                                                               jb.setAProperty((String) attr.getAll().next());
                                          objList.add(jb);                            }

                }


                
// Get the next LDAP page info
                cookie =
                    ((PagedResultsResponseControl) ctx
                        .getResponseControls()[
0])
                        .getCookie();
                
if (cookie != null{                    
                    log.info(
"-----------NEXT--PAGE("+pageCount+")-------");
                    
try {
                        ctx.setRequestControls(
                            
new Control[] {
                                 
new PagedResultsControl(
                                    pageSize,
                                    cookie,
                                    Control.CRITICAL)}
);
                    }
 catch (IOException e2) {
                        log.error(
"Failed to get next paged data from LDAP",e2);
                    }

                }
                
            }
 while (cookie != null);
            log.info(
"All Records Number: " + count);
        }
 catch (Exception err) {
            log.info(
"Get Data from LDAP Failed", err);
        }
 finally {
            
try {
                ctx.close();
            }
 catch (Exception closeErr) {
                log.error(
"Close LdapContext Failed", closeErr);
            }

        }

    }


    
/**
     * 
     * 
@param uid
     * 
@return
     
*/

    
private String getPasswd(String uid) {
        
//your own password maker
                                          return null;
    }


    
private void removeOldData() throws Exception {
        log.info(
"Remove old data at " + new Date());
        String sql 
= "{call " + this.REMOVE_OLD_DATA + "}";
        CallableStatement smt 
= this.getStatement(sql);
        smt.execute();
        smt.close();
    }


    
private void insertNewData() throws Exception {
        log.info(
"Insert new data at " + new Date());
        String sql 
= "{call " + this.INSERT_SS_EMPLOYEE + " (?)}";
        CallableStatement smt 
= this.getStatement(sql);
        
if (smt == null)
            
return;
        
int len = objList.size();
        JavaBean jb 
= null;
        
for (int i = 0; i < len; i++{
            jb 
= (JavaBean) objList.get(i);
            smt.setString(
1, jb.getAProperty());
            smt.addBatch();
        }

        smt.executeBatch();
        smt.close();
    }
    

                     
/**
                      **The main entrance for these operators
                     
*/

    
public void sncronizeEmployeeFromLDAP() {
        log.info(
"Start to Syncronize LDAP and DB at " + new Date());
        
this.getAllDataFromLDAP();
        
if ((objList == null|| (objList.size() < 1)) {
            log.error(
"No data got from LDAP, so exit!");
            
return;
        }

        log.info(
"The number of to update: " + objList.size());
        
this.setDBConnection();
        
if (con == null{
            log.error(
"Cannot connect to DB, so exit!");
            
return;
        }

        
try {
            
this.removeOldData();
            
this.insertNewData();
            con.commit();
        }
 catch (Exception e) {
            log.error(
"DB Operation Error, now try to roll back!", e);
            
try {
                con.rollback();
            }
 catch (Exception ex) {
                log.error(
"Roll back Error!", ex);
            }

        }
 finally {
            
try {
                con.close();
            }
 catch (Exception dbe) {
                log.error(
"Close DB connection Failed", dbe);
            }

        }

        log.info(
"End of Syncronizing at " + (new Date()));
    }

}
 Notice: 这只是我们一个完整项目中的一点,所以在代码中会用到其它包中的类或方法,我尽量避免了。如代码中的AppProperty就是这样的。因此,这里的代码是不能运行,需要根据实际作一定的修改。
<think>好的,我现在要帮助用户理解LDAP中的Connection DNDC的概念及用途。首先,我需要回忆一下LDAP的基本知识,确保自己对这些概念有正确的理解。 LDAP(轻量级目录访问协议)是一种用于访问维护目录服务的协议。在LDAP中,DN(Distinguished Name)是条目的唯一标识,而DC(Domain Component)是DN中的一部分,通常用于表示域名组件。用户的问题集中在Connection DNDC的含义与作用,需要详细解释这两个概念,并结合实际应用场景来说明。 首先,Connection DN应该指的是绑定LDAP服务器时使用的专有名称,也就是绑定DN。这个DN通常具有管理员权限,用于认证客户端到LDAP服务器的连接。例如,当应用程序需要连接到LDAP服务器进行用户查询或修改时,需要使用一个具有相应权限的DN来进行身份验证。这类似于数据库连接中的用户名,但结构更为复杂,因为它包含了层次结构的信息。 接下来是DC,即Domain Component,这是DN中的一种属性类型,用于表示域名的一部分。例如,在DN“cn=admin,dc=example,dc=com”中,dc=exampledc=com组合起来构成了域名example.com。DC在LDAP中用于构建目录信息树的层次结构,通常对应于组织的域名,帮助组织目录中的数据。 现在需要验证这些理解是否正确,并确保没有混淆其他概念,比如OU(Organizational Unit)或CN(Common Name)。例如,CN通常用来表示条目名称,而OU是组织单元,用于进一步分组条目。DC则是更高层次的结构,通常位于DN的最右侧,构成域名的各个部分。 然后,需要结合用户提供的引用内容。引用[1]提到LDAP作为主数据源,MySQL包含额外信息,这可能说明在集成系统中,Connection DN用于LDAP服务器的认证,而DC帮助定位目录中的基础结构。引用[2]提到了错误代码34,指出需要完整的DN,比如“cn=admin,dc=node3,dc=com”,这进一步强调了正确配置Connection DN的重要性,尤其是DC部分在构建完整DN中的作用。 接下来需要组织回答的结构,确保符合用户的要求:分点解释Connection DNDC,各自的作用,以及示例。同时,要引用提供的资料,特别是在解释Connection DN的配置错误时,可以引用[^2]中的例子,说明缺少DC会导致无效DN的错误。 可能还需要考虑用户的实际应用场景,比如在配置Spring应用程序连接LDAP时,如何正确设置Connection DNDC,避免常见错误。例如,在Spring配置中,spring.ldap.username应该使用完整的DN,包括所有DC部分,否则会导致认证失败。 最后,生成相关问题,确保问题与主题相关,并帮助用户深入理解。例如,如何配置LDAP连接、如何设计目录结构、常见错误及解决方法等。 总结思考步骤: 1. 确定Connection DN的定义作用,举例说明。 2. 解释DC的组成部分及其在DN中的位置,结合域名结构。 3. 使用用户提供的引用资料中的例子,说明配置错误的情况。 4. 结构清晰,分点回答,引用标注正确。 5. 生成相关问题,促进用户进一步学习。 现在需要将这些思考整理成符合要求的中文回答,使用正确的格式,确保行内公式独立公式正确应用(虽然这个问题可能较少涉及数学公式,但如果有需要的话)。同时,检查LaTeX语法是否正确,尽管这个问题可能不需要太多数学表达式,但如果有变量或代码,需正确使用格式。</think>### LDAP中Connection DNDC的概念及作用解析 #### 一、Connection DN(绑定专有名称) **定义**:Connection DN是客户端连接LDAP服务器时用于身份验证的完整专有名称(Distinguished Name)。它类似于数据库连接中的“用户名”,但包含层级结构信息,用于唯一标识一个目录条目。 **作用**: 1. **身份验证**:向LDAP服务器证明客户端权限(如管理员权限)[^2]。 2. **权限控制**:决定客户端可操作的目录范围内容。 **示例**: 若LDAP服务器的管理员条目为 `cn=admin,dc=node3,dc=com`,连接时应填写完整DN: ```properties spring.ldap.username=cn=admin,dc=node3,dc=com ``` 若缺少`dc`部分(如仅写`cn=admin`),会触发错误`LDAP: error code 34 - invalid DN`。 --- #### 二、DC(Domain Component) **定义**:DC是LDAP目录树中表示域名组件的属性类型,用于构建层级命名空间。 **作用**: 1. **目录结构设计**:通过域名分段(如`dc=example,dc=com`)组织目录条目,形成逻辑层次。 2. **数据定位**:帮助客户端快速定位特定域下的条目(如用户、组)。 **示例**: 公司域名为`node3.com`,其基础DN通常设计为`dc=node3,dc=com`,所有条目(如用户`cn=user1`)的完整DN为: $$ \text{cn=user1,ou=users,dc=node3,dc=com} $$ --- #### 三、实际应用场景 在集成LDAP数据库的系统中(如引用[^1]): 1. **Connection DN**用于安全连接LDAP主数据源。 2. **DC**定义数据存储的根路径,例如从`dc=node3,dc=com`开始同步用户信息到MySQL。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值