客戶近期頻繁要求修改組織機構,維護部門苦不堪言。更新組織機構就要更新郵箱的通訊錄,使用的應該是某流行的郵件系統,php的,版本挺老的,其中有個功能,在寫收件人的時候輸入的東西會autocomplate,這個東西維護部門需要維護一個超大的文件夾,如下圖:一級目錄是第一個字,二級目錄是前兩個字,三級目錄是前三個字,以此類推,其中每個文件夾下包含一個result.php文件,內容為該級目錄中所對應的全部人員。

那我需要做什麼呢?對,幫助他們生成這個東西。縷了一下思路,需要用到ldap、freemark的知識。
Spring大家應該不陌生,這裡ldap數據的讀取,我選用的是Spring的ldapTemplate 1.3.1,配置如jdbcTemplate:
<bean id="contextSource"
class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="ldap://192.168.101.179:389" />
<property name="base" value="" />
<property name="userDn" value="cn=platoptuser,ou=內置帳號,ou=系統,o=北京XX局" />
<property name="password" value="111111" />
</bean>
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
<constructor-arg ref="contextSource" />
</bean>
讀取Ldap這塊我遇到一個難點,讀取出來人如何得到這個人屬於哪個組織機構,網上搜索無果,通過查看包裡的類找靠譜的方法,最後終於找到了ContextMapper,可以通過獲取dn來取得組織機構
public List<Person> getAllPersonNames() {
// 正則表達式,為獲取組織機構
String regEx_script = "ou=([^,]*)?";
final Pattern p = Pattern.compile(regEx_script, Pattern.DOTALL | Pattern.CASE_INSENSITIVE);// 修改模式
@SuppressWarnings("unchecked")
List<Person> persons = ldapTemplate.search("o=北京XX局", "(objectClass=Person)",
new ContextMapper() {
@Override
public Object mapFromContext(Object arg0) {
DirContextAdapter adapter = (DirContextAdapter)arg0;
Attributes attrs = adapter.getAttributes();
Person bean = new Person();
// 取值
Attribute fullName = attrs.get("cn");
Attribute mail = attrs.get("mail");
Attribute title = attrs.get("title");
Name dn = adapter.getDn();
String org = "";
// 取組織機構
if(dn != null){
Matcher m = p.matcher(dn.toString());
MatchResult mr = null;
// 獲取匹配
while (m.find()) {
mr = m.toMatchResult();
org = org + mr.group(1) + "/";
}
}
// 給對象賦值
try {
bean.setFullName(fullName == null ? "" : fullName.get().toString());
// ldap中有的郵箱有後綴有的沒有
String mailStr = mail == null ? "" : mail.get().toString();
bean.setMail(mailStr);
bean.setTitle(title == null ? "" : title.get().toString());
bean.setOrg(org.equals("") ? "" : org.substring(0, org.length() - 1));
} catch (NamingException e) {
e.printStackTrace();
}
return bean;
}
});
return persons;
}
使用Freemark生成result.php也遇到一個問題,打包成jar後,使用命令行方式輸入java -jar xxx.jar後,提示找不到模板,原先使用的是setDirectoryForTemplateLoading需要修改為:
setTemplateLoader(new ClassTemplateLoader(this.getClass(), "/ftl"));
最後的Freemark代碼是這樣的
public class TestFreemarker {
private Configuration cfg;
public Configuration getCfg() {
return cfg;
}
public void init() throws Exception {
cfg = new Configuration();
cfg.setTemplateLoader(new ClassTemplateLoader(this.getClass(), "/ftl"));
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
TestFreemarker obj = new TestFreemarker();
obj.init();
List<Person> persons = new ArrayList<Person>();
Person user = new Person();
user.setFullName("陳小二");
user.setMail("yueritian@sohu.com");
user.setOrg("XX公司/集團");
user.setTitle("程序員");
persons.add(user);
Map<String, Object> root = new HashMap<String, Object>();
root.put("persons", persons);
Template t = obj.getCfg().getTemplate("result.ftl");
Writer out = new OutputStreamWriter(new FileOutputStream("result.php"), "GBK");
t.process(root, out);
out.flush();
out.close();
}
}