Как я могу использовать переменные пути в контроллере Grails?

Я пытаюсь использовать переменную пути в контроллере Grails, но не могу этого добиться. Намерение состоит в том, чтобы проверить параметр, отправленный в URL-адрес, который мне нужно сделать обязательным. Я не смог добиться этого с помощью RequestParam, поэтому я переключился на PathVariable, чтобы URL-адрес, отправленный без требуемого параметра, отфильтровывался самим контроллером Grails, а не мной, добавляющим проверки if/else на достоверность.

Итак, я могу проиллюстрировать это следующим образом: Мой URL выглядит примерно так: -

'<appcontext>/<controller>/<action>?<paramName>=<something>'

Теперь, чтобы сделать «paramName» обязательным, я не нахожу никакого способа в Grails (Spring MVC предоставляет аннотацию @RequestParam, которая может позволить мне «требуется» как истина).

Еще одна альтернатива, которую я подумал, заключалась в использовании переменных пути, чтобы «paramName» можно было включить в сам URL. Итак, я попробовал следующее:

'<appcontext>/<controller>/<action>/$paramName'

Для проверки приведенного выше URL-адреса я написал специальное сопоставление, но почему-то оно тоже не работает.

Ниже приведено конкретное сопоставление, которое я написал:

"/<controllerName>/<action>/$paramName" {
            controller:<controller to take request>
            action:<action to do task>
            constraints {
                paramName(nullable: false,empty:false, blank: false)
            }
        }

Я попытался использовать аннотацию spring, такую ​​​​как @PathVariable и @RequestParam в контроллере, как показано ниже: -

 def action(@PathVariable("paramName") String param){
        //code goes here
    }

person Vishal    schedule 02.07.2014    source источник
comment
кое как тоже не работает - что именно не так? Помните, что ограничения просто определяют, может ли это конкретное сопоставление URL-адресов применяться к определенному запросу. Если у вас есть другие сопоставления, которые могут соответствовать тому же URL-адресу (например, общее сопоставление "$controller/$action?/$id?"), возможно, ваши ограничения на самом деле работают правильно, отклоняя это конкретное сопоставление, но вместо этого тот же контроллер вызывается через другое сопоставление.   -  person Ian Roberts    schedule 02.07.2014
comment
Ограничение параметра с помощью nullable: false, empty: false, blank: false на самом деле ничего не делает. Поскольку сопоставление не включает ?, параметр должен присутствовать, чтобы это сопоставление применялось. Вы можете устранить эти ограничения.   -  person Jeff Scott Brown    schedule 02.07.2014


Ответы (1)


Если вы назовете аргумент метода так же, как переименовать параметр запроса, Grails позаботится об этом за вас...

// In UrlMappings.groovy
"/foo/$someVariable/$someOtherVariable" {
    controller = 'demo'
    action = 'magic'
}

Затем в вашем контроллере:

// grails-app/controllers/com/demo/DemoController.groovy
class DemoController {
    def magic(String someOtherVariable, String someVariable) {
        // a request to /foo/jeff/brown will result in
        // this action being invoked, someOtherVariable will be
        // "brown" and someVariable will be "jeff"
    }
}

Надеюсь, это поможет.

ИЗМЕНИТЬ:

Другой вариант...

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

import grails.web.RequestParameter
class DemoController {
    def magic(@RequestParameter('someVariable') String s1, 
              @RequestParameter('someOtherVariable') String s2) {
        // a request to /foo/jeff/brown will result in
        // this action being invoked, s2 will be
        // "brown" and s1 will be "jeff"
    }
}
person Jeff Scott Brown    schedule 02.07.2014
comment
это сработало, однако я чувствую, что это своего рода взлом, поскольку я хотел, чтобы в случае сбоя ограничения запрос не проходил. Но здесь это похоже на то, что если оно соответствует действию в контроллере с таким же именем, запрос будет выполнен. Как я могу обязать запрос не предпринимать никаких других действий (кроме сопоставления URL-адресов) без изменения имени действия по умолчанию? - person Vishal; 03.07.2014
comment
Я не понимаю вашего вопроса. Ни один запрос никогда не попадет в действие в вашем контроллере, если он не соответствует некоторому соответствующему сопоставлению, определенному в ваших UrlMappings. Например, если вы удалите сопоставление /$controller/$action?/$id? и у вас будет только сопоставление URL-адресов, которое я определил выше, запрос к /foo/jeff/brown будет работать, а /demo/magic/ — нет. Ни /demo/magic?someVariable=jeff&someOtherVariable=brown, ни /demo/magic/jeff/brown и т. д. Проходят только те запросы, которые соответствуют сопоставлению URL-адресов. - person Jeff Scott Brown; 03.07.2014