-
1. Re: Back button and shopping cart contents
lvdberg Apr 4, 2011 8:00 AM (in response to coenos)Hi,
have you tried solving this with an action on page entry (defined in pages.xml) ?
Leo
-
2. Re: Back button and shopping cart contents
matkapx Apr 4, 2011 8:15 AM (in response to coenos)It looks like you have problem with Bijection,
Is your beans Conversation Scoped ? Well you said , SFSB which i understand is , State Full Session Bean, you can use you seam debug page, to see what object are stored in your conversation context. -
3. Re: Back button and shopping cart contents
coenos Apr 4, 2011 8:50 AM (in response to coenos)Hi,
I do have products.pages.xml files.
<?xml version="1.0" encoding="UTF-8"?> <page xmlns="http://jboss.com/products/seam/pages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.1.xsd" view-id="/custom/products.xhtml" no-conversation-view-id="/login.xhtml" > <!-- <header name="Cache-Control" value="no-cache, no-store, max-age=0, must-revalidate" /> --> <begin-conversation join="true" flush-mode="MANUAL" /> <navigation from-action="#{prodSelCon.addProduct(prod)}"> <rule if-outcome="success"> <!-- <end-conversation/> --> <redirect view-id="/custom/products.xhtml" /> </rule> <redirect /> </navigation> </page>
I removed the end-conversation during tweaking.
Here is my productSelection controller.
@Name("prodSelCon") @Scope(ScopeType.SESSION) public class ProductSelectionController { @In @Out ShoppingCart shoppingCart; Set<Product> products = new HashSet<Product>(); @Logger private Log log; public String addProduct(Product product) { shoppingCart.addProduct(product); products.add(product); log.info("-------------------- adding new product " + product.getName() + " -------------------- "+products.size()); return "success"; } public ShoppingCart getShoppingCart() { log.info("-------------------- GETTING CARD -------------------- "); return shoppingCart; } }
Here is my SFSB cart
@Stateful @Name("shoppingCart") @Scope(ScopeType.SESSION) @AutoCreate public class ShoppingCartImpl implements ShoppingCart { @Logger private Log log; private List<Product> products = new ArrayList<Product>(); private Consumer consumer; @PostConstruct public void initialize() { log.info("------------------------- SHOPPINGCART CREATED ----------------------------"); //products = new ArrayList<Product>(); } @Override public String addProduct(Product product) { products.add(product); log.info("------------------------- ADDED PRODUCT TO CART ----------------------------" + products.size()); return "success"; } @Override public void removeProduct(Product product) { products.remove(product); } @Override public void setConsumer(Consumer consumer) { this.consumer = consumer; } @Override public Consumer getConsumer() { return this.consumer; } @Remove @Override public void remove() { } @Destroy @Override public void destroy() { //products = null; //consumer = null; } @Override public List<Product> getProducts() { return products; } @Override public int getTotalProducts(){ return products.size(); } }
Hope this sheds some light. Thanks for your help,
Coen -
4. Re: Back button and shopping cart contents
coenos Apr 4, 2011 8:54 AM (in response to coenos)I also added this entry to the main pages.xml.
<page view-id="/custom/products.xhtml" conversation-required="true"> <navigation from-action="#{prodSelCon.addProduct(prod)}"> <rule if-outcome="success"> <!-- <end-conversation/> --> <redirect view-id="/custom/products.xhtml" /> </rule> <redirect /> </navigation> </page>
-
5. Re: Back button and shopping cart contents
lvdberg Apr 4, 2011 9:22 AM (in response to coenos)Hi,
some simple guessing, because we don't have the page..
It seems to work, because your beans are in the sessions scope, which lasts until the user log-out/disconnects.
In your ProductSelectionController you have a getShoppingCard-method, so it seems that you've incluuded an additional layer on top of the SFSB; Nice when you use Spring or Struts or whatever other action layers, but not necessary when you have Seam. Add all the needed functionallity in your SFSB.
Additionally it means that the
autocreate
is not necessary anymore, because you call the SFSB directly in your view (which autocreates your beans).make it a simple conversation, so change the SFSB to that scope (or just remove the annotation, because it's default).
Add a init-method on the SFSB, which is called when you start with your page. Add the action element to your page, and the init-method will called when you first open the page.
Consider changing everything to simple POJO (unless you have specific requirements), because the Seam handling of a POJO saves you an additional Interface.
Leo
-
6. Re: Back button and shopping cart contents
coenos Apr 4, 2011 9:33 AM (in response to coenos)Hi Leo,
thanks for your reply. Yes indeed a lot is not according to standard, but you are saying
it seems to work
?I mean, when I add two products to the cart, and then press the back button, the selectedproducts show no entry because the app is back to the previous page without reloading/refreshing. So it never reloads the shopping cart entries to the page. I see that in the log.
Here is the page
<ui:define name="topmenu"> <ui:debug hotkey="1" rendered="true" /> <div id="Container"> <div id="TopMenu"> <ul> <li>ProductPage</li> <li>Adress</li> <li>Enzo</li> <li> <h:outputLabel value="total products: #{shoppingCart.totalProducts}" /> </li> </ul> </div> <div id="Outer"> <div id="Header"> <div id="Logo"> <div id="LogoContainer"></div> </div> </div> <div id="Menu"> <ul> <li>Home</li> <li>Adress</li> <li>Enzo</li> </ul> </div> </div> </div> </ui:define> <ui:define name="content"> <div id="Wrapper"> <h:form styleClass="Left"> <rich:dataList var="cat" value="#{productCategoryRepos.allCategories}" rows="11"> <h:commandLink action="#{prodCon.showProducts(cat.productcatId)}" value="#{cat.name}" /> <br /> </rich:dataList> </h:form> <h:form styleClass="Content"> <h:outputLabel value="Products" /> <rich:panel style="height : 704px; width : 577px;"> <f:facet name="header"> <h:outputText value="Car Store"></h:outputText> </f:facet> <rich:dataGrid value="#{productCategoryRepos.getProductsByCategoryId(prodCon.productcatId)}" var="prod" columns="2" elements="2" width="550px"> <rich:panel bodyClass="pbody"> <f:facet name="header"> <h:outputText value="#{prod.name}"></h:outputText> </f:facet> <h:panelGrid columns="2"> <h:panelGroup> <h:outputText value="Name:" styleClass="label"></h:outputText> <h:outputText value="#{prod.name}" /> <br /> <h:outputText value="webprice:" styleClass="label"></h:outputText> <h:outputText value="#{prod.webprice}" /> <br /> <h:commandLink action="#{prodSelCon.addProduct(prod)}" id="add" value="Add to Cart" /> <br /> </h:panelGroup> <h:graphicImage width="40" height="50" value="/img/Emperor-Palpatine.jpg" /> </h:panelGrid> </rich:panel> <f:facet name="footer"> <br /> <h:commandLink action="#{prodCon.aktie}" value="KLIK 2" /> </f:facet> </rich:dataGrid> </rich:panel> </h:form> <h:form styleClass="Right"> <h:outputText value="Selected Products:" /> <br /> <rich:dataList var="prod" value="#{shoppingCart.products}" rows="11"> <h:outputText value="#{prod.name}" /> <br /> </rich:dataList> </h:form> </div> </ui:define>
So when I press the back button the shoppingCart.products is not executed.
Thanks for your help,
Coen -
7. Re: Back button and shopping cart contents
lvdberg Apr 4, 2011 9:46 AM (in response to coenos)Hi,
try adding the action method to your page. I can see in your page that you have additional beans as repositories, so I assume that you have your persistency there. Keep in mind that Seam injection ONLY works when methods are directly called. So calling a method in a second bean (sucg as the getShoppingCard-method is not useful. As stated, get rid of the unneccesary layers; the SFSB works directly as a controller, so normally there is no need to have additional action layers.
Leo.
-
8. Re: Back button and shopping cart contents
coenos Apr 4, 2011 10:03 AM (in response to coenos)Hi Leo,
I do have the action in my page AND in the products.pages.xml. The action is triggered correctly
I know I have not programmed very tidy (yet) but technically everything works, injection etc works fine. Only the back button problem exists.
When I do the
flow
again, the shopping cart shows the correct product, so- categories, select category
- products page : add product to cart, add another product , right column shows two products in the cart
- press back button, now products are shown but right columns shows no selected products (i.e. the page is not refreshed)
- select another category, those products are shown, and the shopping cart entries are there again!
So the problem is, why does the back button not refresh the page with the selected shopping cart entries?
Thanks for your help,
Coenos -
9. Re: Back button and shopping cart contents
lvdberg Apr 4, 2011 10:15 AM (in response to coenos)Hi,
we're talking about two different things now. You mention the result of an action in the navigation-rule. I mean the addition of an action when you
create
the view.This is an attribute in the page(s) tag. Examples:
<page view-id="/myPage.xhtml" > <action execute="#{doSomething.init}" if="#{ifNeeded}"/> </page> or <page view-id="/myPage.xhtml" action="#{doSomething.init}" />
Whne you add an action to your page definition, you're sure that something gets executed BEFORE rendering anything.
Leo
-
10. Re: Back button and shopping cart contents
antibrumm.mfrey0.bluewin.ch Apr 4, 2011 10:34 AM (in response to coenos)Hi
This sounds for me like a very
basic
caching issue. Did you check if the browser refetches the page when the back button is used? Normal behavior here is that the browser just displays the cached page.I had a very similar issue with ajax rendered stuff on the page. The browser shows just the initially loaded page, which contains none of the ajax rendered parts. I think you use always standard h:commandbuttons? Then i could guess that the url looks always the same if you do not propagate the conversation id. If the url does not change from request to request i'm not sure if all browsers update the cache properly.
As a last resort you could always rerender your shopping cart with an ajax call through the body onload function. This one is called also on the back button usage, even if the page is coming from the cache. As long as your backing bean is in the correct state there should be no issue with that.
-
11. Re: Back button and shopping cart contents
coenos Apr 4, 2011 10:55 AM (in response to coenos)Hi Martin,
indeed, I am wondering, is it a cache issue or my own misconfiguration of my app???
Because when I navigate all the way back to the categories, the cart's products are shown. Only when navigating the
products
pages I have this problem.But I am reading in a lot of articles that Seam should be able to handle this; handling the correct state using the back button.
Thanks,
Coenos -
12. Re: Back button and shopping cart contents
lvdberg Apr 4, 2011 11:07 AM (in response to coenos)Hi Cone,
Personally I think you have an application program as well as a configuration problem. Seam handles the use of the back-button transparantly, and as long as you configure everything as it should be it should work in a stateful and an statlesss environment. However your pages files miss the extra settings, so I assume you have the application handling everything.
The second issue is the Scope of your beans. It may work in the prsent context, but you're missing Seam's perfect handling of conversations (also necessary to handle also the Back-button).
My advice I can give you at the moment is that you re-consider things and go through the docs on the matter.
Leo
-
13. Re: Back button and shopping cart contents
coenos Apr 4, 2011 11:19 AM (in response to coenos)Hi Leo,
I changed the scope of my beans and added some method to pages.xml.
I added this to pages.xml
<page view-id="/custom/products.xhtml" action="#{shoppingCart.init}" />
But why should I initialize something that is already initialized, like the Shopping Cart. The Cart contains the correct objects but it is not rerendered. You say that Seam handles the back button transparantly, but the docs don't say how to configure this. I thought I had everything as it should in the products.pages.xml and pages.xml but apparently not.
So that's why I posted my question.Thanks,
Coenos -
14. Re: Back button and shopping cart contents
lvdberg Apr 4, 2011 11:30 AM (in response to coenos)Hi,
from the manual:
8.1.2. Seam and the back button
When JSF or Seam navigation rules are used, Seam lets the user freely navigate via the back,
forward and refresh buttons. It is the responsibility of the application to ensure that conversational
state remains internally consistent when this occurs. Experience with the combination of web
application frameworks like Struts or WebWork - that do not support a conversational model -
and stateless component models like EJB stateless session beans or the Spring framework has
taught many developers that this is close to impossible to do! However, our experience is that
in the context of Seam, where there is a well-defined conversational model, backed by stateful
session beans, it is actually quite straightforward. Usually it is as simple as combining the use
of no-conversation-view-id with null checks at the beginning of action listener methods. We
consider support for freeform navigation to be almost always desirable.
In this case, the no-conversation-view-id declaration goes in pages.xml. It tells Seam to
redirect to a different page if a request originates from a page rendered during a conversation,
and that conversation no longer exists<page view-id="/checkout.xhtml" no-conversation-view-id="/main.xhtml"/>
On the other hand, in the stateful model, using the back button is interpreted as an undefined
transition back to a previous state. Since the stateful model enforces a defined set of transitions
from the current state, the back button is not permitted by default in the stateful model! Seam
transparently detects the use of the back button, and blocks any attempt to perform an action from
a previous, stale page, and simply redirects the user to the current page (and displays a faces
message). Whether you consider this a feature or a limitation of the stateful model depends upon
your point of view: as an application developer, it is a feature; as a user, it might be frustrating!
You can enable backbutton navigation from a particular page node by settingback=enabled
.
etc. etc.It's just there (my 2.1.2. version of the doc),
Leo