От новичка до гуру: Курсы программирования на CyberDuff

Приложение Grails rest-api для обработки нескольких параметров

Используя Grails 3.1.3, я создал rest-api, чтобы иметь возможность захватывать запросы GET, которые запрашивают не только один параметр, но и несколько, если необходимо. Я не знаю, как правильно это закодировать в файле UrlMappings. Вот подробности.

Класс домена:

class ProdDetail {
  Integer pid
  String title
  String category
  Integer year
}

И некоторые из них внутри BootStrap:

new ProdDetail(pid:'101', title:'No Highway', author:'Nevil Shute', category:'fiction', year:1948).save(failOnError:true)
new ProdDetail(pid:'214', title:'In the Country of Men', author:'Hisham Matar', category:'misery', year:2007).save(failOnError:true)

Контроллер:

protected List<ProdDetail> listAllResources(Map params) {

  println params

  try {
     ProdDetail.where {
        if (params.category && params.maxYear) {
           category == params.category && year <= params.int('maxYear')
        } else if (params.category) {
           category == params.category
        } else if (params.maxYear) {
           year <= params.int('maxYear')
        } else {
           pid > 0
        }
     }.list()
  } catch (Exception e) {
     []
  }
}

UrlMappings:

static mappings = {
   "/prodDetails"(resources:'prodDetail')
   "/prodDetails/category/$category?"(controller:'prodDetail', action:'index')
   "/prodDetails/yearUnder/$maxYear?"(controller:'prodDetail', action:'index')
   // the line below is not right I think, what's the correct format?
   "/prodDetails/combo/$category?&$maxYear?"(controller:'prodDetail', action:'index')
}

Теперь о том, как будут работать эти два завитка:

curl localhost:8080/prodDetails/category/misery
curl localhost:8080/prodDetails/yearUnder/2007

Это не может войти в желаемое предложение в контроллере для обнаружения обоих параметров:

curl localhost:8080/prodDetails/combo/?category=misery&maxYear=2007

Он просто определяет «категорию», но не «maxYear», который он считает «нулевым».

Как я могу обслужить такой curl, пожалуйста?

