Discussions

News: Struts 1.3: sample application showing Chain of Command

  1. Struts developers have completely rebuilt the RequestProcessor using the Chain-of-Command/Chain-of-Responsibility (CoR) pattern implemented in Apache Commons-Chain. This allows us to create cleaner, more efficient code. How? Developers now have much more flexibility in specifying what happens when an action URL is called (such as /do/testAct or testAct.do).

    You can download an entire sample application that uses Struts 1.3 dev and CoR on JRE 1.5, Tomcat 5.5.7 on Eclipse 3.1M4 (all included in download) at http://sourceforge.net/projects/infonoia/

    Read more about Struts 1.3 features at: Better Code With Struts 1.3

    Threaded Messages (28)

  2. I was wondering why there needs to be a return value for execute()? If it normally should return false all the time then why not just remove it and rely on exceptions to kill the chain?
  3. I was wondering why there needs to be a return value for execute()? If it normally should return false all the time then why not just remove it and rely on exceptions to kill the chain?

    CoR/Commons Chain can be used in many situations, Struts is just one of them (but a good one). In Struts, you usually want the chain to go to the end, to return some response to the browser; this is not necessarily the case for non-request/response uses.

    Wolfgang Gehner
  4. I was wondering why there needs to be a return value for execute()? If it normally should return false all the time then why not just remove it and rely on exceptions to kill the chain?

    Here's a use case which isn't in the Struts code yet, but will be soon. Struts uses two main sub-chains for its operations: "process-action" and "process-view". In the original struts-chain implementation, a number of commands test to see if the submitted request was valid before executing. It makes more sense to have a command which aborts processing of the sub-chain when it determines that the form is invalid, instead of having other commands need to repeat that check (or even know about that possible state!)

    I think we'll implement a simple "AbortIfInvalidForm" command, so that it's independent of any other command, and so that people can control where the "cutoff" is. As it is now, there's one additional command which needs to execute after the one which actually determines the form's validity (SelectInput, which deals with routing back to the original form page.)

    It might be nice to implement a generic "AbortIf" command in commons-chain which could take an expression and evaluate it against the context. This would be the second case I've thought of for an expression language in commons-chain, so I may start lobbying for a commons-chain dependency on JEXL (I'd rather not re-invent the wheel.)

    Another option would be to end the "process-action" chain after form validation, and then have two optional sub-chains between "process-action" and "process-view": "process-invalid-form" and "process-valid-form" (or nicer names). That might be tidier.
  5. It might be nice to implement a generic "AbortIf" command in commons-chain which could take an expression and evaluate it against the context.
    I was building a chain last night and might first guess at the "optional" attribute on the LookupCommand was that it controlled how the "return" was processed. Of course, it doesn't, optional indicates if Chain allows references to undefined chains. It might be nice to have a boolean setting for subchains; let's call it "forceAbort". If forceAbort = true then returning true from a subchain would abort the parent chain; with forceAbort = false then returning true from a subchain command aborts the subchain but does not about the parent chain.
  6. I was wondering why there needs to be a return value for execute()? If it normally should return false all the time then why not just remove it and rely on exceptions to kill the chain?

    Some times you want to stop the chain, but no exception has occured.

    The GOF book describes the pattern in this way.
  7. Thanks, the article is very helpful. The example uses the following syntax:

    <command name="testCmd1" className="com.mD.test.NewCmd"/>

    Is there any facility for supplying your own instance of NewCmd here? Or do you have to play the same old You supply the default constructor and only Struts can instantiate the object game?
  8. Thanks, the article is very helpful. The example uses the following syntax:<command name="testCmd1" className="com.mD.test.NewCmd"/>Is there any facility for supplying your own instance of NewCmd here? Or do you have to play the same old You supply the default constructor and only Struts can instantiate the object game?

    Has struts/jakarta commons not learned from Springs ICO container.
  9. Has struts/jakarta commons not learned from Springs ICO container.

    I belive Struts CoR has at least parity w/ Spring or WebWork.
    Compare the code, effort and readability to do equivalent functionality.

    .V
  10. Has struts/jakarta commons not learned from Springs ICO container.
    I belive Struts CoR has at least parity w/ Spring or WebWork.Compare the code, effort and readability to do equivalent functionality..V

    Well, Struts CoR might catch up with the interceptor facilities in Spring Web MVC and WebWork2 now, maybe even going beyond them in some respects. A good step forward for Struts!

    However, that's not at all comparable to Spring's IoC container, which the original question was about. A command chain facility in an MVC framework is completely orthogonal to the generic component management facilities of an IoC container.

    If you think that you can replace the use of IoC with Struts CoR, then you probably haven't had a need for IoC in your application in the first place.

    Juergen
  11. ... haven't had a need for ...

    And of course, taht is a good thing.
    The less the better.

    .V
    sandraSF.com/KISS
  12. Is there any facility for supplying your own instance of NewCmd here? Or do you have to play the same old You supply the default constructor and only Struts can instantiate the object game?

    In what cases would you need to create a new command instance? The model of commons-chain assumes that you get any state-specific information in the Context.

    In theory, you could write some commands which instantiated other commands on your terms, but it might help me if I understood why you needed to.

    By the way, Struts isn't instantiating the objects; commons-chain is.
  13. In theory, you could write some commands which instantiated other commands on your terms, but it might help me if I understood why you needed to.

    The first use-case that comes to mind is that I want my third-party framework to perform Dependency Injection on NewCmd, and then hand it off to Struts to be used in the declared chain.
    By the way, Struts isn't instantiating the objects; commons-chain is.

    As Tommy Lee Jones's character says in The Fugitive, "I don't care!" :)
  14. use-case that comes to mind is that I want my third-party framework to perform Dependency Injection on NewCmd, and then hand it off to Struts to be used in the declared chain

    Chains and commands are fully configrable in many diferent ways, nothing to stop standard IoC from configure it if you want to use both, or in XML ( since Chains leverages Digester).
     
    If you use Struts 1.3 + ... and the need comes up, you'll take the time to figure out how to configure or inject into chains.

    What happend to me is... that I used both IoC and CoR... and then noticed that CoR give me all I need, plus it came w/ Struts and I can use it w/ WebStart. Your millage may vary.


    .V
  15. In theory, you could write some commands which instantiated other commands on your terms, but it might help me if I understood why you needed to.
    The first use-case that comes to mind is that I want my third-party framework to perform Dependency Injection on NewCmd, and then hand it off to Struts to be used in the declared chain.
    Well, commands receive a context which can carry any dependencies they need. (In fact, there's a current TSS thread on "context IOC" which is along the same lines.)

    Based on some of the discussions here and on the struts-dev list, we've adjusted things so that you can easily provide an alternate implementation of the ActionContext class by extending the ComposableRequestProcessor. This provides a way to make sure that your dependency can be found in the context.
  16. Thanks, the article is very helpful. The example uses the following syntax:<command name="testCmd1" className="com.mD.test.NewCmd"/>Is there any facility for supplying your own instance of NewCmd here? Or do you have to play the same old You supply the default constructor and only Struts can instantiate the object game?
    If you want, you can use the Chain API as in the following:

    public class SellVehicleChain extends ChainBase {
    public SellVehicleChain() {
    super();
    addCommand(new GetCustomerInfo());
    addCommand(new TestDriveVehicle());
    addCommand(new NegotiateSale());
    addCommand(new ArrangeFinancing());
    addCommand(new CloseSale());
    }
    public static void main(String[] args) throws Exception {
    Command process = new SellVehicleChain();
    Context ctx = new ContextBase();
    process.execute(ctx);
    }
    }
  17. Beating a dead horse[nt][ Go to top ]

    see title
  18. Workflow?[ Go to top ]

    Ok. So what I see here is a linear set of commands where each command also is an "if" node; the false value leads to the end of the, ah, chain. Basically a very simple workflow.

    I'm willing to bet that not before long people are going to introduce flags in the context, set by previous commands, so certain future commands are skipped.

    Need I go on?

    IMHO workflow.
    So when building a workflow, build a workflow.
  19. Where to get Struts 1.3[ Go to top ]

    Hi,

    I doesn't find Struts 1.3 at http://struts.apache.org/ :-(
  20. Where to get Struts 1.3[ Go to top ]

    Hi,I doesn't find Struts 1.3 at http://struts.apache.org/ :-(

    check http://jakarta.apache.org/commons/chain/
  21. Where to get Struts 1.3[ Go to top ]

    Version 1.3 of Struts has not been released yet at this date.

    The code is based on source bulid of development version.

    .V
  22. The gray area in Struts is its ActionForm. Personally, would like to see more changes in usage of ActionForm. Some points which come to my mind are listed below.

    1) Conversion to and from FormBean to ValueObjects (though it can be achieved with one line statement using BeanUtils,but a automatic conversion would be desired)

    2) Passing a subset of ActionForm through the Action chain(using seperate set of ActionForm for a single HTML Form)

    3) Using ActionForm not only as a carrier of data from HTML forms to the Action but also to display data after executing the Action

    4) Changing the execute() method signature to pass only the ActionForm and ActionMapping, and no
       HttpServletRequest and HttpServletResponse objects. Struts should be protocol agnostic.

    5) Replacing static ActionForm with DynaActionForm for all cases. ActionForm should be dynamic enough to include parameters that are created dynamically using javascript.

    6) Though not part of core Struts, having a sophisticated Struts tag library,like displaying tabular data with run time selection of style sheets,would definitely be handy.

    Regards
    Surajeet
  23. 1) Conversion to and from FormBean to ValueObjects (though it can be achieved with one line statement using BeanUtils,but a automatic conversion would be desired)

    -- It's already there, using bean utils.

    4) Changing the execute() method signature to pass only the ActionForm and ActionMapping, and no
       HttpServletRequest and HttpServletResponse objects. Struts should be protocol agnostic.

    -- if u want this, then use webwork

    6) Though not part of core Struts, having a sophisticated Struts tag library,like displaying tabular data with run time selection of style sheets,would definitely be handy.

    -- this will definitely be great, better still create a subproject for this.
  24. The gray area in Struts is its ActionForm. Personally, would
    like to see more changes in usage of ActionForm. Some points which come
    to my mind are listed below.1) Conversion to and from FormBean to
    ValueObjects (though it can be achieved with one line statement using
    BeanUtils,but a automatic conversion would be desired)

    Check out FormDef I haven't
    used it yet, but it sounds like it addresses some of your concerns.
    2) Passing a subset of ActionForm through the Action
    chain(using seperate set of ActionForm for a single HTML
    Form)

    I don't understand; is the idea to componentize forms so that you could
    reuse logic for processing repeated parts of a form? Why do you need to
    subset ActionForm? Couldn't you just have processing code which only
    paid attention to certain parts? It wouldn't be hard to write a command
    which wrapped the ActionContext's ActionForm with an adapter which only
    exposed certain methods or otherwise made it look as you wanted; this
    together with using the chain-dispatch for an ActionMapping should get
    you where I think you're headed...
    3) Using ActionForm not only as a carrier of data from HTML
    forms to the Action but also to display data after executing the Action

    This has been one of my pet peeves about Struts for a long time. I have
    some ideas about this, and they may well make it into Struts 1.3, but
    the first concern is completing the move to the CoR request processor
    and maintaining backwards compatibility.
    4) Changing the execute() method signature to pass only the
    ActionForm and ActionMapping, and no&nbsp;&nbsp;&nbsp;HttpServletRequest
    and HttpServletResponse objects. Struts should be protocol agnostic.
    More likely will be to pass in the ActionContext, which
    encapsulates the mapping and in practice, carries the request and
    response, but which are not exposed by the ActionContext interface.
    Struts should be protocol agnostic , but there are real use cases for
    directly handling the response, especially when returning binary data.
    See this struts-dev thread for what has become a pretty active
    discussion on the topic.
    5) Replacing static ActionForm with DynaActionForm for all
    cases. ActionForm should be dynamic enough to include parameters that
    are created dynamically using javascript.

    I don't see why
    this should be imposed on people. DynaActionForm is available, and
    probably preferred by most people, but no need to invalidate existing apps which don't use it.
    6) Though not part of core Struts, having a sophisticated
    Struts tag library,like displaying tabular data with run time selection
    of style sheets,would definitely be handy.


    Now that Struts
    has completely established its "TLP" status at Apache, migrated to
    Subversion, and started cleaning up the source repository, we have
    welcomed a few subprojects and are open to more. However, I'm not sure
    that there would be a lot of enthusiasm for something which doesn't tie
    to Struts in some way; there are lots of other places for open projects
    which don't directly depend on Struts. Have you seen the Display taglibrary? It
    sounds close to what you describe, and they're probably open to feature
    requests where you see opportunities.
  25. Hi Joe,

    Thanks for both the links (FormDef and Display Tags).I never knew about them,and they seem to be exactly what i needed.i havent gone through them yet,will do so soon.thanks.

    Regarding the usage of a subset of ActionForm ,i will give a scenario.

    <QUOTE>

      I have a HTML form which displays a tabular list of data,and has few configurable properties,like, sort order of columns,display order of columns,hiding of columns. The tabular list of data is specific to a business service and handled by that business service .On the other hand the configurable properties are handled by a seperate application service,whose main responsibility is to store application wide configurable properties specific to a user/role.
    Now, when the HTML form is submitted , i want to seperate the single HTML form into 2 seperate ActionForm,one ActionForm deals only with the business specific data which is passed to a business specific Action,and another ActionForm which has the configurable parameters and is passed to a seperate Action.Basically, i want the seperation of my 2 concerns - handling business specific data , and handling application specific configurable data.
    What do you say?
    </QUOTE>
    Hope, i was clear in stating the scenario.

    Regards
    Surajeet
  26. Basically, i want the seperation of my 2 concerns - handling business specific data , and handling application specific configurable data.What do you say?
    I say it's making my head hurt thinking about it! Without seeing it, it sounds like an interface only suited to extreme power-users. You'll probably need to spend some quality time looking through the Struts source to get a handle on how to tackle this scenario.

    Normally, we suggest that people do not chain actions, but it's possible that you could achieve your goals by having one action do its work and then return an ActionForward whose path was the app-relative URL of the second action. Struts was never designed for use this way, and it's possible something odd could happen, but it's also true that tons of developers have successfully built apps which use this action-chaining strategy (albeit probably to achieve simpler goals!)
  27. Structural POO???????[ Go to top ]

    this is my point of view about the future of j2ee aplication...jejejeje And struts 1.3 confirm my hipotesys.
  28. we suggest that people do not chain actions, but it's possible that you could achieve your goals by having one action do its work and then return an ActionForward whose path was the app-relative URL of the second action. Struts was never designed for use this way,
    I was wondering how do you sugesst to use struts in following scenario. It would really help to look it your way. A page having a search criteria. for instance say just one field * country (select box) and on selection of country and clicking submit on the same page cities are displayed in tablular format. only constraint is - wihout using the http session object ---- the way i have seen it done is - * action 1 - display the search criteria page - this action is required since the constuction of critera page takes input from many sources. for eg above, say country list box is constructed using a complex logic invoked by action 1. * action 2 - performs the search and displays result - now heres the concern; since the result is on same page this action needs to perform the task of action 1 in addtion to performing its own task of search.and thats because the result of action 1 was lost after action 1 was done. ---- possible soln to be chosen from were: * server component to fill in the place of session object. but its not appealin. * at the end of action 2 add the result of action 2 to reponse and chain to action 1 and finally display result of action 1 action 2 on screen and the second option was chosen. --- now second option you say is not the way stuts was intended to be used right ?
  29. this action needs to perform the task of action 1 in addtion to performing its own task
    The idea is that actions should not be "performing" tasks, but simply calling methods from a facade. At the very least, Action 2 could extend Action 1, and each could be calling the same helper methods, so that "performing the task" is a single line of code. -Ted.