You asked this same question last week... I'll try and give you some specific answers this time...

(1) You have a class member (shoppingCartManager) in your Action. This is bad. Here's a direct quote from the Struts User's Guide:

"The controller servlet creates only one instance of your Action class, and uses it for all requests. Thus, you need to code your Action class so that it operates correctly in a multi-threaded environment, just as you must code a servlet's service method safely. The most important principle that aids in thread-safe coding is to use only local variables, not instance variables, in your Action class. Local variables are created on a stack that is assigned (by your JVM) to each thread request, so there is no need to worry about sharing them."

In other words, multiple requests can and usually will see the same class members or an Action, which is almost certainly why you were seeing that behavior.

You have some options here. The one I would personally go for is to create a ShoppingCart class that has the typical addItem, removeItem, listItems methods. Put this in session for a given user (probably the first request they make should check to see if such an object exists in session yet, and if not, put one in there). From then on you can get the object from session, do what you need to with it, put it back (if changes were made) and go from there. This class should be ignorant of the fact that it's running as part of a webapp... To really do it properly you probably also want to create a ShoppingCartItem class that represents a single item, and add instances of that class to the cart. But, for simplcity's sake you can not bother with that.

As an alternative, you might also consider making the shopping cart a Struts ActionForm, which you can put in session declaratively in struts-config.xml. This will relieve you of some coding dealing with session, but for reasons I'll get to in a moment, I'd say not to do this...

(2) I'm not really sure what you were trying to do with the ActionMapping class... It looks like you were trying to return it to your view (a JSP) to display. If that's the case, what you want to do is one of two things, assuming you do what I said in #1 above... (a) get the ShoppingCart instance from session, call listItems() (probably returns an ArrayList or some other collection), shove it in request as an attribute and forward to your JSP, then just display it as usual, or (b) populate an ActionForm instance, which you get as an argument to execute(), with the results of the call to listItems(). (b) is probably the more "correct" way of doing it, but either will work fine. In general, an ActionForm can be thought of as a data passing mechanism between the view and control layer. In this sense, it's really not proper in my opinion to store shopping cart-like data in it, even if it does make things a little simpler. So, while you COULD have Struts always put the ActionForm in session, and design it in such a way that it is really a storage location for your shopping cart data, I would advise against that because it's not really proper I think.

I think those two points will put you on the right track if you understand what I'm saying. Write back if you have specific questions, I'll try and answer them.

--
Frank W. Zammetti
Founder and Chief Software Architect
Omnytex Technologies
http://www.omnytex.com

Simon MARTIN wrote:
Hi,

I'm currently writing a short Struts application without a database (I know
that this would be better, but as it is only for teaching purposes, I don't
want to 'overflow' my audience with databases and ORM).
It should be a small online sales system -- I've got ShoppingItems,
ShoppingUsers (which are not yet used) and ShoppingCarts.

I want a ShoppingCart which stores the ordered items per user. I had
something like this:

public class ShoppingCartAction extends DispatchAction {
  private ShoppingCartManager shoppingCartManager;
  ...

  public ActionForward order(...)
  ...

  public ActionForward list(...)
  ...
}

and thought that it would work. Unfortunately, each user (which is not
authenticated or anything yet) gets the same shopping cart when he calls
shoppingCart.do?method=list.

So I did some research and found this:
http://www.jguru.com/faq/view.jsp?EID=1057609

So I created an ShoppingCartMapping class

public class ShoppingCartMapping extends ActionMapping {
private ShoppingCartManager shoppingCartManager;
...
}
and call it like this


public ActionForward list(ActionMapping mapping, ActionForm form,
  HttpServletRequest request,
  HttpServletResponse response)
  throws Exception {
    request.setAttribute("orderedItems",
      ((ShoppingCartMapping)mapping).getShoppingCartManager().getItems());
    return mapping.findForward("list");
}

which gives me a ClassCastException.

Do I have to set my custom ActionMapping in web.xml or struts-config.xml?
Am I on the right way, or is there a better way of doing this?

Thanks in advande and kind regards,
  Simon

PS: Please cc me in your answers.






---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to