Grails URLMappings for 404 doesn't work properly - grails

I have a strange problem with handling 404 HTTP response in grails 1.3.6 (the same wrong behavior was in 1.3.5). It sometimes works but most of the time it doesn't. I think it is a grails bug but haven't found any bug in grails' jira..
whenever I request for bad URL I receive default Tomcat 404 page.
My Configuration/UrlMappings.groovy looks like:
class UrlMappings {
static mappings = {
"404" {
controller = 'customError'
action = 'index'
code = 404
}
"500" {
controller = 'customError'
action = 'index'
code = 500
}
"/"(controller: "home", action: "index")
"/$controller/$action?/$id?"{
constraints {
// id has to be a number
id(matches: /\d+/)
}
}
}
}
Doesn anybody know how to solve it?:-)
Best,
Mateo

I think the problem is you are using braces { } instead of using parenthesis ( ). This is how it should be listed for your example of using a customError controller.
static mappings = {
"404"(controller: "customError", action: "index")
"500"(controller: "customError", action: "index")
...
}
Please see [6.4.4 in the Grails documentation][1] for more information.
[1]: http://grails.org/doc/latest/guide/6.%20The%20Web%20Layer.html#6.4.4 Mapping to Response Codes

Try it without the space. There was a bug in older versions of Grails where a space would cause the error mappings not to be picked up due to a bug in some regex somewhere:
static mappings = {
"404"{
controller = 'customError'
action = 'index'
code = 404
}
"500"{
controller = 'customError'
action = 'index'
code = 500
}

Related

Getting error as Page Not Found(Error Code: 404) when trying $http.get to a URL

My Grails 3.2.3 app is running on port 9000 and I'm doing a GET request to the URL /api/mail/getUnreadCount but I'm getting a 404 error to that URL.
My URLMapping.groovy having:
get "/api/$controller(.$format)?"(action: "index")
get "/api/$controller/$id(.$format)?"(action: "show")
"/api/$controller/$action?/$id?(.$format)?" {
constraints {
// apply constraints here
}
}
Also help me, how we can enable Grails URL mapping logs?
Update 1
class MailController {
static allowedMethods = [index: "GET", getUnreadCount: "GET"]
.....
.......
def getUnreadCount() {
User currentUserInstance = springSecurityService.getCurrentUser()
List counts = userService.getUnreadCounts(currentUserInstance)
respond(counts)
}
}
It is expected that you have getUnreadCount.gsp in views/mail directory to get the output from respond
.. and for the code you provided, if you dont have any view, you should get Error 500 not 404.
In your code, put
formats: ['xml', 'json']
or explicitely mention view
view: "showCount"
or try render method instead
Update
Btw, please remove
get "/api/$controller/$id(.$format)?"(action: "show")
When you hit /api/mail/getUnreadCount, this mapping causes $id = getUnreadCount, and you don't have any action show in your controller, which generates 404 error.

Grails channel security causing a redirect loop

I am new to Grails and I am working on an exisiting application. I am trying to force the anyone using our website to allways be on https. I added the Spring Security Core plugin
//BuildConfig.groovy
compile "org.grails.plugins:spring-security-core:2.0.0"
and I just added
///Config.groovy
grails.plugin.springsecurity.secureChannel.definition = [
'/**': 'REQUIRES_SECURE_CHANNEL'
When I try to go on localhost:8080/myapp, it redirects me to https://localhost:8443/myapp, but I get a "This webpage has a redirect loop ERR_TOO_MANY_REDIRECTS" message.
I added print statements in my SecurityFilters.groovy, and I can see the infinite loop going
baseFilter(controller: "*", action: "*")
{
before = {
println "baseFilter"
// If auth controller then ok to continue
if (controllerName.equals("auth"))
{
return true;
}
// If no subject (user) and not auth controller then user must authenticate
if (!session.subject && !(controllerName.equals("auth")))
{
params.targetUri = request.forwardURI - request.contextPath
if (params.action=="profile") {
params.targetUri=params.targetUri + "?page=" + params?.page
}
else if (params.action=="results") {
params.targetUri="/home"
}
println "baseFilter: Redirecting: PARAMS = $params"
redirect(controller:'auth', action:'login', params: params)
return false;
}
}
}
It's just:
baseFilter
baseFilter: Redirecting: PARAMS = [action:auth, format:null, controller:login, targetUri:/login/auth]
Over and over.
I've tried many other things I found on Stackoverflow and other websites, but they either do not work, or are too complicated.
Thank you.
Ok, so this isn't the answer to the question, but I managed to achieve what I was trying to do, which was to force SLL, and redirect any attempts to use http. I did this by using the shiro plugin, which was already being used by my application. In the Buildconfig.groovy, just add compile ":shiro:1.2.1" to you plugins. In the config.groovy I added the following properties:
security {
shiro {
filter {
loginUrl = "/login"
successUrl = "/"
unauthorizedUrl = "/unauthorized"
filterChainDefinitions = """
/** = ssl[443]
"""
}
}
}
You can modify your filterChainDefinitions to only force ssl on certain urls. I just used /** because I always want SSL.

How to change status code of response in grails filter

I'm using grails 2.3.7 ; my objective is to forward (not redirect !) all requests that are not ajax to a view 'index.gsp'
I've created a filter :
import javax.servlet.http.HttpServletResponse
class SinglePageFilters {
def filters = {
isNotAjax(uri: '/**') {
before = {
if (!request.xhr) {
render(status:HttpServletResponse.SC_OK, view: 'index')
return false;
}
}
}
}
}
This filter works, but the status code of the response is always 404, never 200. It's seems I can't change de the response status code from the filter.
Has someone any hint to solve this problem ?

Automatic language detection by browser

How can I detect the language of the browser and automatically display the correctly localized version of my grails website depending on that value.
I put this in to Index action
Locale locale = new Locale(params.lang)
cookieLocaleResolver.setLocale(request, response, (Locale)
session.getAttribute('locale'))
{
render controller: "home", action: "index"
return
}
And I got exception--
Error 500: Executing action [index] of controller [socialworking.HomeController] caused exception: null
Servlet: grails
URI: /socialworking/grails/home.dispatch
Exception Message:
Caused by:
Class: Unknown
First off, you should put that in a filter in grails-app/conf directory. Create a filter if you don't already have one.
MyFilters.groovy
class MyFilters {
def filters = {
setLocale(controller:'*', action:'*') {
before = {
// Your logic here
}
}
}
}
Your logic here could look in many ways, but here is a try:
String langToSet = 'en';
if ( params.lang && params.lang in validLanguages )
langToSet = params.lang;
else if ( session.lang ) {
langToSet = session.lang;
}
else if ( ... ) // Cookie lang is set ( User might have accessed the site before and you have stored their preferred lang )
// Get cookie lang
Locale locale = new Locale( langToUse)
org.springframework.web.servlet.support.RequestContextUtils.getLocaleResolver(request).setLocale(request, response, locale);
// Set the cookie lang
...
// We set the session lang
session.lang = langToSet
Note that the above is not a complete implementation but it is almost. The cookie stuff and validLanguages you should be able to figure out what they do.
I hope that helps!

Grails: Mapping to response codes, impossible to change http status code

"404" (controller: 'error', action: 'pageNotFound')
Any changes to response.status inside the pageNotFound action is reverted back to 404 before the response is sent to the client. Is it possible to work around this some way? I would like to be able to change it to 410 when I detect that the resource has been deleted or 301 when it's moved permanently.
If that's not working try this in your error controller:
class ErrorController {
def notFound = {
redirect( action: 'gone')
}
def gone= {
response.sendError(410, "Gone")
}
}
Try setting the header yourself manually by response.setHeader()

Resources