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;
}