On Nov 5, 2007 1:44 PM, Brian Pontarelli <[EMAIL PROTECTED]> wrote: > Okay. The example is in the SmartURLs repository: > > http://smarturls-s2.googlecode.com/svn/trunk/apps/crud-example/ >
Are you using a modified TLD? When I tried to run it in Eclipse, Tomcat complained Nov 6, 2007 5:40:25 AM org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service() for servlet default threw exception org.apache.jasper.JasperException: /WEB-INF/content/index.jsp(32,12) According to TLD or attribute directive in tag file, attribute fieldValue does not accept any expressions at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:40) Using an inline Action to run a Prepare method is an interesting idea, as is flexing the form target with an expression. I also note good use of the HTTP error handlers (404.jsp and 500.jsp). We should make sure those are mentioned in the Cookbook :) > if (ServletActionContext.getRequest().getMethod().equals("GET")) { > >or I could write a variation on Action that is more knowledgable about > GETs and POSTs and invokes two different methods depending on the method. Oooh, that's a good one too! In working with this myself, I've started to create "more knowlegable" Actions and methods, to help automate the workflow in the SmartURLs spirit. One notion is to have a CRUD action sniff for an ID. If there's a non-empty ID, we can deem it an update, otherwise it's a create. Of course, for delete and read, we have to use some type of hidden field, and/or sniff the HTTP method (as shown by that expression). (What happens here if a web service or Ajax request hits an Action using PUT or DELETE?) Having ascertained what kind of CRUD request is being made, a "smart" input method can return $crud-input instead of plain-old "input". In this way, from the same Action, we can easily map back to a create-input, read-input, update-input, or delete-input page. (Which may just be wrappers around an include tag.) This strategy also works well for cancel. A smart cancel method can do things like "exit" to "higher" workflow if a create is canceled, but return to the local index page if an update is canceled. Strategies like this help to simplify the page logic, so that they only need to worry about submitting to simple actions like "create" or "cancel", without knowing anything about the overall workflow. (It may be a fetish, but I'm a fan of low-maintenance pages.) Anyway, over the weekend, I put together a couple of MailReader implementations. One uses a single execute method per Action (thin Actions), and the other uses multiple methods per Action (rich Actions). * (thin) http://smarturls-s2.googlecode.com/svn/tags/mail-reader-input-support-2/java/actions/ * (thin) http://smarturls-s2.googlecode.com/svn/tags/mail-reader-input-support-2/webapp/WEB-INF/results/ * (rich) http://smarturls-s2.googlecode.com/svn/tags/mail-reader-input-support-2/java/action/ * (rich) http://smarturls-s2.googlecode.com/svn/tags/mail-reader-input-support-2/webapp/WEB-INF/result/ Of course, whether or not to use "aliases" has been a longstanding discussion point (alongside of whether to expose actual domain objects to an Action). There are pros and cons either way, and I'm not sure if there is any one right answer. Of course, for SmartURLs today, in order to use action validation we have to use the thin approach. The validation annotations for multiple methods are glommed together in 2.0, and SmartURLs doesn't seem to pickup on the method mappings for the validation.xml. Though, while working on the multiple-methods prototype, I found that the SmartURLs index page handling clarifies the "rich" paradigm. I setup a package and result-folder for each rich Action , which SmartURLs automatically puts together into a namespac, and named the Action "Index". The Index model avoids ugly notations like /user/user to access the UserAction. Using method invocation, the Index-package strategy leads to a style where the forms kept submitting back to the Index action, but used a different method for different buttons. Of course, since S2 supports post-back forms, we don't actually have to specify the action, just the method. Taking it a step farther, I refined the rich Action implementation to give action names to the alias methods. Along the way, I rediscovered using "doMethods". A keen benefit of doMethods is that a GUI will sort all the Action aliases together, clarifying the API. The doMethod form might also make for a better convention than blindly exposing any old public method with zero parameters. This "prototype" approach is the head right now. * http://smarturls-s2.googlecode.com/svn/trunk/apps/mail-reader/java/action/ * http://smarturls-s2.googlecode.com/svn/trunk/apps/mail-reader/webapp/WEB-INF/result/ The head prototype uses a bunch of ActionName annotations to map the "doMethods" to top-level actions. So "/user/index!create" becomes "/user/create". Of course, this would be better handled by an convention that automatically mapped doMethods on an Index Action to action names. Or maybe even #action-names. I note that that the latest GMail URIs are using a style like * http://mail.google.com/mail/#inbox * http://mail.google.com/mail/#compose This looks a lot like, say, * http://apache.org/licenses/#clas where we are linking to an anchor target in an index.html file. I don't know what motivates GMail to use this convention, but, in our case, it would help avoid collisions between automatically mapped Index aliases and other actions developers might map. But, when I tried it with the ActionName annotation, it didn't seem to work :( So for the SmartURLs/CodeBehind plugin, I'd suggest that we * Fix the method-level action validations (or support -validation.xml for methods). * Automatically map "doMethods" on an Index Action to "method" . * For access to methods on other Actions, fall back to the !-bang syntax. -Ted. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]