> I hope I am not abusing this list by asking > a design question... Not at all.
> In a typical web app using MVC design (in this > case Maverick) is it reasonable that each page > with dynamic content has its own command mapping > (and associated class)? Yes it is. But many commands can be associated with same class. And not all commands need a controller. > As I refactor my app using Maverick, I am finding > my library of classes growing significantly, and > started to wonder if I should be consolidating some > classes my passing parameters for different code paths. For consolidating and using separate code paths with maverick you can use controller parameters. > One class per action (re: dynamic web page) seems > clean, but is it execessive? Yes, it is. > The classes are relatively simple, sharing helper > classes where the code is similiar, but bascially > I have a lot of separate classes implementing there > own insidePerform() where the model is created for > the JSP. Here is what I have been doing lately. First of all I have so called "components". These components are initialized by a servlet filter and they can be in any scope defined using separate components.xml file (servlet scope, session scope, request scope). I use components only to read only things. Eg. retrieving something to View from database. I do not use Maverick's model that much (mainly for error reporting $model.errors.XXX and to remember eg. form parameters so that user does not need to re-enter those values, if something went wrong). My so called components are ordinary JavaBeans that can implement one of defined interfaces (one interface for each scope - defaulting to request scope). These are the cases when I use maverick actions: 1. When user posts form (e.g. updating something, inserting something, deleting something). - populate maverick action class with parameters - validate input parameters - error reporting 2. When user clicks a link that does one (or some) of the following: - update operation - insert operation - delete operation I do not use maverick actions for retrieving something, for retrieving I use my components. There is one more important use for maverick actions: Authentication and Authorization. I use controller parameter for authorization (e.g. roles-required: administrator, user or user-type-required: 100). So I have base classes ProtectedController and PublicController (one with authentication and optional authorization and one without these). If I have actions that do not modify anything (only retrieves data) then I can use ProtectedController or PublicController. So I have lots of action that does nothing more except use ProtectedController that returns "success", "authentication" or "authorization" or PublicController that always returns "success" or actions that doesn't have controller class at all. The components have a name and those components are automatically available in JSP, Velocity, or whatever templating technology you are using (components are located in servlet, session and request attribute collections). This leaves one problem. If I have a component that needs authorization, then this needs to be done in a view (of course I could write some authentication code in component itself, but I have not needed it): #if ($user.type == $usertype.administrator) #foreach $item in $administrativeStuff ... #end #end I attached my ComponentFilter and some test components in this mail. ComponentFilter is configurated in your web.xml like this: <filter> <filter-name>component</filter-name> <filter-class>common.filters.ComponentFilter</filter-class> </filter> <filter-mapping> <filter-name>component</filter-name> <url-pattern>*.m</url-pattern> </filter-mapping> I apply it only to Maverick actions. Regards Aapo
<?xml version="1.0"?> <components> <component name="servletContextComponent" class="common.components.ServletContextTestComponent" context="servlet"/> <component name="sessionContextComponent" class="common.components.SessionContextTestComponent" context="session"/> <component name="requestContextComponent" class="common.components.RequestContextTestComponent" context="request"/> </components>
RequestContextComponent.java
Description: Binary data
RequestContextTestComponent.java
Description: Binary data
ServletContextComponent.java
Description: Binary data
ServletContextTestComponent.java
Description: Binary data
SessionContextComponent.java
Description: Binary data
SessionContextTestComponent.java
Description: Binary data
ComponentFilter.java
Description: Binary data