使用Spring Boot降序对LDAP进行排序

时间:2019-01-29 12:00:37

标签: java sorting spring-boot ldap spring-ldap

是否可以通过SortControlDirContextProcessor降序而不是升序对LDAP目录中的记录进行排序?

我基于此: SpringLdap - LdapTemplateSortedSearchITest

public void testSearch_SortControl_ConvenienceMethod() {
    SortControlDirContextProcessor requestControl;

    // Prepare for first search
    requestControl = new SortControlDirContextProcessor("cn");
    tested.search(BASE, FILTER_STRING, searchControls, callbackHandler,
            requestControl);
    int resultCode = requestControl.getResultCode();
    boolean sorted = requestControl.isSorted();
    assertThat("Search result should have been sorted: " + resultCode, sorted).isTrue();
    List list = callbackHandler.getList();
    assertSortedList(list);
}

它起作用,但升序。如何设置降序排序?

2 个答案:

答案 0 :(得分:0)

我相信这可能会有所帮助:

公共SortKey(字符串attrID,                布尔值ascendingOrder,                字符串matchingRuleID)

为属性创建一个排序键。条目将根据指定的属性以指定的排序顺序并使用指定的匹配规则(如果提供)进行排序。

参数: attrID -用作排序键的属性的非null ID。


升序-如果为true,则条目按升序排列。否则按降序排列。


matchingRuleID -用于对属性值进行排序的匹配规则的ID(可能为null)。如果未指定,则使用为排序键属性定义的排序匹配规则。

它来自文档:Java doc

关于您的问题:Example code from java doc

我发现了另一种名为 unboundid ldap sdk 的替代方案 link

答案 1 :(得分:0)

对我来说,解决方案是实现一个自定义 DirContextProcessor ,它允许我利用 SortControl的重载方法对具有期望方向(升/降)的多个属性进行排序类,该类将 SortKey 对象的数组作为参数。

实现必须扩展AbstractFallbackRequestAndResponseControlDirContextProcessor并覆盖 createRequestControl 方法。

超类 AbstractFallbackRequestAndResponseControlDirContextProcessor 将负责控件的实际创建。它只希望从子类获得2条信息。

  1. 要实例化的控件的完全限定的类名
  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);