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
Related
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?
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 = {
}
}
}
}
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'm using Grails 1.2.1. I want to set up this mapping ...
http://localhost:8080/context-path/mediaproxy
So I added this to my URLMappings.groovy file ...
class UrlMappings {
static mappings = {
‰name mediaproxy: "/mediaproxy" {
controller = "SocialMediaCacheProxy"
action = "index"
}
"/"(view:"/index")
"500"(view:'/error')
}
}
However, I'm getting a 404 when I visit the above URL. Here is how I set up my controller
class SocialMediaCacheProxyController {
def index = {
if (params.dumpAll != null) {
} else if (params.url != null) {
doCacheTransport(params, response);
} // if
}
...
}
Any ideas what I'm doing wrong? Thanks, - Dave
There are is some weird character in front of your named mapping (‰) and your controller name should be lowercase on the first character so that it points to SocialMediaCacheProxyController.
If you don't need a named mapping the following mapping would do the trick for you:
class UrlMappings {
static mappings = {
"/mediaproxy"(controller:"socialMediaCacheProxy", action:"index")
"/"(view:"/index")
"500"(view:'/error')
}
}
It might be some problem with your question formatting but I would expect the url mapping to look like this:
class UrlMappings {
static mappings = {
"/mediaproxy" {
controller = "SocialMediaCacheProxy"
action = "index"
}
"/"(view:"/index")
"500"(view:'/error')
}
}
When getting an HTTP status code 500, I want to display 2 different pages according to the running environment.
In development mode, I want to display a stackStrace page (like the default Grails 500 error page) and in production mode, I want to display a formal "internal error" page.
Is it possible and how can I do that ?
You can do environment specific mappings within UrlMappings.groovy
grails.util.GrailsUtil to the rescue
Its not pretty, but I think it will solve your issue
E.g
import grails.util.GrailsUtil
class UrlMappings {
static mappings = {
if(GrailsUtil.getEnvironment() == "development") {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/"(view:"/devIndex")
"500"(view:'/error')
}
if(GrailsUtil.getEnvironment() == "test") {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/"(view:"/testIndex")
"500"(view:'/error')
}
if(GrailsUtil.getEnvironment() == "production") {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/"(view:"/prodIndex")
"500"(view:'/error')
}
}
}
There may be a cleaner way to do this, but I'd got with mapping the error code to a controller and handling the logic there:
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?" { constraints {} }
"/"(view:"/index")
"403"(controller: "errors", action: "accessDenied")
"404"(controller: "errors", action: "notFound")
"405"(controller: "errors", action: "notAllowed")
"500"(view: '/error')
}
}
and then create the corresponding controller (grails-app/conf/controllers/ErrorsController.groovy):
import grails.util.Environment
class ErrorsController extends AbstractController {
def accessDenied = {}
def notFound = {}
def notAllowed = {}
def serverError = {
if (Environment.current == Environment.DEVELOPMENT) {
render view: '/error'
}
else {
render view: '/errorProd'
}
}
}
You'll need to create the corresponding GSPs in grails-app/views/errors (accessDenied.gsp, notFound.gsp, etc.) and also the new grails-app/views/errorProd.gsp. By routing to a controller method for all error codes you make it easier to add logic to the other error code handlers in the future.