I’m trying to understand how the Convention plugin determines when to do URL interpretation. In some REST Plug-in examples I see PrefixBasedActionMapper configured with ”/rest:rest,:struts” and it seems that Convention is only applied to the rest mapper and not the DefaultActionMapper. Is this correct? Either way, under what conditions does the Convention plugin kick in for requests?
I’ve been googling like a mad-man these last two days and can’t seem to find any explanation. Inspecting the plugin source didn't give any insights either.
They are different. Convention Plugin is not about URL/action mapping. It just search java classes and create action configs from them.
However, you can tell the plugin to search specific root packages using the property struts.convention.action.packages. e.g.
<constant name="struts.convention.action.packages" value="com.mycompany.myactions.myconvention.*"/>
Related
I've read the official documentation on filter dependencies, but I cannot find any information about how the ordering is calculated (for different filter classes). Is it at runtime or during the build process?
I know that with Plugins we can participate in building web.xml and there we can make sure we come after a certain filter.
Does dependsOn also work by adding the filters to the web.xml file?
The filters defined in grails-app/conf are not the same as Servlet filters which are defined in web.xml. These are two different things.
The order of Grails filters is determined when the application starts up.
I have a Grails project and want to add existing filters from a JAR file.
I used the WebXmlConfig plugin, mentioned in this answer:
How to add filters to a Grails app
and that worked great for a single filter, but I can't figure out how to extend that to more than one filter.
Do I need to change approach and edit the web.xml template directly?
I'd use the pluginator plugin and put the definitions in doWithWebDescriptor just like you would in a plugin - you can add as many elements as you want. It's a slick plugin that lets apps do things that are generally only supported in plugins, like conveniently editing web.xml (although with a seriously weird DSL) and registering custom artifact types.
What is the recommended approach when an application Controller name conflicts with the name of a plugin's Controller?
I've seen these Grails JIRAs:
GRAILS-4240
GRAILS-1243
...and Burt Beckwith's replies to these two threads imply that the only recourse is to rename one of the Controllers (presumably the application Controller since hacking plugin code is not desirable)
How to use the package name to differentiate between classes in grails?
How to extend/override controller actions of plugins?
However, Burt's own spring-security-ui plugin advocates the exact approach of naming an application Controller the same as a plugin Controller - see spring-security-ui docs.
This approach actually seems to work in both development mode (grails run-app) and when the app is deployed as a WAR. So can this functionality be depended on? If so, what is the Controller conflict resolution rule? The grails docs do not make any mention of it. Perhasps Burt can share his insight?
Having a "plugin" architecture like grails' without even a basic namespacing facility to handle conflicts like this seems pretty broken to me...
The problem is that while you can use packages for any artifact, the convention for controllers is to remove the package and "Controller" to create URLs, e.g. PersonController -> /appname/person/action_name. So in effect everything gets flattened.
In 1.2 and more so in 1.3 things were changed so plugins are compiled separately from application code (and are compiled first) and this gives you the opportunity to replace a plugin artifact with the application's version. Since you shouldn't edit plugin code, this gives you the flexibility to extend or replace a plugin artifact just by using the same name.
I tend to use UrlMappings to get around stuff like this when there are two similarly named controllers. For example say you have an admin UserController that allows low-level CRUD actions and a regular UserController that users work with. I'd name the admin controller AdminUserController and map it to /admin/user/* and leave UserController as is. The admin GSPs will be in views/adminUser and the others will be in views/user so there's no conflict there. This has the added benefit of being able to easily secure - map /admin/** -> ROLE_ADMIN. The conventions are convenient, but this is a simple configuration step that solves this issue for me.
The good news is that GRAILS-1243 will definitely be implemented in 2.0 and possibly in 1.4. And the plugin that Kim Betti references in the comments of GRAILS-1243 looks interesting.
I'm writing a Grails app which I'd like 3rd parties to augment at runtime. Ideally they would be able to add a JAR/WAR to the webapp directory which contains new domain, controller and service classes, new views, and other content.
Is there a simple way to do this within grails? Would it be simplest to create a startup script which copies the new classes etc. into the relevant directories and then updates grails.xml and web.xml?
You will be able to do this in version 2 of grails in which plugins will be also OSGI plugins http://jira.codehaus.org/browse/GRAILS/fixforversion/15421
It seems that the Grails plugins will actually fit quite well for this: http://www.grails.org/Understanding+Plugins
A plugin can do just about anything... One thing a plugin cannot do though is modify the web-app/WEB-INF/web.xml or web-app/WEB-INF/applicationContext.xml files. A plugin can participate in web.xml generation, but not modify the file or provide a replacement. A plugin can NEVER change the applicationContext.xml file, but can provide runtime bean definitions
I'm working on on a site built using struts2. The vast majority of our targets generate xml, so mapping the result to a jsp page makes sense. A couple of our targets actually generated binaries. I'm wondering if there is a convenient way to say that the result should come from a servlet/controller instead of a jsp.
Obviously this could be done by modifying the web.xml so the struts filter doesn't apply to those targets and mapping those targets as servlets, but this is non-ideal. Currently, the struts filter applies to the entire site, and we would like to keep it that way.
Ideas?
Thanks!
I am not sure I understand you scenario, but it seems to me you want the Stream Result
Here you can find an excellent tutorial with code examples about Struts2 file upload and file download that covers the Stream Result:
http://www.jeetrainers.com/struts2-course/chapter12-13-1-1#slide