我的解决方案是实现一个自定义 DirContextProcessor,它允许我通过使用 SortControl 的重载方法以所需方向(升序/降序)对多个属性进行排序 类,将 SortKey 的对象数组作为参数。
实现必须扩展 AbstractFallbackRequestAndResponseControlDirContextProcessor 并覆盖 createRequestControl 方法。
超类 AbstractFallbackRequestAndResponseControlDirContextProcessor 将负责控件的实际创建。它只需要来自子类的 2 条信息。
- 要实例化的控件的完全限定类名
- 构造函数参数的类型和值
全限定类名在子类属性defaultRequestControl中提供,构造函数参数的类型和值在子类方法createRequestControl中提供。
SortKey 对象的 ascendingOrder 属性中提供了任何特定属性的排序方向信息。
public class SortMultipleControlDirContextProcessor extends AbstractFallbackRequestAndResponseControlDirContextProcessor{
private SortKey[] sortKeys;
private boolean sorted;
private int resultCode;
public SortMultipleControlDirContextProcessor(SortKey ... sortKeys){
if(ArrayUtils.isEmpty(sortKeys)){
throw new IllegalArgumentException("At least one key to sort on must be provided.");
}
this.sortKeys = sortKeys;
this.sorted = false;
this.resultCode = -1;
this.defaultRequestControl = "javax.naming.ldap.SortControl";
this.defaultResponseControl = "javax.naming.ldap.SortResponseControl";
this.fallbackRequestControl = "com.sun.jndi.ldap.ctl.SortControl";
this.fallbackResponseControl = "com.sun.jndi.ldap.ctl.SortResponseControl";
loadControlClasses();
}
@Override
public Control createRequestControl(){
return super.createRequestControl(new Class[]{SortKey[].class, boolean.class}, new Object[]{sortKeys, critical});
}
@Override
protected void handleResponse(Object control) {
Boolean result = (Boolean) invokeMethod("isSorted", responseControlClass, control);
this.sorted = result;
Integer code = (Integer) invokeMethod("getResultCode", responseControlClass, control);
this.resultCode = code;
}
public SortKey[] getSortKeys(){
return sortKeys;
}
public boolean isSorted(){
return sorted;
}
public int getResultCode(){
return resultCode;
}
}
实现后,您可以使用该类对多个属性的结果进行任意方向的排序:
// SortKey for sorting results on the cn attribute in descending order
SortKey cnSortKey = new SortKey("cn", false, null);
// Instantiate the control
SortMultipleControlDirContextProcessor myCustomControl = new SortMultipleControlDirContextProcessor(cnSortKey);
// Perform the search with the control
List<User> users = ldapTemplate.search("", orFilter.encode(), searchControls, new UserAttributesMapper(), myCustomControl);