With grails, can I specify the controller, action, and view in UrlMappings.groovy? - grails

With Grails, in UrlMappings.groovy, it seems I can specify the controller and action:
"/someURL" (controller: "Some", action: "someAction")
Or I can specify the view:
"/someURL" (view: "someView")
But I can't specify the controller, action, and view:
"/someURL" (controller: "Some", action: "someAction", view: "someView")
Instead, I have to specify the view in the controller. Is there a way to specify the view in the UrlMappings.groovy? Or is it just not possible?

To do this, you would first need to know that Grails uses Spring Web under the hood. Spring Web is the most complex web framework I can think of (capable of doing anything AFAIK). At any rate, the important thing to know is how Spring Web's Request Life Cycle works. You can get a feel for it by reading the documentation of the "DispatcherServlet" which is the main Servlet in Spring Web (and consequently in Grails):
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/DispatcherServlet.html
Here is a great article from the grails team about how grails is really just spring:
http://spring.io/blog/2010/06/08/spring-the-foundation-for-grails/
The important part relevant to this question are these two lines from that documentation:
Its view resolution strategy can be specified via a ViewResolver implementation, resolving symbolic view names into View objects. Default is InternalResourceViewResolver. ViewResolver objects can be added as beans in the application context, overriding the default ViewResolver. ViewResolvers can be given any bean name (they are tested by type).
If a View or view name is not supplied by the user, then the configured RequestToViewNameTranslator will translate the current request into a view name. The corresponding bean name is "viewNameTranslator"; the default is DefaultRequestToViewNameTranslator.
What you really want to do is create a customized ViewResolver or RequestToViewNameTranslator. The world is quite complex - if a View is supplied by the user in the Grails Controller explicitly, then you would want a ViewResolver. If instead a Map is returned (or some other custom object), then you want a RequestToViewNameTranslator.
Don't forget that grails has customized these two things already, to use the whole "convention over configuration" idea. So, you have to be careful in how you implement yours - I would recommend looking at the grails default implementations of these things.
Source for the GrailsViewResolver is here:
https://github.com/grails/grails-core/blob/master/grails-web/src/main/groovy/org/codehaus/groovy/grails/web/servlet/view/GrailsViewResolver.java
Now, the real fun begins. The grails team didn't just provide custom implementations of spring web's default life cycle, they completely customized the dispatcher servlet as well. This means you need to be aware of how their universe differs from the spring universe (thus rendering many helpful spring forum questions irrelevant). Here is a link to the GrailsDispatcherServlet source code:
https://github.com/grails/grails-core/blob/master/grails-web/src/main/groovy/org/codehaus/groovy/grails/web/servlet/GrailsDispatcherServlet.java
So if you managed to read this far, you can probably envision how to write a customized view resolver to return the view you want, but how to get access to the URL Mappings configuration data, so you can define views in there (however you see fit). The UrlMappings file relates to a spring bean, which will be available to autowire using the property "grailsUrlMappingsHolderBean" - see http://grails.org/doc/2.3.4/ref/Plug-ins/URL%20mappings.html
From that bean, you can access UrlMappings object, which you can get access to all UrlMapping definitions. See:
https://github.com/grails/grails-core/blob/master/grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/UrlMappings.java
https://github.com/grails/grails-core/blob/master/grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/UrlMapping.java
I'm not entirely convinced whether you can just throw anything in there, but since it's groovy I'd think you can. If not, you would have at least 2 options:
Create a new config file for just controller/view mappings your custom view/viewname resolver would use
Customize the URLMappings based on the grails source to interpret your custom configuration
A little off topic, here is an interesting article about removing the default mappings file and home-rolling your own:
http://mrhaki.blogspot.com/2011/12/grails-goodness-customize-url-format.html
Again, I found several posts online where people went down this path, and it ended up being too hard because of the numerous configuration pieces need to make it function. Thus, I highly recommend against it. To a certain degree, I agree with the response on this page (which is what you will see alot trying to do something out of the grails universe):
Bypassing grails view resolvers?

Related

Where do a Grails controller's "expando" methods come from?

