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就是这样的。因此,这里的代码是不能运行,需要根据实际作一定的修改。