• Post Reply Bookmark Topic Watch Topic
  • New Topic

Sharing bean properties between forms

 
Wally Hartshorn
Ranch Hand
Posts: 77
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm working on my first JSF program and have run into a problem.

This is a small webapp, consisting of 3 pages:

  • a List page that allows the user to select one or more items from the list;
  • a Preview page that shows the user the items they've selected and asks them for a user ID and password;
  • a Done page that shows them the final results of the operation -- success or failure.

  • (It's actually just a web front-end to allow the user to FTP files between two servers.)

    I have created two managed beans:

  • a ListPageBean to hold the information that is entered on the List page;
  • a PreviewPageBean to hold the information that is entered on the Preview page.

  • In order to FTP the files, the FTP method needs access to some information that was entered on the List page (the names of the files to be transferred) and some information that was entered on the Preview page (the user ID and password). However, this information is stored in two different managed beans.

    How does a method in one managed bean access information stored in a different managed bean? Am I supposed to be somehow retrieving it from the session? How would I do that? Or am I somehow supposed to be passing the bean via the <h:commandButton>, in which case how would I do that?

    Or am I approaching this all wrong? I've been working under the assumption that "good MVC design" implies a separate bean for each form (page). Is that incorrect? Am I supposed to be created a single large managed bean to hold everything?
     
    Wally Hartshorn
    Ranch Hand
    Posts: 77
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I've figured out a way to get the info I need, but it is very kludgey and feels wrong.



    Surely there's a better way?

    (Plus, this gives me a warning in Eclipse that I don't understand: "Type safety: The cast from Object to ArrayList<FileBean> is actually checking against the erased type ArrayList". What does that mean? How can I fix it?)
     
    Tim Holloway
    Bartender
    Posts: 18412
    58
    Android Eclipse IDE Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Yes, there's a better way, and it involves JSF's Inversion of Control. Use the jsf config xml file to wire an injection of the bean containing the control information into the bean that consumes that information. Kito Mann's JDF In Action book gave me the info I needed to do that.

    In my case, one page was a search form, the second was a list of searched-for objects. By adding a setter for the search form's backing bean into the list's backing bean and wiring the injection into the framework xml, it all became trivial, because then all the lister had to do was get an "update list" event fired, and it got the search parameters as properties of the injected search form bean. (e.g. "searchBean.getSortOrder()").

    The great thing about this is that you don't have to code anything at all that's JSF-specific, and you can test the beans outside the JSF system.
     
    Wally Hartshorn
    Ranch Hand
    Posts: 77
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    When I first read your message, I must say I scarcely understood a word of it. :-) However, I did a search on "JSF inversion of control" and found this article, The JavaServer Faces Managed Bean Facility, that explained Inversion of Control well enough that I think I understand what you were recommending.

    So, just to confirm that I haven't misunderstood, I'll explain what I did:

    In my faces-confix.xml file, I added a <managed-property> to the "preview" bean, like so:


    That calls getSelectedFiles in the ListPageBean and uses it to call setSelectedFiles in the PreviewPageBean. So, I need to add a getter/setter and instance variable for selectedFiles in my ListPageBean, like so:



    I can then access the selectedFiles property from my preview.jsp page, like so:



    Is that what you had in mind? I'm a little bit uncomfortable with having a getter/setter and instance variable in one bean that duplicates that of another bean, since it duplicates code, but since the getter/setter code is extremely short -- "this.myVar = myVar" and "return myVar" -- I suppose it doesn't much matter.

    Thanks very much for your help! This is definitely going to be easier to use than my previous solution.
     
    Wally Hartshorn
    Ranch Hand
    Posts: 77
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Ah! Wait, I think I just figured out what you really meant. In my previous reply, I created a property in the PreviewPageBean for the property that needed to be retrieved from the ListPageBean. That works, but it requires creating a getter/setter for each property that needs to be accessed.

    After poking about a bit more, I think that what you were saying is that I should create a property in the PreviewPageBean that refers to the entire ListPageBean, not just to one property. Is that correct?

    I changed my code to this and successfully tested it.

    In my faces-confix.xml file, I added a <managed-property> to the "preview" bean, like so:


    That creates a property called "list" in the PreviewPageBean and points it to the ListFormBean. So, I need to add a getter/setter and instance variable for "list" in my ListPageBean, like so:



    I can then access the selectedFiles property of the ListFormBean from my preview.jsp page, like so:



    Is that more like what you had in mind? That eliminates the duplicate code of creating getter/setter methods for each property that I want to access. It feels much cleaner!
     
    Tim Holloway
    Bartender
    Posts: 18412
    58
    Android Eclipse IDE Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    If you find IoC confusing, take comfort in the fact that I still struggle with inside-out thinking myself on occasion.

    To say definitively that you did things "right", I'd have to print out all the above and make sure that everything was flowing in the expected directions, but for practical purposes, "right" means 1) it does what you wanted it to, 2) that it won't break when you make trivial changes.

    Usually, you'll find that the solution that requires the least code/xml is the "right" one.
     
    Fintan Conway
    Ranch Hand
    Posts: 142
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Originally posted by Wally Hartshorn:



    this gives me a warning in Eclipse that I don't understand:
    "Type safety: The cast from Object to ArrayList<FileBean> is actually checking against the erased type ArrayList".

    What does that mean? How can I fix it?)

    This problem is purely to do with generics. It essentially tells you that you are casting from an non-generic Object to a generic type (ArrayList<FileBean> . These are only warnings, which I tend to ignore.

    HTH,

    Fintan
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!