According to the documentation, a Grails controller is simply a class with "Controller" appended to the name and saved in grails-app/controllers/. The simplest of such a class being:
package some.package
class FooController {
def index = {}
}
When the Grails application is run, this controller will inherit some standard methods like getParams and getSession. From the attached screenshot I can see that these are added via groovy.lang.ExpandoMetaClass. What I don't see is how this happens. The controller doesn't implement any interfaces or extend any abstractions. Where do these methods come from?
From Grails 2.0 a new methodology was adapted to add the dynamic methods to the controller artefacts. You can visit them step wise to see how those properties are added to Controllers:-
Controller in grails is not part of grails-core but a plugin by itself to grails named grails-plugin-controllers.
Being a plugin, the corresponding *GrailsPlugin Class would define the behavior of the plugin.
ControllersApi (extending CommonWebApi) bears all those properties which are to added to controller artefact. (Introduced from Grails 2.0)
ControllerGrailsPlugin registers ControllersApi as a spring bean.
There is more to just adding ControllerApi as a bean.
There is a concept of MetaClassEnhancer which would take/consider an API (in this case ControllerApi) and enhance/reconcile the artefact (controller) with the corresponding API by adding CachedMethods to the artefact using reflection, which is the role of a BaseApiProvider present in grails-core.
This magic happens in the Controller plugin class as well.
Now, prior to Grails 2.0 a different method was adapted to add the dynamic properties to controller. That way metaClass properties were added to controllers at runtime which was found to be less efficient. Each of the dynamic property was represented by its own class (viz: GetParamsDynamicProperty, GetSessionDynamicProperty) which is not in use right now.
So what you need to look now in the object tree for those dynamic methods is this where the CachedMethods are available in the controller. Hope that helps. I would be glad to add more if you seek more. :-)
You are right, Grails 'Controllers' are not really Controllers in the sense they inherit from a base class, but rather they are just simple POGOs that follow the convention of being placed in the grails-app/controllers directory. When your application is compiled, 30+ methods are mixed in through AST transformations, the majority of them coming from
org.codehaus.groovy.grails.plugins.web.api.ControllersApi, but also from
org.codehaus.groovy.grails.plugins.converters.api.ConvertersControllersApi,
org.codehaus.groovy.grails.plugins.web.api.ControllersMimeTypesApi.
The preceding was paraphrased from Programming Grails by Burt Beckwith, and I would recommend it if you are interested in the finer details of Grails.
Quoting from Burt Beckwith's excellent book, Programming Grails:
Over 30 methods are mixed into controller classes with AST
transformations. The majority are added from the
org.codehaus.groovy.grails.plugins.web.api.ControllersApi class
ControllersApi source

When would a bean tag be used in Struts 2 configuration file?