07.03.2016

  • Если вы отправили UrlMappings по адресу: "/prodDetails/combo/$category"(controller:'prodDetail', action:'index'), а затем curl localhost:8080/prodDetails/combo/misery?maxYear=2007, каково содержимое карты параметров? 08.03.2016
  • Просто попробовал. Он возвращает обе записи (чего не должно быть). Выходной сигнал контроллера для println params равен [controller:prodDetail, action:index, category:misery, max:10] 08.03.2016
  • Подождите, извините, ваше предложение сработало! Это сработало, я удалил -i в команде curl. Надо знать, почему ... Я напишу еще, но сейчас хочу вас поблагодарить. 08.03.2016
  • Да, у меня была ошибка, оставив -i в команде curl без правильных заголовков для применения вашего предложения (отредактировано и исправлено). Итак, ваше предложение работает. Но позвольте мне сделать еще один шаг. Что, если бы я хотел сделать запрос по трем или более параметрам, этот подход не сработал бы, верно? Скажем, я хотел запросить категорию, maxYear и имя, например, как тогда будет выглядеть запись в UrlMappings? Команда curl будет иметь вид curl localhost:8080/prodDetails/combo/misery?maxYear=2010&title=common. 08.03.2016
  • Здесь println params' didn't see 'title', and swapping the & for ? gave this: [maxYear: 2010? Title = common, controller: prodDetail, action: index, category: misery, max: 10] `. 08.03.2016
  • Вы должны иметь возможность добавлять столько параметров, сколько хотите, curl localhost:8080/prodDetails/combo/misery?maxYear=2010&title=common должен работать, пока у вас есть правильный UrlMapping, в UrlMapping должно быть только "/prodDetails/combo/$category"(controller:'prodDetail', action:'index') без знака вопроса после $category 08.03.2016
  • Это не сработало. Здесь указаны параметры [maxYear:2010, controller:prodDetail, action:index, category:misery, max:10]. 08.03.2016
  • @photon: Мне очень жаль, ваше второе предложение работает как чары (на самом деле, последний ответ, который я ответил, говорит об этом - у меня показаны оба параметра, maxYear и category). Если это вас утешит, я сегодня не пошла на работу из-за сильной простуды, и это видно :-) Спасибо за вашу помощь. Я бы хотел, чтобы вы опубликовали свой ответ. 08.03.2016

Ответы:


1

Это отчасти зависит от того, как вы хотите, чтобы ваши URL-адреса выглядели, но при условии, что вы хотите, чтобы ваши запросы выглядели так:

http://localhost:8080/prodDetails/combo/misery?maxYear=2007&title=common

UrlMappings должен выглядеть так

static mappings = {
   "/prodDetails/combo/$category"(controller:'prodDetail', action:'index')
}

Затем объект params в контроллере должен иметь как все, что стоит вместо $category, в этом примере - misery, так и другие параметры после ?.

Если вы хотите, чтобы параметры были в пути, вы можете сделать это:

static mappings = {
   "/prodDetails/combo/$category/$title/$maxYear"(controller:'prodDetail', action:'index')
}

Тогда запрос будет таким:

http://localhost:8080/prodDetails/combo/misery/common/2007

Еще один вариант - использовать командный объект. Итак, если у вас было:

static mappings = {
   "/prodDetails/combosearch"(controller:'prodDetail', action:'comboSearch')
}

А затем создал объект рядом с контроллером под названием ComboSearchCommand.groovy, который выглядел так:

import grails.validation.Validateable
class ComboSearchCommand implements Validetable {
    String category
    String title
    int maxYear

    static constraints = {
        category blank: false, nullable: true
        title blank: false, nullable: true
        maxYear blank: false, nullable: true
    }
}

(Которые вы можете выполнять проверку так же, как объект домена)

И затем в вашем контроллере у вас есть метод, принимающий объект команды вместо параметров

protected List<ProdDetail> comboSearch(ComboSearchCommand command) {
    println command.category
}

Тогда ваш URL-адрес будет

http://localhost:8080/prodDetails/combosearch?category=misery&maxYear=2007&title=common

И параметры будут привязаны к объекту команды.

Я использовал это довольно много, вы можете совместно использовать проверки или сделать так, чтобы ваш командный объект наследовал проверки от объектов домена, большая гибкость.

https://grails.github.io/grails-doc/latest/guide/single.html#commandObjects

08.03.2016
  • Спасибо! Последнее решение - это именно то, что я тоже искал. Я попробую сегодня вечером. 08.03.2016

  • 2

    Вам не нужно указывать параметры в UrlMappings, если эти параметры не являются частью URL-адреса:

    В этом нет нужды:

    "/prodDetails/combo/$category&?$maxYear?"(controller:'prodDetail', action:'index')
    

    Да, вам нужно это, чтобы сопоставить URL-адрес с контроллером / действием (но удалить?)

    "/prodDetails/yearUnder/$maxYear?"(controller:'prodDetail', action:'index')
    

    Кроме того, вам не нужны параметры карты в listAllResources(Map params)

    "params" - это внедренное свойство контроллеров, параметры println будут работать нормально с: listAllResources()

    Что бы я сделал, так это определил:

    listAllResources(String category, int maxYear, ...) где ... - это все параметры, которые может получить действие, большинство из них являются необязательными, поэтому вы получите нулевое значение, если оно не будет включено в ваш запрос.

    Помните: UrlMappings предназначены для сопоставления URL-адресов с контроллером / действиями, и у вас есть тот же контроллер / действие, поэтому я бы удалил все сопоставления и обработал необязательные параметры в действии, просто проверяя, какие из них являются нулевыми или нет.

    Редактировать (с учетом комментариев)

    В: метод не перегружен для обработки подобных параметров

    О: методы динамические, это Grails / Groovy, а не Java. Он вызовет метод действия, даже если все параметры равны нулю. Я бы порекомендовал вам подробно изучить документацию по контроллеру Grails.

    Вопрос: обнаружено, что метод listAllResources никогда не вызывался

    О: удалите ключевое слово protected из действия, только подклассы смогут вызывать этот метод. Кроме того, вы можете добавить UrlMapping, чтобы пользователи не вызывали этот URL-адрес (сопоставьте URL-адрес и верните 404 Not Available или что-то в этом роде)

    В: Я хочу обрабатывать GET-запрос следующим образом: localhost: 8080 / prodDetails / combo? category = misery & year = 2016 & title = commonTitle, как именно должна выглядеть i) запись в UrlMappings и ii) метод listAllResources? < / em>

    A:

    static mappings = {
       // if "compo" comes in the action portion, map that to the listAllResources method
       // as I said, if all parameters comes in the query string, no further actions are needed, if you need parameters to be part of the URL path, then you need to play with the $xxxx in the URL
       "/prodDetails/combo"(controller:'prodDetail', action:'listAllResources')
    }
    
    def listAllResources()
    {
       println params
       // logic here
       render "OK"
    }
    

    Проверять:

    08.03.2016
  • Как вы используете listAllResources, я думаю, не будет работать - метод не перегружен для обработки подобных параметров. 08.03.2016
  • Я не пробовал, но уверен, что видел такие методы контроллера. Это может сработать, хотя мне лично не нравятся методы, принимающие множество параметров. 08.03.2016
  • @mohsenmadi Я создаю приложения с помощью Grails, начиная с версии 0.4.3. Да, это работает с новейшими версиями, проверьте mrhaki.blogspot.com.uy/2012/02/ 08.03.2016
  • @photon вы всегда можете определить метод без параметров для действия и получить доступ ко всем параметрам через введенную переменную params, об этом было сказано в моем ответе. 08.03.2016
  • Я пробовал это перед тем, как ответить на @PabloPazos, и обнаружил, что метод listAllResources никогда не вызывался (оператор println никогда не выполнялся), что наводит меня на мысль, что перегрузка как таковая здесь не была принята. Я посмотрю на ваш отзыв и расскажу больше, когда узнаю. Большое спасибо. 08.03.2016
  • Итак, для ясности: если я хочу обработать такой запрос GET localhost:8080/prodDetails/combo?category=misery&year=2016&title=commonTitle, как именно должна выглядеть i) запись в UrlMappings и ii) метод listAllResources? Вы также можете помочь предложить лучший URL-путь вместо того, который я использую. 09.03.2016
  • Мне нравится ваша ссылка, она дает очень хорошее представление о том, как сопоставить параметры URL-адреса с аргументами метода. Но это специальный метод, не использующий listAllRrsources (сейчас меня это не волнует). 09.03.2016
  • @PabloPazos Именно то, что я искал! Спасибо за ваше разъяснение. Я расскажу, как это происходит, по мере того, как подхожу к кодированию, но это логично и понятно. 09.03.2016
  • @mohsenmadi нет проблем, пожалуйста, протестируйте его в чистом проекте, чтобы убедиться, что он работает нормально, чтобы вы знали, что если он не работает, это не проблема в другом компоненте вашего приложения. 09.03.2016
  • Пробовал, но не совсем сработало. С запросом curl localhost:8080/prodDetails/combo?category=misery&year=2015 и всем остальным, как вы предложили в UrlMappings и методе контроллера, обнаруживается только первый параметр (println params дает [category:misery, controller:prodDetail, action:listAllResources]). Я правильно называю это, правда? 10.03.2016
  • У вас есть приложение под названием prodDetails, а в моем примере это контроллер. 14.03.2016
  • Привет, @PabloPazos, извини, я не понял, что ты ответил. По этой ссылке показано приложение prodDetails - не стесняйтесь экспериментировать и применять свое предложение, надеюсь, вы его получите. Бег. 17.03.2016
  • Новые материалы

    Я предполагаю, что вы имеете в виду методы обработки категориальных данных.
    Я предполагаю, что вы имеете в виду методы обработки категориальных данных. Пожалуйста, проверьте мой пост Инструментарий специалиста по данным для кодирования категориальных переменных в..

    Игра в прятки с данными
    Игра в прятки с данными Я хотел бы, чтобы вы сделали мне одолжение и ответили на следующие вопросы. Гуглить можно в любое время, здесь никто не забивается. Сколько регионов в Гане? А как..

    «Раскрытие математических рассуждений с помощью Microsoft MathPrompter и моделей больших языков»
    TL;DR: MathPrompter от Microsoft показывает, как использовать математические рассуждения с большими языковыми моделями; 4-этапный процесс для улучшения доверия и рассуждений в математических..

    Раскройте свой потенциал в области разработки мобильных приложений: Абсолютная бесплатная серия
    Глава 6: Работа в сети и выборка данных Глава 1: Введение в React Native Глава 2: Основы React Native Глава 3: Создание пользовательского интерфейса с помощью React Native Глава 4:..

    Все о кейсах: Camel, Snake, Kebab & Pascal
    В программировании вы сталкивались с ними при именовании переменной, класса или функции. Поддержание согласованности типов и стилей случаев делает ваш код более читабельным и облегчает совместную..

    Как работает дистанционное парное программирование и почему оно может изменить вашу жизнь
    Серебряная пуля от одиночества и отвлекающих факторов во время обучения программированию Независимо от того, работаете ли вы или учитесь удаленно, велика вероятность, что одиночество и..

    🔥🔥👉Питон 🆚Javascript👈🔥🔥
    Сегодня Python и Javascript потрясают мир в области ИТ. Все хотят выучить Python и Javascript, чтобы получить высокооплачиваемую работу. Различные фреймворки Python и Javascript расширяют..


    © 2024 cyberbuff.ru, От новичка до гуру: Курсы программирования на CyberDuff