Discussions

News: Struts Best Practices

  1. Struts Best Practices (78 messages)

    There has been no limit on the talk of best practices with Struts. This latest article discusses working with dynamic fields, error categorization, validation, security, prepopulation, and many more best practices.

    Read more in Struts best practices

    Threaded Messages (78)

  2. Struts Best Practices[ Go to top ]

    Nice Article for the new Users of the Struts . I have skimed through the entire article and would like to share my experience of DTO(Value Object) transformation part .Here I would like to stress on the point that , do we really need the FormBean for all the interactions .If we dont have a server side validations then we dont require the FormBeans , I would not populate the form Beans first and then use the same again to Populate the DTO.Although I can populate the DTO from the Request Object in the Action Object.
    My point here is to suggest that we dont need to introdude the FormBean for each Action unless we have to do the ServerSide validations.Otherwise we are doing
    1) Redundant work , populating the FormBean(View Helper) and then repopulating the DTO . A performance overhead is here.
    2) Increasing the Development Time as you have to code the FormBean .Here you would say it does nor matter as you could use the IDE but then the maintainance will be more .
    I am sure there will be the other users with the same opinion
    Regards
    Vicky
  3. Better separation[ Go to top ]

    I agree with you: sometimes FormBeans seem cumbersome, but in my opinion they positively keep data separated from the use of it.
    In the Actions you can invoke external classes that manage the conversions from beans to VO. This operation is related to business logic and not only with the view stratus, because you can't always have a one-to-one relationship between FormBeans and VO (but in the case you are coding a strict DB GUI).
    Going back to the article, I have to say that using reflection by custom methods or by BeanUtils classes means slowing down the application, expecially if you don't have only very small DB tables and only very small VO (few columns).
  4. Struts Best Practices[ Go to top ]

    If we dont have a server side validations then we dont require the FormBeans , I would not populate the form Beans first and then use the same again to Populate the DTO.Although I can populate the DTO from the Request Object in the Action Object.My point here is to suggest that we dont need to introdude the FormBean for each Action unless we have to do the ServerSide validations.Otherwise we are doing 1) Redundant work , populating the FormBean(View Helper) and then repopulating the DTO . A performance overhead is here.2) Increasing the Development Time as you have to code the FormBean .Here you would say it does nor matter as you could use the IDE but then the maintainance will be more .I am sure there will be the other users with the same opinionRegardsVicky
    Looks like you are not using 'nested' taglib. Take a glance and get rid of all redundant work and populate/repopulate issues. Forms are usually simple as this:
    class MyActionForm extends ActionForm{
     private MyComplexDTOOrBusinessObject myComplexDTOOrBusinessObject;

     setMyComplexDTOOrBusinessObject( MyComplexDTOOrBusinessObject v ){
       this.myComplexDTOOrBusinessObject = v
     }

     getMyComplexDTOOrBusinessObject(){
      return myComplexDTOOrBusinessObject;
     }
    }
  5. Looks like you are not using 'nested' taglib. Take a glance and get rid of all redundant work and populate/repopulate issues. Forms are usually simple as this:
    class MyActionForm extends ActionForm{ 
    private MyComplexDTOOrBusinessObject myComplexDTOOrBusinessObject; 
    setMyComplexDTOOrBusinessObject( MyComplexDTOOrBusinessObject v ){   this.myComplexDTOOrBusinessObject = v } 
    getMyComplexDTOOrBusinessObject(){  return myComplexDTOOrBusinessObject; }}
    I have not used the TagLibs as never really need it , we have a lot of manipulations to be done at rendering and did not have the simple rendering .As I have pointed out earlier we dont need to write the FormBean blindly for all the actions .And if we do that don't write the DTO(VO) blindly then .Your FormBean does contain all the Data what the Form have posted so you can pass the same to the different tier , although it is not a POJO .It is not mentioned a good practice but again it depends on the Project .If you have the requirements clear and you are sure about the Deployment Strategies like whethere the system is Distributed , if the Business Tier and Presentation Tier are a part of the same process etc ...
    For a project requirement where the Presentation and EJB Tier lie within the same process we can pass the FormBean as a VO , but if both the Tiers are in different process we can still do but then both Tiers have to have the corresponding API .In this case your Bussiness Tier doesnot really need the Struts API , rathar that we could have the VO(DTO) of POJO form there.
    We can do all this but you have to take the MAINTAINANCE Issue into consideration.
    It may nice to use the FormBean for some cases but we should evaulate and then use it .
    Now looking at your code snippet you need to write a heavy logic of reading a data form Bean and Populate in the DTO .
    I can make the Struts work in the "Dispatcher View Pattern"(MVC PULL) when required , here I dont take the FormBean population in account Or let the "Service to Worker "(MVC Push) go ahead.

    Regards
    Vicky
  6. Your FormBean does contain all the Data what the Form have posted so you can pass the same to the different tier , although it is not a POJO .It is not mentioned a good practice but again it depends on the Project .If you have the requirements clear and you are sure about the Deployment Strategies like whethere the system is Distributed , if the Business Tier and Presentation Tier are a part of the same process etc ...For a project requirement where the Presentation and EJB Tier lie within the same process we can pass the FormBean as a VO , but if both the Tiers are in different process we can still do but then both Tiers have to have the corresponding API .
    There is no excuse for using the ActionForm in any other layer. It doesnt depend on any kind of project, be it distributed or non-distributed. That is the most horrible thing you can do. U r not only tying ur business and persistence layers with ur controller component, but also getting tied to a specific Web-MVC framework. Think abt it, tomorrow if u decide to move from Struts to some other web framework, u will end up having to change ur business and persistence layers.

    There was this guy who I interviewed recently who said that in his company they do SQL queries from JSP pages and he said that they were very productive since they could make changes to persistence code within the JSP, do a refresh in the browser and thats it. And this was what he claimed to be easy MAINTAINABILITY.

    Well, I think u shud really check out the nested taglib which Konstantin suggested. I didnt know abt it, but will definitely take a look at it. From his code sample, it looks absolutely trivial and doesnt seem to have heavy logic as u seem to suggest.
  7. There is no excuse for using the ActionForm in any other layer. It doesnt depend on any kind of project, be it distributed or non-distributed. That is the most horrible thing you can do. U r not only tying ur business and persistence layers with ur controller component, but also getting tied to a specific Web-MVC framework.
    Well by the Project type it means additional things other than the Distributed Systems etc ... Ok let me explain it a more
    1) Project where it is fixed that it can't be transferred to other Web MVC framework , I mean it is final.Inthis case why can't we pass the FormBean as a VO to Bussiness Tier.
    2) Project with First case but the Distributed One , the BT(Bussiness Tier) at different location , here you are making the dependency to Struts API.In this case we can pass FormBean as VO but that will make the Struts API dependency .So the proper way will be to create a fresh POJO VO. In case one as there will be the BT and PT in same process and the app is dependent on the Struts API genuinely .
       I can think of many more options .... but we have to really evaulate .Ideally your design is never final at first level the refractoring always make it proper/better ...
    Think abt it, tomorrow if u decide to move from Struts to some other web framework, u will end up having to change ur business and persistence layers.
    I am keeping the Struts MVC Final , although it is JSP centric .\
    There was this guy who I interviewed recently who said that in his company they do SQL queries from JSP pages and he said that they were very productive since they could make changes to persistence code within the JSP, do a refresh in the browser and thats it. And this was what he claimed to be easy MAINTAINABILITY.
    Well if there is no reusability of the Bussiness Logic , it can be fine .We were using the page centric model before the MVC.Again I would say it depends on the need.But you should have asked the guy more about the MVC and the Page Centric Model , I hope you must have .
    Well, I think u shud really check out the nested taglib which Konstantin suggested. I didnt know abt it, but will definitely take a look at it. From his code sample, it looks absolutely trivial and doesnt seem to have heavy logic as u seem to suggest.
    If I require it I will definetly go ahead with tag libs. Where will you populate the VO , it has either to be populated from the FormBean or the HttpRequest .. He is not showing that part , so you have some additional part , either the Framework does it for you or App Developer does it .
    Regards
    Vicky
  8. ...Project where it is fixed that it can't be transferred to other Web MVC framework , I mean it is final.Inthis case why can't we pass the FormBean as a VO to Bussiness Tier. ...
    It is tricky to predict the future. You say that or are being told that today. But history has shown that this is seldom the case. Technology changes quickly and especially in the web tier - for at least a few reasons.

    Struts has had its day and might still continue to be useful. If one is starting a new project, I would look to something else.
  9. ... Think abt it, tomorrow if u decide to move from Struts to some other web framework, u will end up having to change ur business and persistence layers.
    Good point.

    And what if you need more than the browser can give and need to Webstart a Java UI?

    I always try to have people at least think of how they would implement a different UI or UI technology. Even if that "UI" is a batch program. Doing JUnit tests helps alot with this.
    There was this guy who I interviewed recently who said that in his company they do SQL queries from JSP pages and he said that they were very productive since they could make changes to persistence code within the JSP, do a refresh in the browser and thats it. And this was what he claimed to be easy MAINTAINABILITY.
    It seems he was confusing maintainability with quick change/deploy.
  10. Struts Best Practices[ Go to top ]

    The way in which I tackle this is as follows:

    If the resulting page is not going to need to use the data in your DTO for anything (i.e. the data is view only) then there is no need to populate your form bean with the data. If you have a collection of DTO's you can just iterate over them to display to the end user.

    However if the users are going to update/change the data it is best to prepopulate the form. This population of the form should take place in some sort of Business Delegate Class.

    Mike
  11. Please Help <logic:iterate> tags...[ Go to top ]

    Hello there!!
    Please help us with a problem: We tried to use Struts (Ver 1.1) <nested:iterate> tag to iterate thru' collection of objects. The collected was a List. Now when we change that to a Set, we get an exception as follows:

    java.lang.IllegalArgumentException: Property 'blocks' is not indexed
    org.apache.commons.beanutils.PropertyUtils.getIndexedProperty(PropertyUtils.java:517)
    org.apache.commons.beanutils.PropertyUtils.getIndexedProperty(PropertyUtils.java:428)
    org.apache.commons.beanutils.PropertyUtils.getNestedProperty(PropertyUtils.java:750)
    org.apache.commons.beanutils.PropertyUtils.getProperty(PropertyUtils.java:801)
    org.apache.struts.util.RequestUtils.lookup(RequestUtils.java:952)
    org.apache.struts.taglib.html.CheckboxTag.doStartTag(CheckboxTag.java:207)
    org.apache.struts.taglib.nested.html.NestedCheckboxTag.doStartTag(NestedCheckboxTag.java:94)
    org.apache.jsp.web.planner.PlannerCycleDefinedDays_jsp._jspx_meth_nested_checkbox_0(PlannerCycleDefinedDays_jsp.java:1271)
    org.apache.jsp.web.planner.PlannerCycleDefinedDays_jsp._jspService(PlannerCycleDefinedDays_jsp.java:752)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:94)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:324)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:292)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:236)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:810)


    According to the documentation given by Struts, any Collection object can be used in the <logic:iterate> and <nested:iterate> tags. Set is very much a Collection according to J2SE 1.4 specs. Please help us if u could..

    Thanks in Advance..
  12. Hello there!!Please help us with a problem: We tried to use Struts (Ver 1.1) <nested:iterate> ..
    Most likely you have problem not with iterate tag but somewhere inside the loop body. Feel free to contact me directly if need more help.
  13. Lack of Examples[ Go to top ]

    Yeah ! I agree, no doubt, it's a good article but it should contain some more examples. I read it and found that it's little bit difficult to understand some points due to the lack of examples.

    However it is good :)

    GiveMeJ
    Sanjeev
  14. Struts Architecture[ Go to top ]

    I would say the practice of Form beans makes the code more cleaner as once we have values set to the form the values are autoimatically picked by the jsp by introspection no need to ever call the getter.(Provided we are setting vales in form and using the same attribute names in jsp)
    There are cases whenw e need to hold the values of the pages then we need to over ride the reset() method.
    I would personally go with the action,form and controller as its like setting a process in place....once we develop a flow its so simple the subsequent flows

    Each time we need a new functionality to be developed...its pretty straight forward..just add an action,form,change the strutsconfig..and write ur business in the next tier...and we r done...

    Regards,
    Tharun G Babu
  15. Each time we need a new functionality to be developed...its pretty straight forward..just add an action,form,change the strutsconfig..and write ur business in the next tier...and we r done...Regards,Tharun G Babu
    It could be even simpler with XDoclet ( http://xdoclet.sourceforge.net/xdoclet/tags/apache-tags.html ): you will never need to touch struts config file and worry about its validity:

    /**
     * @struts.form name="confinedspace.crudForm"
     */
    public class ConfinedSpaceCRUDForm extends AbstractForm {
    ....
    }

     /**
     * @struts.action path="/confinedspace/crud/delete"
     * validate="false"
     * name="confinedspace.crudForm"
     * attribute="confinedspaceCrudForm"
     * scope="session"
     *
     * @struts.action-forward name="crud" path="confinedspace.crud"
     * @struts.action-forward name="list" path="/do/confinedspace/list"
     * @struts.action-forward name="listRefresh" path="/do/confinedspace/list/refresh"
     */
    public class ConfinedSpaceCRUDAction extends AbstractAction {

    }
  16. FormBean performance overhead[ Go to top ]

    Another note on FormBeans performance overhead:
    if you declared in the action mapping to keep the FormBean in the request then the reset() method is called even if the formBeam is repopulated with the request properties. This can have a quite nagative impact if your reset() method is time consumening due to some calculations or BD access.

    Any opinions on this?
  17. Prefer FormBean's[ Go to top ]

    I would see this the other way. Form Beans allows you to de-couple UI from business object. If there is a change in UI (like introducing a check box) you don’t have to necessarily modify your DTO.
    Also Form Beans may be very simple POJO and so maintenance wouldn’t (shouldn't) be much (as that of DTO’s).

    -Kirupa
  18. Prefer FormBean's[ Go to top ]

    Also Form Beans may be very simple POJO and so maintenance wouldn’t (shouldn't) be much (as that of DTO’s).
    How can u call it a POJO. It extends from ActionForm.
    Form Beans allows you to de-couple UI from business object.
    I dont think so. Extracting parameters from the request or from the form bean should be done in the controller/ActionClass. Either way, it is decoupled from business logic. But many people write business logic in action classes or pass the ActionForm to the business layer in which case business logic gets tightly coupled with Struts.
  19. Prefer FormBean's[ Go to top ]

    I dont think so. Extracting parameters from the request or from the form bean should be done in the controller/ActionClass. Either way, it is decoupled from business logic. But many people write business logic in action classes or pass the ActionForm to the business layer in which case business logic gets tightly coupled with Struts.
    We make sure our Forms implement a business level interface and use these interfaces in our business layer. I think it is ok to have the UI use the business layer but not the other way round. Experts correct me if I am wrong.
  20. Prefer FormBean's[ Go to top ]

    <blockquoteWe make sure our Forms implement a business level interface and use these interfaces in our business layer. I think that is good approach, but wud luv to hear from others too.
    I think it is ok to have the UI use the business layer but not the other way round. Experts correct me if I am wrong.
    100%
  21. Prefer FormBean's[ Go to top ]

    We make sure our Forms implement a business level interface and use these interfaces in our business layer.
    I think that is good approach, but wud luv to hear from others too.
    On second thoughts, I am beginning to think that this might not be a good approach. What abt the data types. ActionForm does not support datatype conversion. So all the ActionForm variables are Strings. So if u implement the ActionForm from a business interface, it take it that u have String variables in ur business layer and probably u do a conversion later on to the appropriate data type. Or am i missing something here.
  22. Prefer FormBean's[ Go to top ]

    The RequestProcessor DOES provide datatype conversion when populating the form bean. So it's a valid approach to have form bean implement a business interface and use it in the business layer as long as you are sure the input data is clean (eg. from dropdown list or checkbox, etc.).
  23. Re FormBean's[ Go to top ]

    For me this approach is good. It implies to have multiple getter/setters and for example extract/insert methods that match each non-typed attribute to a typed attribute.
    The form bean will implement a bunch of business level interface, for example address blocks, identification block and so on, used in the business validation.

    I have another form related problem:
    For a JSP that reuse common blocs (e.g. address), you must declare each address attribute in the new ActionForm. Is there a way to avoid this by having an address form that can be submited at the same time? I don't think it's possible...
  24. Re FormBean's[ Go to top ]

    I have another form related problem:For a JSP that reuse common blocs (e.g. address), you must declare each address attribute in the new ActionForm. Is there a way to avoid this by having an address form that can be submited at the same time? I don't think it's possible...

    Yes it is possible. Create yourself a bean to hold the fields of the address. Give the form beans for both pages a property (called "address") whose type is of your address bean. You need to make sure that when your form beans are created that the address property is populated with a bean:

        private Address address = new Address();

    Then in your JSP you refer to the address properties using dotted notation thus:

        <html:text property="address.street"/>

    Actually this very example is in the manual

    You can then develop an include JSP for address. If you want to give your address property different names (for example a form might include billing and delivery addresses) then you might want to experiment with using the expression-language versions of the tag libraries and setting the name of the property in a bean.

        <html:text property="${addressProperyName}.street"/>

    Even better, develop a tile and pass the property name as a parameter.
  25. Prefer FormBean's[ Go to top ]

    I dont think so. Extracting parameters from the request or from the form bean should be done in the controller/ActionClass. Either way, it is decoupled from business logic. But many people write business logic in action classes or pass the ActionForm to the business layer in which case business logic gets tightly coupled with Struts.
    We make sure our Forms implement a business level interface and use these interfaces in our business layer. I think it is ok to have the UI use the business layer but not the other way round. Experts correct me if I am wrong.
    Not saying I am an expert. But I agree. If I understand you correctly. I know for sure that you don't want a bunch of data objects directly referenced in the UI layer - if used at all.
  26. Prefer FormBean's[ Go to top ]

    I would see this the other way. Form Beans allows you to de-couple UI from business object. If there is a change in UI (like introducing a check box) you don’t have to necessarily modify your DTO.
    I don't see the need for DTOs. You have your form beans, which:
    * deliver input data from HTML form;
    * provide hook for input data validation;
    * prepare data for output.
    And you have your business objects, which can be used from either action class or from a form bean if a particular action mapping does not have action class. Business objects interact with database/EJB and persist themselves when needed. That's it.
  27. Prefer FormBean's[ Go to top ]

    <blockquoteI don't see the need for DTOs.How do you pass data from the controller to ur business layer.
  28. Prefer FormBean's[ Go to top ]

    I don't see the need for DTOs. You have your form beans, which:
    How do u pass data from ur controller to ur business layer.
  29. Prefer FormBean's[ Go to top ]

    I don't see the need for DTOs. You have your form beans, which:
    How do u pass data from ur controller to ur business layer.
    What data?
  30. Action Form's scope parameter[ Go to top ]

    Here's another best practice:

    Explicitly set the scope of HTML:FORM tags to "request" for Action Forms that don't need to be saved to Session. The default is "session" and in load balanced clustered environments with session replication, if the scope is not defined, Struts will put the Action Form in the user's HTTP session and it will needlessly get replicated in the cluster. Also, explicitly set the scope to "request" in Action Mapping definition.

    Did anyone else ever run into a similar situation?
  31. Prefer FormBean's[ Go to top ]

    I don't see the need for DTOs. You have your form beans, which:
    How do u pass data from ur controller to ur business layer.
    What data?
    Sorry for not being clear. I mean passing the form parameters to the business layer.
  32. Prefer FormBean's[ Go to top ]

    I don't see the need for DTOs. You have your form beans, which:
    How do u pass data from ur controller to ur business layer.
    What data?
    Sorry for not being clear. I mean passing the form parameters to the business layer.
    You were fine. I was pretty sure what you meant but I wanted you to define "data".

    As mentioned earlier, no need to "pass" anything. One way to deal with it is via the "factory pattern" (I get a gold star today : )) and interfaces. Create or retrieve an object (Business/Proxy/DTO(shudder)) this way and stick it in the Form bean. Use delegate methods to populate the object. The some method can be used if you have to use DTOs (now I have to wash my mouth out again) cause you are using Entity Beans. If you look at Martin Fowler's Architecture book you will see in his full discusion on DTOs, that you should put them back into some proper object as soon as possible.
  33. Prefer FormBean's[ Go to top ]

    One way to deal with it is via the "factory pattern" (I get a gold star today : )) and interfaces. Create or retrieve an object (Business/Proxy/DTO(shudder)) this way and stick it in the Form bean. Use delegate methods to populate the object.
    Thnx for the tip Mark.
    The some method can be used if you have to use DTOs (now I have to wash my mouth out again) cause you are using Entity Beans.
    hey its not me....its Michael Jouravlev who uses entity beans :)
  34. Prefer FormBean's[ Go to top ]

    hey its not me....its Michael Jouravlev who uses entity beans :)
    Sorry. Should have used third person. :)
  35. FormBean performance overhead[ Go to top ]

    Yes, i've got one : AVOID accessing a database in your restet() method !!! Event if, for some reason or another, you need to access data that are stored in a database, access a local cache but never access the database itself.

    Sebastien
  36. FormBean performance overhead[ Go to top ]

    [...] This can have a quite nagative impact if your reset() method is time consuming due to some calculations or BD access.Any opinions on this?
    The reset method should not be time consuming : it's just supposed to reset checkbox properties. See http://struts.apache.org/faqs/newbie.html#reset
    Why would you need to calculate anything or get data from the DB for this ? Sorry, but I cannot see any concrete example.
  37. FormBean performance overhead[ Go to top ]

    Another note on FormBeans performance overhead:if you declared in the action mapping to keep the FormBean in the request then the reset() method is called even if the formBeam is repopulated with the request properties. This can have a quite nagative impact if your reset() method is time consumening due to some calculations or BD access.Any opinions on this?
    If you chain your actions by forwarding, you can easily distinguish is a particular action is called at the very beginning of request processing, or somewhere in the middle. Just stick a token into HttpRequest object.

    If you chain your actions using redirection, or if the same instance with scope higher that "request" is called servicing another request, you can just set a flag in the form bean itself.

    I'd say that action class/form bean should not know anything about database, they should work with business objects. It is the BO/peristence problem to properly cache data.
  38. Struts Best Practices[ Go to top ]

    I think it's a fairly academic article. Real-life best practices for Struts would include:

    1. Custom Action hierarchy - For most real-world applications you'd want a single point of control, which would provide:
     + Helper methods for the rest of the actions hiearchy
     + Application exception handling

    2. Error categorization - Again this is good, but in most enterprise level applications there are two notable differences:
     + Resource bundles are stored in database (made available by custom tags)
     + During application development/integration, the developers usually want the entire stack of messages. Error categorization is good only if this categorization is hierarchical in nature, with a capabaility to see the entire stack, if required. And in production, this capability should then be disabled as easily as by changing a property(debug="false", for example).

    3. Application security - I can understand the obvious fears about performance when Servlet filters are used for authentication, however, most applications I've seen resort to tighter checks rather than brushing the problem off by saying "This option is efficient, but overkill for the problem at hand"

    4. On demand lazy loading of application data sounds good in principle, but with dynamic data, you run the gauntlet of ensuring this data is refreshed when it changes. With several different chunks of such data, it isn't a trivial task

    These are just from the top of my head. There are more comprehensive lists on Ted Husted's website
  39. What you descrive here is in fact a two steps process :

    1) Authentication : ensure that the user is who he claims he is (validate credential against user repository and then load user role). The J2EE Server can do this for your application, and THIS is the best practice ;

    2) Authorization : is the current authenticated user authorized to access the resource he request (the resource beeing an URL) : Struts provides a declarative authorization mechanism in its config file (generally named struts-config.xml). For each path, declare the list of role which can actually access it, and that's all ("role" attribute). I think that THIS is the best practice.

    Sebastien
  40. What you descrive here is in fact a two steps process :1) Authentication : ensure that the user is who he claims he is (validate credential against user repository and then load user role). The J2EE Server can do this for your application, and THIS is the best practice ;
    Well, that's debatable. Container managed security is very limited.

    1. If you want to have a small login form on every page, you cannot use the containers "single point of entry".

    2. The simple role-based approach does not fit for all sorts of applications.

    3. Setting up realms for containers is not portable.

    4. Not being able to keep all classes related to authentication/authorization within your webapp can lead to classloader related problems

    If you look at Acegi Security for Spring, they explicitly recommend not to use the included container integration stuff.
  41. Don't Bash CMA[ Go to top ]

    Well, that's debatable. Container managed security is very limited.
    I hardly think "very" limited is an accurate description. It has some limitations but it does fit many cases.
    1. If you want to have a small login form on every page, you cannot use the containers "single point of entry".
    why not? just make the presentation view dependant on where you came from.
    2. The simple role-based approach does not fit for all sorts of applications.
    well this is a fairly generic comment, you can say that about *ANY* technology.
    3. Setting up realms for containers is not portable.
    Well this is kind of like saying configuring Weblogic isn't the same as Tomcat or JBoss or WebSphere... its going to be a little different, but its not really difficult on any of them. (and it is used the same way within the container.)
    4. Not being able to keep all classes related to authentication/authorization within your webapp can lead to classloader related problems
    how so? please explain.
    If you look at Acegi Security for Spring, they explicitly recommend not to use the included container integration stuff.
    Acegi security looks pretty slick, and yes its use seems to not want CMA (Container Managed Auth). But I'd imagine that this would have much less demand than much simpler CMA. (and CMA (Credentials) can easily be centralized via LDAP)

    Also that JSR 168 specification recommends CMA.
    "The portlet container is responsible for informing portlets of the roles users are in when accessing them. The portlet container does not deal with user authentication. It should leverage the authentication mechanisms provided by the underlying servlet container defined in the Servlet Specification 2.3, SRV.12.1 Section."

    I am not saying that CMA fits all situations, but it seems like everyone is so quick to abandon something that is fairly simple & works. (for most situations).

    seems like in the java world people always want to look for the expection to the rule and code to that...



    -jp
  42. Don't Bash CMA[ Go to top ]

    Not to mention that CMA propagates the security context to the EJB layer. And any features not implemented by CMA can be done by hand (with filters, for example).

    Dumping CMA isn't wise, for it solves all issues 99% of the time. The rest can be solved in a complementary way. I am always surprised when I see someone NOT using it, since it is always simple to use in every container - and you can always plug in your own authentication/authorization mechanism (I have done it already with JBoss, WLS and WAS).

    In WAS, for example, you get a "free" SSO (single sign-on) in a whole cell when you use it (a "cell" contins all servers in all clusters).

    I would ALWAYS use CMA, and I would look at 3rd-party solutions only for the extra stuff (non role-based authorization, for example).
  43. Seems like every application I work on ends up with needing very granular control over authorization. Usually this is not only with users, groups and roles, but also authorities to do different things to different objects based on their properties (i.e. if the actor is also an Investigator of the Case or if they're listed as the Legal Contact). Acegi provides a really nice solution for this sort of thing through either custom voters or by (my preference) adding the instance checks into the business service code.
  44. Seems like things that filters can do very easily.
  45. Don't Bash CMA[ Go to top ]

    Yeap, just remember that A in the acronym mostly stays for Authentication, and CMA is good and convenient enough for that. Authorization is a whole different matter: I agree that isUserInRole() method has limited applicability, I usually use custom SecurityOficer class that makes decision if user has a permission to do something upon object. And that decision can take into account pretty much anything.
    This way there is a clear separation: Authentication is handled by Container, and Authorization is handled by application.
  46. Dynamic user lists and CMA?[ Go to top ]

    What if you want the admin users of your application to be able to add
    new users with varying Roles through your application UI? I haven't seen
    any portable way of doing that; J2EE auth config files don't cut it.
  47. Dynamic user lists and CMA?[ Go to top ]

    That is fairly easy if you point the CMA at a RDBMS (pick any, and no MS Access doesn't count).
    I have done this with Tomcat, WebLogic + JBoss.
    haven't had the need to try others, but I am fairly certain it wouldn't be hard.

    what app server are you using?

    -j
  48. Dynamic user lists and CMA?[ Go to top ]

    If there is a PORTABLE way of doing it, I would be very interested in hearing about it. For example, JDBCRealm or DataSourceRealm would work in Tomcat, but nowhere else.

    And if you allow for runtime creation of new roles, how could that possibly work with a <security-constraint>?

    I use JBoss and WebSphere.
  49. Dynamic user lists and CMA?[ Go to top ]

    If there is a PORTABLE way of doing it, I would be very interested in hearing about it. For example, JDBCRealm or DataSourceRealm would work in Tomcat, but nowhere else.And if you allow for runtime creation of new roles, how could that possibly work with a <security-constraint>?I use JBoss and WebSphere.
    Every container has some way of accessing user/role data via JDBC - it might just be different configuration, but it's can be the same db. As for adding roles from your app, what would that achieve? Roles are designed to protect various bits of the app so if you're adding a new role you're adding new functionality, hence you're already modifying code and so you can change the security constraints in the config while you're at it. Theoretically there's nothing stopping you adding a role to a user (via direct access to the db) and then using a dynamic isUserInRole().
  50. Dynamic user lists and CMA?[ Go to top ]

    AOP? Check out the book on AspectJ for examples.
  51. Where is it?[ Go to top ]

    I've also been thinking about this. There is no standard J2EE API to define new roles/users. You can't really list the users in the system either. I wish that EJB 3.0 would address this shortcoming. isUserInRole() does not cut it.

    Regards,
    Mikael
  52. Where is it?[ Go to top ]

    Its not EJBs problem to solve.

    It would be within the J2ee spec somewhere else. (because I am fairly certain many people would want to use it without EJB)

    isUserInRole() is not the end all, and J2ee would benefit from adding to their CMA API... the question is how? what would we want that would remain generic enough to become a standard across containers.
    groups?

    -j
  53. Don't Bash CMA[ Go to top ]

    2. The simple role-based approach does not fit for all sorts of applications.
    well this is a fairly generic comment, you can say that about *ANY* technology.
    Ok, I should have written "does not fit for many sorts of applications". What's the benefit of standardization if so many things are left out? If your authorization requirements depend on two aspects (let's say your role and your location) you are left in the cold. And this is a only a very simple example.
    I really *do* think isUserInRole() is very limted.
    3. Setting up realms for containers is not portable.
    Well this is kind of like saying configuring Weblogic isn't the same as Tomcat or JBoss or WebSphere... its going to be a little different, but its not really difficult on any of them. (and it is used the same way within the container.)
    I was not only talking about configuration, I was also talking about *implementation*. What if the container-provided realm implementations do not fit your needs? You are going to implement your own and that is not portable.
    4. Not being able to keep all classes related to authentication/authorization within your webapp can lead to classloader related problems
    how so? please explain.
    Well I'll just cite the creator of Acegi:
    "We don't recommend using container adapters, as they require complex classloader configuration in your web container. They also require you to configure your web container's particular security realm. All-in-all, a non-portable solution that is likely to introduce classloader problems as your WAR needs additional JARs for business-specific functionality."

    Furthermore I didn't mean to bash CMA. I am just confused why so many people just jump on the standardization train while this particular standard has so many gaps that I hardly see the advantages in using it over non-standardized, framework-based solution like Acegi. Of course CMA may be suitable for many simple web apps, no doubt.

    Oh, and forget the first point, was just confusing several things... ;-)

    Jens
  54. Don't Bash CMA[ Go to top ]

    2. The simple role-based approach does not fit for all sorts of applications.
    well this is a fairly generic comment, you can say that about *ANY* technology.
    Ok, I should have written "does not fit for many sorts of applications". What's the benefit of standardization if so many things are left out? If your authorization requirements depend on two aspects (let's say your role and your location) you are left in the cold. And this is a only a very simple example.I really *do* think isUserInRole() is very limted.
    use a very simple filter for this.
    3. Setting up realms for containers is not portable.
    Well this is kind of like saying configuring Weblogic isn't the same as Tomcat or JBoss or WebSphere... its going to be a little different, but its not really difficult on any of them. (and it is used the same way within the container.)
    I was not only talking about configuration, I was also talking about *implementation*. What if the container-provided realm implementations do not fit your needs? You are going to implement your own and that is not portable. if you sit on top of what is there for J2ee, and use filters when you need to. I don't see why you say its "not portable" sure the setup will be a bit different but that is because each app server is different. (no different then having to deploy to two different app servers.
    I can see you have not tried it on the app servers, because if you had you probably wouldn't be saying this.
    4. Not being able to keep all classes related to authentication/authorization within your webapp can lead to classloader related problems
    how so? please explain.
    Well I'll just cite the creator of Acegi:"We don't recommend using container adapters, as they require complex classloader configuration in your web container. They also require you to configure your web container's particular security realm. All-in-all, a non-portable solution that is likely to introduce classloader problems as your WAR needs additional JARs for business-specific functionality.this is someone talking who seems to very one sided, without any real cases its hard to argue against. what complex classloader issues will arise? it'd be more beneficial to hear about them to see if they are valid. other than just to hear that they are "likely" when you don't use their solution. (don't mean to bash Acegi, just like a little more substance to a claim than has been given)
    "Furthermore I didn't mean to bash CMA. I am just confused why so many people just jump on the standardization train while this particular standard has so many gaps that I hardly see the advantages in using it over non-standardized, framework-based solution like Acegi. Of course CMA may be suitable for many simple web apps, no doubt. Oh, and forget the first point, was just confusing several things... ;-)Jens
    its not so much a "standardization train" as a problem that has been solved for the majority of cases, that seems to often be thrown out because someone doesn't want to learn filters or something simple like that.
    you can build Complex webapps with centralized security, that use simply CMA + filters (for location, etc).
    I'd rather also not become dependant on CAS. how mature is that really? how does it scale? is it proven? (I am truely asking because I don't know). seems to be very non standard, and wouldn't fit into most enterprises.

    standards are needed for a reason of "integration" sometimes you don't control the entire universe, only a small portion. this is one key reason why you couldn't use Acegi. Or does it talk to LDAP ?

    -j
  55. Struts Best Practices[ Go to top ]

    I am amazed to see how many peopole continue to consider that using action forms/Value objects is a good parctice. In real world applications this becomes (at least for me) a maintainance nightmare. Imagine all the classes you have to modify to add a new field for instance. You have to update the action form, the value object, the model and the ejb (if you use any). As for using custom class hierarchy to manage security and the like, I consider it to be a poor practice because it prevents you from using the other useful struts built-in actions. I think that the best practice is to use the J2EE security(and yes, it is possible to have a login box in each page). It is possible to use filters instead of class hierarchy to handle security but you will end up redoing the same job as J2EE securites with less feateures (and more bugs).
    Anyway, I think that the most useful Struts best practice is to use another MVC framework: Spring, WebWork, JSF, you have the choice !
  56. Struts Best Practices[ Go to top ]

    Anyway, I think that the most useful Struts best practice is to use another MVC framework: Spring, WebWork, JSF, you have the choice !
    Not sure I have agreed in the past with you. But on this one I am. Struts was great when it came out. But there better ways to create web apps today. Maybe for Web sites that have some minor app functionality it is fine.
  57. Struts Best Practices[ Go to top ]

    Anyway, I think that the most useful Struts best practice is to use another MVC framework: Spring, WebWork, JSF, you have the choice !
    Not sure I have agreed in the past with you. But on this one I am. Struts was great when it came out. But there better ways to create web apps today. Maybe for Web sites that have some minor app functionality it is fine.
    Not sure if it has got anything to do with minor or major app functionality. But I do agree that there are better frameworks out there in terms of architecture and letting developers write cleaner code. Spring and Webwork as mentioned. But I would remove JSF from the list and substitute it with Tapestry for the simple reason that a JSF component is a custom tag which means presentation code in java.
  58. Struts Best Practices[ Go to top ]

    There has been no limit on the talk of best practices with Struts. This latest article discusses working with dynamic fields, error categorization, validation, security, prepopulation, and many more best practices.
  59. Struts Best Practices[ Go to top ]

    Forgive me for quoting the main message again. I was hoping there's a good practice to handle multiple rows of form data . By that I mean, say adding 1 or more Employees(with name, gender, address and age) through 1 HTML page and implementing that in Struts. Typically people use Arrays of Arrays or similar data structures to capture this. Is there a good and efficient way to implement this.

    Also there's not mention about DynaBeans. I find that quite a use when you have forms that have a large number of input fields etc.

    -Anand
  60. Dynabeans the way to go..[ Go to top ]

    I was also surprised to not see coverage on dynabeans (DynaActionForm). I find these invaluable and a lot more elegant for most of my implementations..

    Good writeup though..

    -Chris
  61. Dynamic levels of dynabeans[ Go to top ]

    Also there's not mention about DynaBeans. I find that quite a use when you have forms that have a large number of input fields etc.-Anand
    This is true. How do you handle multiple layers of parent-child row data with dynabeans ? The usual way of handling this is not easy for so many levels. It is a good article for beginners.
        We should not forget that one of the hallmarks of a framework is extensibility and there are so many ways to extend Struts. Not just RequestProcessor,Action and ActionForm.
  62. Struts Best Practices[ Go to top ]

    It would be nice if we could utilize POJOs for Actions. I also tend to use DynaValidatorActionForms rather than explicitly writing FormBeans. What I am interested in is if anybody has any experience with Struts-chain. Has anybody used this framework, and have any (positive or negative) experience with it?
  63. Struts Best Practices[ Go to top ]

    I also find a pretty good practice also:
    1) DynamicForms: We use in a large project DynamicForms and helps us a lot not to adding getters and setters to forms all the time.
    2) BaseAction: A base action containing helper methods and extending DisptchAction.
    3) Drop Down lists: In order to populate options tags, we develop Providers (http://providers.sourceforge.net/) to place there all the lists. Also we use Providers to write descriptions from ids (similar to bean:write) and to generate dependant drop down lists. Providers helps us a lot with this problem.
    4) Wizard navigation-Backward navigation: If your application has wizards, Navigation is really an issue, or if you are linking different use cases you need a navigation support. We develop a navigation extension with stepBack and stepToCheckpoint. This helps us to return from velidation errors, and going back from one page without knowing where we came from. We use a stack scheme to do it.
    5) Layout and look & feel: We use tiles for page Layout and Xkins for page look&feel. Tiles helps a lot in setting yup tempaltes for our pages. Xkins (http://xkins.sourceforge.net/) allows us to render the page forms, fields, and every piece of our UI without placing HTML code in the JSPs, so reducing the look&feel maintenance and giving us skinning capabilities.

    Cheers.
    Guillermo Meyer
  64. Struts Best Practices[ Go to top ]

    you can use POJOs and never have to deal with forms again, just learn webwork and kick struts to the curb if you can, it will make you happy.
  65. Struts Best Practices[ Go to top ]

    you can use POJOs and never have to deal with forms again, just learn webwork and kick struts to the curb if you can, it will make you happy.
    Yup, WebWork is definitely a better option than Struts. Also lends itself to easier testing.
  66. Error categorization[ Go to top ]

    I'm not keen on using the property parameter of ActionErrors.add() to attach categories to messages.

    I use the validator, which as you probably know adds messages to ActionErrors using the name of the property that fails validation. You then typically put a <html:errors property="myField"/> tag next to each field in your JSP, so that the messages are displayed next to the failing fields. I personally use my own tag which puts a marker gif next to failing field (displaying the message on hover) when the server side or javascript validation fails.

    Using the property name string to categorise the messages, means that you no longer have this mechanism for displaying validation messages.

    It would be better to store your different categories of message in different ActionErrors objects which you place into the request using different keys. Then from your JSP use the <html:messages/errors name="key" property="myField"/> tag to get the category of messages you require.
  67. Error Categorization[ Go to top ]

    Well i think categorizing messsages is good where you think that the result of the action will be success or error e.g An action interating with DAO for DML operations in which we can add success msg under properties(category)like Success / Warning . As i am using a custom tag in which i specify the severity to tag which on rendering it dynamically displays a message in red/green outline with relative gifs.
  68. Error Categorization[ Go to top ]

    I have no problems with anyone want to create categories of message. It's just that the original "best practice" would break other things.

    Struts now has more that one type of message (messages and errors). They are functionally the same but are different classes. You could extend the message class as many times as you like, or even extend it once to include a category property which only your tag uses if present.
  69. Dispatching[ Go to top ]

    I am glad the article doesn't mention the use of DynaActionForm beans, I never liked them, never found a good use for them.

    But here's something that I thought the article may have mentioned: what are the best practices when you have a form containing multiple submission points? I've found the DispatchAction class to be useful in this situation, but it's sometimes problematic.

    1) You have to ensure that your form submission's HTTP request always contains the dispatch parameter, especially when your user wants to be able to submit forms by hitting enter in a text field or you need to be able to submit the form through mechanims other than an <html:submit/>.

    2) I find myself coding the values for the dispatch parameters in multiple locations in different ways:
    * struts-config.xml - for the action forwards, <forward name="myAction" path="/do/MyAction?dispatch=init"/>
    * ApplicationResources.properties - myaction.initialize=init
    * my DispatchActionClass - keyMethodMap.put("myaction.initialize", "doInit");
    * my JSPs - <html:submit property="dispatch"><bean:message key="myaction.initialize"/></html:submit>
    Adding new dispatch parameter values or changing existing ones can be toilsome.
  70. Dispatching[ Go to top ]

    I am glad the article doesn't mention the use of DynaActionForm beans, I never liked them, never found a good use for them. But here's something that I thought the article may have mentioned: what are the best practices when you have a form containing multiple submission points? I've found the DispatchAction class to be useful in this situation, but it's sometimes problematic. 1) You have to ensure that your form submission's HTTP request always contains the dispatch parameter, especially when your user wants to be able to submit forms by hitting enter in a text field or you need to be able to submit the form through mechanims other than an <html:submit/>.2) I find myself coding the values for the dispatch parameters in multiple locations in different ways: * struts-config.xml - for the action forwards, <forward name="myAction" path="/do/MyAction?dispatch=init"/> * ApplicationResources.properties - myaction.initialize=init * my DispatchActionClass - keyMethodMap.put("myaction.initialize", "doInit"); * my JSPs - <html:submit property="dispatch"><bean:message key="myaction.initialize"/></html:submit>Adding new dispatch parameter values or changing existing ones can be toilsome.
    I seriously doubt if u need to localize the dispatch action parameter. What do u gain by doing that.
  71. Localizing Dispatch Parameter[ Go to top ]

    I seriously doubt if u need to localize the dispatch action parameter. What do u gain by doing that.
    For clarity, I was talking LookupDispatchAction specifically in my above post.
    http://struts.apache.org/api/org/apache/struts/actions/LookupDispatchAction.htmlWhat do you mean by localizing the dispatch parameter?
  72. Localizing Dispatch Parameter[ Go to top ]

    I seriously doubt if u need to localize the dispatch action parameter. What do u gain by doing that.
    For clarity, I was talking LookupDispatchAction specifically in my above post. http://struts.apache.org/api/org/apache/struts/actions/LookupDispatchAction.htmlWhat do you mean by localizing the dispatch parameter?
    I mean why do u have to put the dispatch parameter in ur ApplicationResources.properties?
  73. Localizing Dispatch Parameter[ Go to top ]

    I mean why do u have to put the dispatch parameter in ur ApplicationResources.properties?
    That's what the API for LookupDispatchAction says to do. Your getKeyMethodMap() method is supposed to return a mapping of property names (which reasonably belong in ApplicationResources.properties) to Action class method names. LookupDispatchAction then grabs the value of the property, compares that with the value of your dispatch request parameter, and forwards to the appropriate method...or blows up.

    http://struts.apache.org/api/org/apache/struts/actions/LookupDispatchAction.html
  74. Localizing Dispatch Parameter[ Go to top ]

    Your getKeyMethodMap() method is supposed to return a mapping of property names (which reasonably belong in ApplicationResources.properties) to Action class method names.
    Maybe I am wrong, but shouldnt ApplicationResources.properties be used only for internationalization. Is it valid to use it for other purposes like LookupDispatchAction's parameters.

    I can think of a situation where one fine day, u need to convert ur website to German, the German guy picks up ApplicationResources.properties and creates a German version of it and in the process ends up translating the dispatch parameter to German. And Boom, the German site fails.

    So is this a design flaw in Struts. Curious to know what others think.
  75. Alternative to LookupDispatchAction[ Go to top ]

    Nice to see that someone finds LookupDispatchAction strange. For an alternative, look at http://issues.apache.org/bugzilla/show_bug.cgi?id=30292.

    JB
  76. When I habe more submit buttons, I never use the value of those for the dispatch. The value is displayed in the HTML page and has to be localized.

    I use following approach:

    The button's name has the form "submit(ACTION1)", "submit(ACTION2)", ...

    The FormBean contains a mapped property "setSubmit(String action, String dummy)" which only stores the last set key (the dummy value is ignored).

    The Action can then dispatch the request according to the value of the submit-property of the FormBean.
  77. Localizing Dispatch Parameter[ Go to top ]

    Well first, sorry for replying so late.

    >Is it valid to use it for other purposes like >LookupDispatchAction's parameters.I can think of a >situation where one fine day, u need to convert ur website >to German, the German guy picks up >ApplicationResources.properties and creates a German >version of it

    Well LookupDispatchAction is used when there are multiple buttons on a single form with the same name. For ex: Add Record, Delete Record, Edit Record might be there on a single form. By having the parameter name to have the value that's coming from the ApplicationResources.properties file is even better because as you said tomorrow the site might be transformed to Germany and those button values should should up in German. All that has to be done is to have another ApplicationResources properties to that particular locale.


    >and in the process ends up translating the dispatch >parameter to German. And Boom, the German site fails.So is >this a design flaw in Struts. Curious to know what others >think


    Nope. not at all. LookupDispatchAction gets the value alright (like "Add Record";) and it uses that value to reverse lookup the key for it. so, as long as the key doesn't change (for eg: button.add) nothing breaks even when you switch locales.
  78. Prepopulation - the three action edit[ Go to top ]

    I have a different solution to the drop-down list population problem. It comes from using the validator and using only request scope form beans.

    Let me start with a long ramble about the problem. Please bear with me, I've been thinking about this a long time.

    People often put their form beans into the session. Struts does this by default (did you realise?). When a form is submitted by the browser, struts will re-use the same form bean that was used to render the original JSP. So if the validator rejects the data in a form, the user is returned to the JSP showing the data with any drop-downs populated. Just as it was on their first visit. Great.

    However, using session scope form beans ultimately uses more resources than ones just stored in the request. It can also get confused by users who like to use "Right Click->Menu->Open In New Window/Tab", to view or edit different instances of the same form/entity where the drop down differ. So it makes sense to use request scope. With request scope a new form bean is created every time, and is only in existence while the request cycle ball is with the server.

    The problem with request scope is that when the browser submits the form, the new form bean is created and populated with only the field values submitted by the user. Any support data for drop down lists are not populated, as that is not submitted by the browser. When validation fails, struts forwards to the JSP configured in struts-config.xml as being the INPUT to the action. If the form bean holds the support data, then the drop down lists will appear empty.

    You could put the drop-down data into a separate session or application scope bean. That would work, but the drop-down list might contain options that are only relevant to the particular entity being edited, or even just the logged in user. It can get confusing to have many scattered beans in different scopes. So I like to add this stuff to the form bean because it makes it easy to find and the Struts tags look there for it by default.

    So I want to use request scope form beans. But wait there is more …

    If you use the validator, you have to use separate actions for requesting and submitting JSP pages (load and save actions). You need to have validation turned off for the load, and turned on for the save. You route both through the same Action class but they must be distinct actions in the strut-config.xml file.

    Want is more, you will probably want to use the same form bean class and JSP, for creating new entities, or editing viewing and printing existing entities. Each may have a different load and save action, but they will probably share the same form support data.

    Nearly there. Bear with me ...

    The solution is to handle the Request Page/Edit Page/Submit Page cycle using three actions.
    1. To load the form bean with the entity's values,
        and forward to the second action.
    2. To load the form bean with the form
        support data (drop down lists etc.) and
        forward to the JSP.
    3. To save form bean's data as an entity,
        or if validation fails to forward the form
        bean with the invalid entity data (but
        no support data) back to the second action.

    So the strut-config.xml entries my look like:

    <action name="myForm" path="/myFormEdit" scope="request"
      type="MyFormLoadAction" validate="false">
      <forward name="success" path="/myFormSupport.do"/>
    </action>

    <action name="myForm" path="/myFormSupport" scope="request"
      type="MyFormSupportAction" validate="false">
      <forward name="success" path="/MyFormEdit.jsp"/>
    </action>

    <action name="myForm" path="/myFormSave" scope="request"
      type="MyFormSaveAction" validate="true" input="/myFormSupport.do">
      <forward name="success" path="elsewhere" />
    </action>

    The validation failure forwarding happens when you set the "input" attribute of a validating action in struts-config.xml. Here you set it to forward to an other action, where as most examples nominate the JSP involved.

    You will find there is a lot of code that can be shared across the actions that deal with the forms for a particular entity. Keep it all in a class separate from the action classes to give the best code re-use.
  79. Solution could be simple: make input point to an action rather than .jsp where you can populate form bean from DB or cache as you like. You can even make and additional mapping to you let say CRUDAction like this
    input="/do/myCRUD/error"

    in the action
    ...
    String path = actionMapping.getPath();
    if( path.endsWith( "error" ){
      //init form based on data there
      return actionMapping.findForward( "crud" );
    }