When would be the bean tag used in struts.xml configuration file using Struts 2? What is difference between action class properties and bean tag in Struts 2 configuration file struts.xml?
Some places have strict separation of work or for what ever reason you can edit the view (JSP) but not the actions source.
In this case the bean tag becomes most useful (otherwise I agree it isn't particularly attractive). It is generally easiest to produce what is needed for the view within the action and also process that data such that it is readily displayable. As such there is not generally much need for append, generator, merge tags either... but once again if you consider the content people separate from the backend people these tags would be used more often.
In theory it is possible to use the bean tag to access things like singletons for counters and such, but if the view is acquiring resources in this way it is kind of a component way of thinking(as opposed to action based thinking). This is also why the action tag's use isn't particularly favored either. If you need it, the action class should be the main one responsible for getting it (or interceptors, but certainly not the view) at least following action based thinking.

Is there a Django's context processor like in Grails?

I want to output a value which is global in all the templates or even layout in Grails, like Django's context processor where you could render the context and use it as global variable in the templates.
Is there a concept like this in Grails? And, how can I use that in the layout?
I am not familiar with Django at all. Looked up Django's context processor in google, I think I get it. Basically it configures reusable data that gets injected into every template? Anyway, as far as I know nothing like that exists in Grails. You can try the following as a workaround.
Use ApplicationContext
Every view has access to the applicationContext. So make a service that holds all the data you need, let's say it is called fooService, and the data item you want is a field in the service called bar (could be a method too of course). Then in your view do ${applicationContext.fooService.bar}. Resource for accessing applicationContext in view: http://mrhaki.blogspot.com/2011/11/grails-goodness-get-grailsapplication.html.
Use your layout
I am not sure about this one, so use at your own risk. The top one is of course extremely verbose. It would be annoying to call that over and over again in different views. So instead, call it once and make it a variable in your layout with g:set. I think the variable will be available in every view that uses that layout.... but not sure. Here are the docs for g:set -> http://grails.org/doc/latest/ref/Tags/set.html.
If I didn't get what context processors do in python I am happy to try again...

Ninject binding/unbind issue

I have a bit of a dilemma, which to be honest is a fringe case but still poses an issue.
Currently I am using Ninject MVC and bind all my controllers like so:
Kernel.Bind<SomeController>.ToSelf();
Which works a treat for 99% of things that I have needed to do, however at the moment I am doing some wacky stuff around dynamic routing and dynamic controllers which require me to manually write a method to get the type of a controller from ninject. Now initially I thought it would be easy, but its not... I was expecting that I could get the controller based on its name, but that didnt work.
Kernel.Get<IController>("SomeController");
That got me thinking that its probably because it only knows about a binding to SomeController, not IController. So I thought, I can just write all my bindings like so:
Kernel.Bind<IController>.To<SomeController>().Named("SomeController");
This way it should be easy to get the type of the controller from the name doing the previous code, however if I were to bind this way, I would have a problem when I come to unbind the controllers (as plugins can be loaded and unloaded at runtime). So the normal:
Kernel.Unbind<SomeController>()
Which was great, will no longer work, and I would have to do:
Kernel.Unbind<IController>();
However then I realised that I need to give it some constraint to tell it which binding for this type I want to unbind, and there seems to be no overloads or DSL available to do this...
So I am trapped between a rock and a hard place, as I need to satisfy the ControllerLookup method, but also need to keep it so I can add and remove bindings easily at runtime.
protected override Type GetControllerType(RequestContext requestContext, string controllerName) {
//... find and return type from ninject
}
Anyone have any ideas?
(Just incase anyone questions why I am doing this, its because of the way I am loading plugins, Ninject knows about the types and the namespaces, but within the context of creating a controller it doesn't know the namespace just the controller name, so I do this to satisfy the isolation of the plugin, and the location of the dynamic controller, it is a roundabout way of doing it, but it is what people have done with AutoFac before Example of similar thing with AutoFac)
In my opinion the bindings should be created once at application startup and not change anymore after the first resolve. Everything else can lead to strange issues. Unless you have proper isolation using an AppDomain for each plugin you can not really unload them anyway. Instead of unloading bindings you can make them conditional and disable them using some configuration.
If you really want to unload bindings then I suggest not to do it for single bindings but take advantage of modules. Load all bindings belonging to one plugin together in one or several modules and unload those modules instead of the single bindings.

What are good candidates for base controller class in ASP.NET MVC?

I've seen a lot of people talk about using base controllers in their ASP.NET MVC projects. The typical examples I've seen do this for logging or maybe CRUD scaffolding. What are some other good uses of a base controller class?
There are no good uses of a base controller class.
Now hear me out.
Asp.Net MVC, especially MVC 3 has tons of extensibility hooks that provide a more decoupled way to add functionality to all controllers. Since your controllers classes are very important and central to an application its really important to keep them light, agile and loosely coupled to everything else.
Logging infrastructure belongs in a
constructor and should be injected
via a DI framework.
CRUD scaffolding should be handled by
code generation or a custom
ModelMetadata provider.
Global exception handling should be
handled by an custom ActionInvoker.
Global view data and authorization
should be handled by action filters.
Even easier with Global action filters
in MVC3.
Constants can go in another class/file called ApplicationConstants or something.
Base Controllers are usually used by inexperienced MVC devs who don't know all the different extensibility pieces of MVC. Now don't get me wrong, I'm not judging and work with people who use them for all the wrong reasons. Its just experience that provides you with more tools to solve common problems.
I'm almost positive there isn't a single problem you can't solve with another extensibility hook than a base controller class. Don't take on the the tightest form of coupling ( inheritance ) unless there is a significant productivity reason and you don't violate Liskov. I'd much rather take the < 1 second to type out a property 20 times across my controllers like public ILogger Logger { get; set; } than introduce a tight coupling which affects the application in much more significant ways.
Even something like a userId or a multitenant key can go in a ControllerFactory instead of a base controller. The coupling cost of a base controller class is just not worth it.
I like to use base controller for the authorization.
Instead of decorating each action with "Authorize" attribute, I do authorization in the base controller. Authorized actions list is fetched from database for the logged in user.
please read below link for more information about authorization.
Good practice to do common authorization in a custom controller factory?
I use it for accessing the session, application data etc.
I also have an application object which holds things like the app name etc and i access that from the base class
Essentially i use it for things i repeat a lot
Oh, i should mention i don't use it for buisiness logic or database access. Constants are a pretty good bet for a base class too i guess.
I have used base controller in many of my projects and worked fantastic. I mostly used for
Exception logging
Notification (success, error, adding..)
Invoking HTTP404 error handling
From my experience most of the logic you'd want to put in a base controller would ideally go into an action filter. Action Filter's can only be initialized with constants, so in some cases you just can't do that. In some cases you need the action to apply to every action method in the system, in which case it may just make more sense to put your logic in a base as opposed to annotating every action method with a new actionFilter attribute.
I've also found it helpful to put properties referencing services (which are otherwise decoupled from the controller) into the base, making them easy to access and initialized consistently.
What i did was to use a generic controller base class to handle:
I created BaseCRUDController<Key,Model> which required a ICRUDService<TModel> object as constructor parameter so the base class will handle Create / Edit / Delete. and sure in virtual mode to handle in custom situations
The ICRUDService<TModel> has methods like Save / Update / Delete / Find / ResetChache /... and i implement it for each repository I create so i can add more functionality to it.
using this structure i could add some general functionality like PagedList / AutoComplete / ResetCache / IncOrder&DecOrder (if the model is IOrderable)
Error / Notification messages handling: a part in Layout with #TempData["MHError"] code and a Property in base Controller like
public Notification Error
{
set { TempData["MHError"] = value; }
get { return (Notification) TempData.Peek("MHError"); }
}
With this Abstract classes i could easily handle methods i had to write each time or create with Code Generator.
But this approach has it's weakness too.
We use the BaseController for two things:
Attributes that should be applied to all Controllers.
An override of Redirect, which protects against open redirection attacks by checking that the redirect URL is a local URL. That way all Controllers that call Redirect are protected.
I'm using a base controller now for internationalization using the i18N library. It provides a method I can use to localize any strings within the controller.
Filter is not thread safe, the condition of database accessing and dependency injection, database connections might be closed by other thread when using it.
We used base controller:
to override the .User property because we use our own User object that should have our own custom properties.
to add global OnActionExecuted logic and add some global action-filters

Resources