SoftSlate Commerce
Home » Get Support » Documentation » HTML Documentation

Anatomy of a Request: Adding an Item to the Cart

There's nothing better than a detailed example to provide some insight into the concepts presented above. In the following example, we'll go step-by-step through a typical request sent to the SoftSlate Commerce application, touching on each of the configuration files, Java classes, and JSP templates used to process it. The example we'll use is a request from a user to add an item to the cart.

  1. The user submits the "Add to Cart" form from a product detail page. As you can see, the form contains an input box for the quantity, as well as any number of form elements describing customer-selected "attributes" for the product (in this case, "Frame" and "Size" are the two attributes assigned to this product).

  2. The Web Controller or Struts layer identifies the action mapping corresponding to the URL of the request. In this case, the URL is / . The Struts ActionServlet looks up the corresponding action mapping and finds it in the WEB-INF/conf/order/struts-config-order.xml configuration file:

    	<forward name="failure" path="/"/>
    	<forward name="success" path="cart.full"/>

  3. The Web Controller or Struts layer identifies and invokes the Struts action form corresponding to the request. The above action mapping refers to the "cartAddForm" form bean, which is defined at the top of the same configuration file, WEB-INF/conf/order/struts-config-order.xml :


    Because the action mapping's validate attribute is set to true, Struts knows that the request must be validated. In Struts, this means that the validate method of the action form com.softslate.commerce.customer.order.CartAddForm must be invoked.

  4. The validate method of com.softslate.commerce.customer.order.CartAddForm validates the request's parameters. In this case, CartAddForm makes sure a postitive integer is present for the quantity to be added, and that if any of the product's attributes are required, they are present in the request.


    More details about the add to cart validation is available in the API Documentation for CartAddForm .

    If the result of the validation is one or more errors, the request gets forwarded to the value of the action mapping's input attribute. If there are no errors, Struts proceeds to invoke the execute method of the action class com.softslate.commerce.customer.order.CartAddAction . We'll assume a successful result without errors.

  5. The execute method of com.softslate.commerce.customer.order.CartAddAction is invoked to process the request. In this case, CartAddAction starts by creating an instance of com.softslate.commerce.businessobjects.order.CartProcessor , invoking its processAddItems method:

    // Process the items
    CartProcessor cartProcessor = (CartProcessor) baseForm
    Map results = cartProcessor.processAddItems(PropertyUtils

    At this point, control of the request is passed from the Web Controller or Struts layer, to the Business layer.


    Whenever an object in the Business layer is created, the com.softslate.commerce.businessobjects.core.BusinessObjectFactory class is used. This class looks at the values in the WEB-INF/classes/ file to determine which concrete class to instantiate. In this case by default it instantiates com.softslate.commerce.businessobjects.order.BasicCartProcessor , which is the application's default implementation of com.softslate.commerce.businessobjects.order.CartProcessor .

  6. Now in the Business layer, the processAddItems method of com.softslate.commerce.businessobjects.order.BasicCartProcessor is invoked. This method handles the business logic involved with the request to add an item to the cart. Namely, it instantiates the user's cart if it doesn't already exist. A user's cart is represented as an instance of com.softslate.commerce.businessobjects.order.Order . It then parses the incoming parameters and creates an instance of com.softslate.commerce.businessobjects.order.OrderItem to represent the order item.

    After performing some validations against the database, processing inventory, and processing discounts, it finally hands things off to the Data Access layer to record the results of the request in the database:

    OrderGatewayDAO orderGatewayDAO = (OrderGatewayDAO) getDaoFactory()
    		.processOrderItems(getUser(), newOrderItems, results);


    Whenever an object in the Data Access layer is created, the com.softslate.commerce.daos.core.DAOFactory class is used. This class looks at the values in the WEB-INF/classes/ file to determine which concrete class to instantiate. In this case by default it instantiates com.softslate.commerce.doas.order.OrderGatewayDAOHibernate , which is the application's default implementation of com.softslate.commerce.doas.order.OrderGatewayDAO .

  7. Now in the Data Access layer, the processOrderItems method of com.softslate.commerce.doas.order.OrderGatewayDAOHibernate is invoked. This method synchronizes the state of the user's cart with the database. Namely, it will insert or update records into the sscOrder and related tables, storing the new order item in the sscOrderItem table.

    The DAO will use Hibernate mappings to synchronize the application's objects with the database. In this case, the Hibernate mapping file WEB-INF/classes/com/softslate/commerce/businessobjects/order/Order.hbm.xml and other mappings files next to it are used to synchronize the application's objects with the database tables.

    Some DAOs will use HQL (Hibernate Query Language) mappings to communicate with the database. In cases where data is being retrieved from the database, the DAO will employ the HQL queries in the queries.hbm.xml files in the WEB-INF/classes/resources subdirectories to query the database through Hibernate.

  8. Assuming a successful result, control passes back to com.softslate.commerce.customer.order.CartAddAction . Assuming everything goes well, control will pass back to the Web Controller or Struts layer. In this case, CartAddAction will perform some additional processing of the request. In particular, depending on the application's inventory settings, the results of the processing by the Business layer might indicate that one or more messages be displayed to the user concerning inventory levels, or that one or more "low stock emails" be sent to the store's administrator.

    When it is finished processing these possibilities, the execute method of CartAddAction forwards the request to a Struts action forward:

    return mapping.findForward(forward);

  9. The Web Controller or Struts layer looks up the action forward returned by the action class. The Struts action forwards are defined back in the Struts action mapping for the request. In this case the following two action forwards can be returned:

    <forward name="failure" path="/"/>
    <forward name="success" path="cart.full"/>

    If it's a failure, control of the request is passed to the "/" URL. In other words, the user is sent back to the product page where any errors that occured are displayed.

    If on the other hand everything went well and the processing succeeded, control is passed to "cart.full", which is not a URL but rather a Tiles definition. Forwards that use this sort of dot notation identify Tiles definitions.

    It's at this point that control passes to the Presentation layer.

  10. The Presentation layer looks up the Tiles definition corresponding to the action forward. In this case, it finds the "cart.full" Tiles definition in the WEB-INF/conf/order/tiles-defs-order.xml configuration file:

    <definition name="cart.full" extends="core.baseLeftLayout">
    	<put name="pageTitleKey" value="page.cart"/>
    	<put name="subMenu" value="product.breadcrumbs" />
    	<put name="body" value="cart.fullLayout" />

    Tiles definitions can both extend other definitions, and include other definitions under them. As you can see, "cart.full" extends the "core.baseLeftLayout" definition, which is defined in the WEB-INF/conf/core/tiles-defs.xml file:

    <definition name="core.baseLeftLayout" 
    	<put name="beforeHTML" 
    		value="/WEB-INF/layouts/default/core/empty.jsp" />
    	<put name="htmlHead" 
    		value="/WEB-INF/layouts/default/core/htmlHead.jsp" />
    	<put name="tracking" 
    		value="/WEB-INF/layouts/default/core/tracking.jsp" />
    	<put name="header" 
    		value="/WEB-INF/layouts/default/core/header.jsp" />
    	<put name="error" 
    		value="/WEB-INF/layouts/default/core/error.jsp" />
    	<put name="message" 
    		value="/WEB-INF/layouts/default/core/message.jsp" />
    	<put name="leftSide" 
    		value="core.leftSide" />
    	<put name="rightSide" 
    		value="core.rightSide" />
    	<put name="subMenu" 
    		value="/WEB-INF/layouts/default/core/empty.jsp" />
    	<put name="body" 
    		value="/WEB-INF/layouts/default/core/empty.jsp" />
    	<put name="footer" 
    		value="/WEB-INF/layouts/default/core/footer.jsp" />
    	<put name="afterHTML" 
    		value="/WEB-INF/layouts/default/core/empty.jsp" />

    Here you can start to understand how Tiles organizes the JSP templates used to display the results of every request. The "cart.full" definition extends "core.baseLeftLayout", which identifies many of the JSP templates used to display the application's HTML. Note that "core.baseLeftLayout" indicates that a JSP file named empty.jsp should be use for the "body" of the page. Fortunately, "cart.full" overrides this attribute - otherwise, only an empty space would be displayed in the page's body.

    "cart.full" identifies another Tiles definition should be used for the body of the page: "cart.fullLayout". This definition appears just below "cart.full" in the same WEB-INF/conf/order/tiles-defs-order.xml file:

    <definition name="cart.fullLayout" 
    	<put name="couponFormGuts" 
    		value="/WEB-INF/layouts/default/order/couponFormGuts.jsp" />

    With this definition we've now seen nearly all of the JSP templates used to generate the response. In particular, we can guess that cart.jsp is going to provide the guts of the screen for us.

  11. The Presentation layer forwards the request to JSP template correponding to the path attribute of the Tiles definition. In this case, because "cart.full" extends "core.baseLeftLayout", the request is forwarded to /WEB-INF/layouts/default/core/leftLayout.jsp .

  12. The JSP templates are processed, including processing of the Tiles tags.

    A peek at leftLayout.jsp will give you a good idea of how the various attributes of each Tiles definition are used. For example, this line is the point at which the value of the "body" attribute (in our case, cart.jsp) is included:

    <tiles:insert attribute="body"/>

    All of leftLayout.jsp is processed in this way, including each of the JSP templates referred to by their Tiles attributes. The result is an HTML page displaying the contents of the user's cart, including the new item that has just been added to it.


    SoftSlate Commerce extends the Tiles framework to first look inside the custom directory each time a given template is called for, before using the template found in the default directory. This is how a definition that calls for /WEB-INF/layouts/default/core/welcome.jsp will include /WEB-INF/layouts/custom/core/welcome.jsp instead, if it exists.

Copyright © 2008 SoftSlate, LLC. All Rights Reserved.

Powered by SoftSlate Commerce

Foraker Design