Disable grails Searchable plugin default search page? - grails

I'm trying to disable the Searchable plugin default search page (http://localhost/searchable/), but haven't found a way to do it. Anyone know how this can be done, preferably in a legit way, but resorting to trickery if necessary?

I usually re-route error code handlers to a controller so I can do some logging or whatever before rendering the view. You can use that here also:
class UrlMappings {
static mappings = {
"/searchable/$action?"(controller: "errors", action: "urlMapping")
"/$controller/$action?/$id?" { }
"/"(view:"/index")
"403"(controller: "errors", action: "accessDenied")
"404"(controller: "errors", action: "notFound")
"405"(controller: "errors", action: "notAllowed")
"500"(view: '/error')
}
}
where ErrorsController looks something like this:
class ErrorsController {
def accessDenied = {}
def notFound = {
log.debug "could not find $request.forwardURI"
}
def notAllowed = {}
def urlMapping = {
log.warn "unexpected call to URL-Mapped $request.forwardURI"
render view: 'notFound'
}
}
and you'll need to create accessDenied.gsp, notFound.gsp, and notAllowed.gsp in grails-app/errors
By sending a 'hidden' controller to its custom mapping you can log unexpected access to it, but still render the 404 page to hide its existence.

Related

Grails: How do I map a 404 with /**

I've tried to create a custom 404 url mapping for URL's that are not found:
"/test" {
controller="test"
}
"404" {
controller="application"
action="send404"
}
"500" {
controller="application"
action="send500"
}
But for some reason, the controller and action are never called. I get the default container 404 page. So, instead I tried:
"/test" {
controller="test"
}
"/**" {
controller="application"
action="send404"
}
"500" {
controller="application"
action="send500"
}
Which seems to work fine, except that it also seems to call the send404 action on every request. For example, if I hit /test, I see the test page, but I also get the log statement I made in the send404() action.
Ideas appreciated...
Have you tried killing whitespace in your declaration, as outlined in this answer?
"404"(controller:'application', action:'send404')
There is also an open issue GRAILS-4232 about this topic.
In grails, there is an ErrorController, the one that render stacktrace on 500, etc.
class UrlMappings {
static mappings {
"403" (controller: "error", action: "forbidden")
"404" (controller: "error", action: "notFound")
"500" (controller: "error", action: "internalError")
}
}
And then, you can render(controller:"error", action"notFound") in another controller to stay RESTful. Or it will automagically render the notFound action of the error controller.
More details here : http://groovy.dzone.com/articles/grails-exception-handling-http
Perhaps it's favicon.ico that's being requested by the browser on each request that's causing this to happen.
// Route 404 to this action to see!
def send404() {
log.error("404 Page Not Found! " + request.forwardURI)
response.status = 404;
render(view:"/application/not-found.gsp")
}

request.exception is always null

I've created the following class
class ErrorsController {
def index = {
log.error request.exception
}
}
In my UrlMappings I have this:
"500"(controller: "errors")
"404"(controller: "errors")
request.exception is always null. Debugging, I see 2 parameters in the request object. controller and action. I see no exception. If I remove the "404", it works as expected. I'm using Grails 1.3.7.

Grails: Can't figure out why I'm getting a 404

I'm using Grails 1.3.6. I have this file ...
grails-app/views/home/design/index.gsp
Here is what is defined in my HomeController. Sadly, whenever I visit, "http://localhost:port/context-path/design/", I get a 404 error. The server starts normally and there are no errors in the logs. What can I do to get my page instead of the 404?
def index = {
def folder = params.folder;
def page = params.page;
if (page) {
try {
def contents = IOService.getFileContents(folder, page)
response.setContentType("application/json")
response << contents
} catch (FileNotFoundException e) {
response.status = 404;
} // try
} else {
render(view: "/home/${folder}/index")
} // if
}
My URLMappings file consists of ...
static mappings = {
"/$folder?/$page"{
controller = "home"
action = "index"
}
"/"(view:"/index")
"500"(view:'/error')
}
Thanks, - Dave
If you want to be able to access
/context-path/home/design
Your action needs to be named design, i.e.
class HomeController {
def design = {
}
}
The Grails convention is always /context-path/controllerName/actionName (unless you have it mapped differently in grails-app/conf/URLMappings.groovy).
Your example's a bit unclear which path you're trying to access. To address both:
If you want /context-path/design, you need a DesignController with an index action (because if no action is supplied in the URL, Grails looks for the index action).
If you want /context-path/home/design, you need a HomeController with a design action.
Edit:
In the comments, you express the want to be able to have /context-path/design map to the HomeController index action. You can do this with grails-app/conf/URLMappings.groovy:
"/design"(controller: 'home', action: 'index')
Since it seems you have two distinct actions, I would set things up a bit differently:
def indexWithPage = {
def folder = params.folder;
def page = params.page;
try {
def contents = IOService.getFileContents(folder, page)
response.setContentType("application/json")
response << contents
} catch (FileNotFoundException e) {
e.printStackTrace();
response.status = 404;
} // try
}
def index
def folder = params.folder;
render(view: "/home/${folder}/index")
}
with a URLMaping of:
static mappings = {
"/$folder/$page"{
controller = "home"
action = "indexWithPage"
}
"/$folder"{
controller = "home"
action = "index"
}
"/"(view:"/index")
"500"(view:'/error')
}
I also threw a e.printStackTrace(); in there to help us determine whether you're getting YOUR 404 or the action is truely not being called.

Grails: Return 404 & show my 'Not Found' page for invalid id

What's the best way to handle invalid ids in a Grails controller action?
When MyDomainClass.get(params['i']) returns null in my controller action I want the user to see my custom 'Not Found' page and for a 404 HTTP response code to be returned - I can't figure out the cleanest way to do this.
Thanks.
I've used the following in my controllers, where 'notFound' is a custom 404 page:
def show = {
def referenceData = ReferenceData.get( params.id )
if (referenceData)
{ return [ referenceData : referenceData ] }
else
{ redirect(uri:'/notFound') }
}
I also mapped the custom error pages in UrlMapping.groovy, something like
static mappings = {
"403"(controller: "errors", action: "forbidden")
"404"(controller: "errors", action: "notFound")
"500"(controller: "errors", action: "serverError")
}
or
static mappings = {
"403"(view: "/errors/forbidden")
"404"(view: "/errors/notFound")
"500"(view: "/errors/serverError")
}
Grails Docs - mapping to response codes
EDIT - I apologize for misreading your question. the render method takes a status code. So in the controller, if nothing is found, try
render status: 404
or
render view: you_not_found_view
or both (in one render call).
Here's my magic formula for doing this. Maybe there's a better way, but this one works and ensures the same 404 view renders whether you generate the 404 or grails does it internally (no controller found, for example).
First, create a View class that extends AbstractView:
class NotFoundView extends AbstractView {
#Override
protected void renderMergedOutputModel(Map<String, Object> model,
HttpServletRequest request, HttpServletResponse response) {
response.sendError(HttpServletResponse.SC_NOT_FOUND)
}
}
Next, create an error controller:
class ErrorController {
def notFound = {
return render(view: '/error/notFound')
}
}
Now create your error view under views/error/notFound.gsp:
<g:applyLayout name="main">
<!doctype html>
<html>
<head>
<title>Oops! Not found!</title>
</head>
<body>
<h1>Not Found</h1>
<section id="page-body">
<p>Nothing was found at your URI!</p>
</section>
</body>
</html>
</g:applyLayout>
It's crucial that you use the <g:applyLayout> tag. If you use your layout will render twice and nest itself.
Now for the URL mapping:
"404"(controller: 'error', action: 'notFound')
You're all set now to send that 404 from your controller:
def myAction = {
Thing thing = Thing.get(params.id)
if (!thing) {
return new ModelAndView(new NotFoundView())
}
}
This approach also lets you easily log the 404, try to resolve it and send a 301, or whatever you want to do.

How to make some URL mappings depending on the environment?

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.

Resources