GAE-запрос с параметром коллекции

Я подтвердил, что искомый объект находится в хранилище данных. Я проверил, что список, который я передаю как параметр метода, содержит эту сущность. Я пытаюсь найти все объекты, чьи userGmail содержатся в списке строк, которые я передаю.

Вот мой код

    @SuppressWarnings("unchecked")
@ApiMethod(name = "findFriendsByEmailList")
public CollectionResponse<ZeppaUser> findFriendsByEmailList(
        @Named("emailsList") List<String> emailsList, User user)
        throws OAuthRequestException {

    if (user == null) {
        throw new OAuthRequestException(
                "Null User Authorization Exception, findFriendsByEmailList");
    }

    PersistenceManager mgr = null;
    List<ZeppaUser> execute = null;
    Query query = null;
    try {
        mgr = getPersistenceManager();

        query = mgr.newQuery(ZeppaUser.class);
        query.declareParameters("java.util.List emailListParam");
        query.setFilter("emailListParam.contains( userGmail )");

        execute = (List<ZeppaUser>) query.execute(emailsList);

        query.closeAll();

    } finally {
        mgr.close();
    }

    return CollectionResponse.<ZeppaUser> builder().setItems(execute)
            .build();

}

Это трассировка стека, которую я получаю от нее:

Что-то стоит отметить: я не получаю эту ошибку в списках, которые я передаю, чтобы не содержать элемент, найденный в хранилище данных. Именно когда он существует, это наводит меня на мысль, что Query обнаружил элемент, но не был закрыт или правильно выполнен в возвращаемом параметре. Если предпочтительнее вернуть List, то это более чем нормально. Я пробовал несколько вариантов этого безуспешно. Это становится довольно расстраивающим.

1 ответ

Решение

Итак, я нашел способ обойти это.

Списки не могут быть переданы в ApiEndpoints. Это или я не нашел правильный способ сделать это и ЛЮБЛЮ обновленную информацию о том, как это сделать.

Вместо этого в моем клиенте я создаю строку писем, разделенных запятой, и отправляю строку в параметр в виде "закодированного" списка строк, а затем "декодирую" его при выполнении. Работает хорошо, но кажется хакерским.

Вот методы, которые я использовал. Это удобно, потому что это работает и с iOS.

public static String encodeListString(ArrayList<String> stringList){
    StringBuilder stringbuilder = new StringBuilder();
    stringbuilder.append(stringList.get(0));
    if(stringList.size() > 1){
        for( int i = 0; i < stringList.size(); i++){
            stringbuilder.append(",");
            stringbuilder.append(stringList.get(i));
        }
    }

    return stringbuilder.toString();
}

public static List<String> decodeListString(String encodedString){

    char[] characters = encodedString.toCharArray();
    StringBuilder stringbuilder = new StringBuilder();
    int position = 0;
    ArrayList<String> stringList = new ArrayList<String>();
    while(true){
        try {
        char character = characters[position];
        if(character == ','){
            String resultString = stringbuilder.toString();
            stringList.add(resultString);
            stringbuilder = new StringBuilder(); // clear it
        } else {
            stringbuilder.append(character);
        }

        position++;

        } catch (ArrayIndexOutOfBoundsException aiex){
            // List ended
            String resultString = stringbuilder.toString();
            if(!resultString.isEmpty())
                stringList.add(resultString);
            break;
        }

    }

    return stringList;

}
Другие вопросы по тегам