郵件系統通訊錄需按拼音首字母分級目錄存儲(一級目錄首字母、二級前兩字母…),每級目錄包含 result.php 列出該分組人員。手動維護成本極高,需自動化生成。
LdapTemplate)<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>
public List<Person> getAllPersonNames() {
String dnRegex = "ou=([^,]*)?"; // 匹配 ou=組織名
Pattern pattern = Pattern.compile(dnRegex, Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
return ldapTemplate.search(
"o=北京XX局",
"(objectClass=Person)",
(ContextMapper<Person>) ctx -> {
DirContextAdapter adapter = (DirContextAdapter) ctx;
Attributes attrs = adapter.getAttributes();
Person person = new Person();
// 基礎屬性
person.setFullName(getStringAttr(attrs, "cn"));
person.setMail(getStringAttr(attrs, "mail"));
person.setTitle(getStringAttr(attrs, "title"));
// 關鍵:從 DN 解析組織路徑
Name dn = adapter.getDn();
String orgPath = "";
if (dn != null) {
Matcher m = pattern.matcher(dn.toString());
while (m.find()) {
orgPath += m.group(1) + "/";
}
}
person.setOrg(orgPath.isEmpty() ? "" : orgPath.substring(0, orgPath.length() - 1));
return person;
}
);
}
private String getStringAttr(Attributes attrs, String key) {
try {
Attribute attr = attrs.get(key);
return attr == null ? "" : attr.get().toString();
} catch (NamingException e) {
return "";
}
}
result.ftl<?xml version="1.0" encoding="GBK"?>
<ul>
<#list persons as p>
<li>${p.fullName} - ${p.mail} - ${p.title} - ${p.org}</li>
</#list>
</ul>
public class LdapDirectoryGenerator {
private Configuration cfg;
public void init() {
cfg = new Configuration(Configuration.VERSION_2_3_31);
// 關鍵點:打包成 JAR 後需用 ClassTemplateLoader 載入模板
cfg.setTemplateLoader(new ClassTemplateLoader(this.getClass(), "/ftl"));
}
public void generate(List<Person> persons, String outputPath) throws Exception {
Map<String, Object> root = new HashMap<>();
root.put("persons", persons);
Template template = cfg.getTemplate("result.ftl");
try (Writer out = new OutputStreamWriter(new FileOutputStream(outputPath), "GBK")) {
template.process(root, out);
}
}
public static void main(String[] args) throws Exception {
LdapDirectoryGenerator gen = new LdapDirectoryGenerator();
gen.init();
// 測試數據
List<Person> list = new ArrayList<>();
Person p = new Person();
p.setFullName("陳小二");
p.setMail("yueritian@sohu.com");
p.setOrg("XX公司/集團");
p.setTitle("程序員");
list.add(p);
gen.generate(list, "result.php");
System.out.println("生成成功!");
}
}
cn=張三,ou=研發部,ou=技術中心,o=公司,正則提取所有 ou 組成路徑ClassTemplateLoader 替代 setDirectoryForTemplateLoading,解決資源文件在 JAR 內無法讀取