I have a Grails 3.1.3 app with the following setup:
class UrlMappings {
static mappings = {
"/error"(controller: 'error', action: 'error')
"/$controller/$action?/$id?"()
"/"(controller: "index", action: "index")
}
}
class IndexController {
static allowedMethods = [index:'GET']
def index() {
println "Reached index action"
...
}
}
class FormInterceptor implements grails.artefact.Interceptor {
int order = HIGHEST_PRECEDENCE + 100
FormInterceptor() {
matchAll()
}
boolean before() {
println "request.requestURI: ${request.requestURI}"
}
...
}
When navigating to the app's context root (i.e. http://localhost:8080/app-context-root/), the following output results:
request.requestURI: /app-context-root/
Reached index action
Aside from using a redirect in UrlMappings.groovy, can I have the url mapping from / to /app-context-root/index/index happen BEFORE my interceptors receive the request URI?
Related
I organized my url mappings in grails with groups.
Example from UrlMappings:
class UrlMappings {
static mappings = {
group "/rest", {
"/" {
controller = "rest"
action = "index"
}
"/method1" {
controller = "rest"
action = "method1"
}
}
"/webservice/" {
controller = "webservice"
action = "index"
}
}
What I want: When the Url is called /rest/notexists, I want a 404 for this path. But only for /rest group, so the 404 should belong to the group rest. Other 404 are handled by my backbone router.
Any ideas?
I solved it with a catch all at the end of the rest group:
"/**" {
controller = "rest"
action ="notFound"
}
Grails 2.4.4 here. All of my controllers were generated using the standard grails create-controller ... command:
class FizzController {
def index() {
// ...
}
}
class BuzzController {
def index() {
// ...
}
}
...etc.
At the top of each action method, in each controller, I need to call a method doSomething(String). This method needs to have access to redirect(...) so that it can redirect the user if need be. Ideally, I could create an abstract base controller class and have all my controllers extend it:
abstract class BaseController {
void doSomething(String cmd) {
if(cmd == 'Yee haw!') {
redirect(controller: 'foo', action: 'baz')
return false
}
}
}
class FizzController extends BaseController {
def index() {
String cmd = getCmdSomehow()
doSomething(cmd)
// ...etc.
}
}
class BuzzController extends BaseController {
def index() {
String cmd = getCmdSomehow()
doSomething(cmd)
// ...etc.
}
}
However I'm not sure Grails will allow this, since it's doing "Groovy magic" under the hood to make sure there is access to things like redirect(...) and render(...), etc. It would also be wonderful if I could put all this in a closure and just have it executed implicitly (without having to call doSomething() at the beginning of each and every controller action.
What is my best option/solution here? Please use a concrete code example!
Use Filter instead:
class ExampleFilters {
def filters = {
logFilter(controller: '*', action: '*') {
before = {
}
after = { Map model ->
}
afterView = {
}
}
}
}
Given this mapping:
"/student/degree/$studentid/$degreecode"(controller:'student', action:'degree')
I am trying the tests below and both fail with AssertionFailedError: '...did not match any mapping' and both are valid URLs that do function. I can succeed with a test URL of just '/student/degree' which I think should fail as the parameters are required.
It seems the assertURL methods are not handling multiple parameters. Does this only work for 'id' and is it not possible to create tests for these URLs?
#TestFor(UrlMappings)
#Mock([StudentController])
class UrlMappingsTests {
void testUrlMappings() {
assertForwardUrlMapping("/student/degree/102345678/N", controller: "student", action: "degree") {
assertForwardUrlMapping("/student/degree/102345678/N", controller: "student", action: "degree") {
studentid = 102345678
degreecode = "N"
}
}
}
}
Tested with Grails 2.2.4, and it works for me, I just add a custom mappings class:
package test
class MyUrlMappings {
static mappings = {
"/test/show/$myId/$myVal"(controller: "test", action: "show")
}
}
import spock.lang.*
import test.MyUrlMappings
#TestFor(MyUrlMappings)
#Mock([TestController])
//I'm using Spock
class MyUrlMappingsSpec extends Specification {
void "mapping should consider myId and myVal"() {
expect:
assertForwardUrlMapping("/test/show/1/tst", controller: "test", action: "show") {
//all params considered as String
myId = '1'
myVal = 'tst'
}
}
}
I have the following:
"/api/users"(controller: "user") {
action = [GET:"list"]
}
Doing a call to http://localhost:8080/platform/users I get a list of users back. Then I added this:
"/api/users"(controller: "user") {
action = [POST:"save"]
}
And now I get a 404 and it is not hitting either method in UserController. I'd like to be able to use the same URL with the verb controlling which action. Am I doing this wrong or does Grails not support this?
From the Grails docs: URL Mappings
static mappings = {
"/product/$id"(controller:"product") {
action = [GET:"show", PUT:"update", DELETE:"delete", POST:"save"]
}
}
For your case:
"/api/users"(controller: "user") {
action = [GET:"list",POST:"save"]
}
Check your userController to see if there is allowedMethods defined accordingly like this:
class UserController {
static allowedMethods = [save: "POST", list: "GET"]
def list() {
.....
}
def save() {
.....
}
}
I've created a Grails (1.2.1) application in SpringSource Tools Suite 2.3.2 and here is my UrlMappings.groovy:
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/broadcasters/setInterval" { //cause a 404
controller = "broadcaster"
action = "setRefreshInterval"
}
"/broadcasters/online/$id?" { //this one is OK
controller = "broadcaster"
action = "listOnlineBroadcasters"
}
"/broadcasters/$id?" { //this one is OK
controller = "broadcaster"
action = "listAllBroadcasters"
}
"/" (controller: "login", action:"auth")
"/logout" (controller: "logout")
"500"(view:'/error')
"404"(view:'/404')
}
}
Here is my controller
package xxx.yyy.controllers
import org.codehaus.groovy.grails.plugins.springsecurity.Secured
#Secured(['ROLE_ADMIN'])
class BroadcasterController {
def broadcasterService
static defaultAction = "listAllBroadcasters"
def listOnlineBroadcasters = {
...
}
def listAllBroadcasters = {
...
}
def setRefreshInterval = {
...
}
}
When I access the url /broadcasters/setInterval, I've got a 404 both as normal or ajax request. I also write a simple unit test to check the for my UrlMappings:
class GSMUrlMappingTests extends GrailsUrlMappingsTestCase {
void testUrlMapping() {
assertUrlMapping ("/broadcasters/setInterval", controller: "broadcaster", action: "setRefreshInterval")
}
}
And the test failed! Is it a bug of Grails 1.2.1 or am I missing something?
Here is the plugins I've used
plugins.acegi=0.5.2
plugins.debug=1.0.2
plugins.hibernate=1.2.1
plugins.jdbc-pool=0.1
plugins.tomcat=1.2.1
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
is closed.
Other mappings need to be within