Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do not understand passing parameters in seam

As I debug my seam application, it dawns on me that I don't really understand how parameter passing works. The following terminology really has me confused. So I am asking this very general question in the hopes of getting a good explanation of what works with what and what certain things are for.

First of all, to get from one page to the next you can use h:commandButton or s:button. I understand that s:button does not submit a form, but that doesn't help me understand the difference. If you are not submitting a form by going from one page to the next, then what are you doing?

My app involves entering information in a form, hitting a button and then going to a new page that displays results after running a query. It seems I have seen this activity take place with s:button, so how is that if it's not "submitting a form"? I feel I'm missing something fundamental here.

As for the parameters themselves...from what I have seen you can pass parameters using one of 3 methods:

  1. f:param. This seems to occur more often in combo with s:button than h:commandbutton. Why is that?
  2. Also, you can "pass" (or something) parameters using your page.xml file. The parameter seems to have to appear in both the source page.xml and the target page.xml to make it show up in the URL.
  3. Last of all, there is the option of adding @RequestParameter annotation to your backing bean. I gather that is also used when you set f:param in your view. Does that mean the one in page.xml gets overlooked? I notice in the registration example of the seam distribution, the user bean gets populated without any parameters being passed via page.xml for f:param. How is that possible?

I'm sure this question reveals a great deal of ignorance.

Hopefully one of you eloquent people will "get" what I'm asking and give me an explanation of this process.

Thanks in advance.

TDR

like image 471
april26 Avatar asked Oct 21 '09 15:10

april26


2 Answers

If you are not submitting a form by going from one page to the next, then what are you doing?

Navigating to another page without submitting any form fields.

My app involves entering information in a form, hitting a button and then going to a new page that displays results after running a query. It seems I have seen this activity take place with s:button

s:button won't submit the form, so the values on your page will not be applied to the model. You must use a commandButton/Link for this. The activity you may have seen is passing an already populated value to another page.

f:param

Used more often with s:button/link as these are often used for navigation. You can use f:param to pass an already populated value across to another page. h:commandButton/Link is used for submitting forms so the values are in form fields. Of course there is nothing stopping you from using f:param for this to.

page.xml

the params used here are for applying request parameters to the model and vice versa.

@RequestParameter

Can be used in conjunction with all of the above but is a little pointless when used with page.xml params as they can be used to do the same job

Example

If you start with this page:

http://mydomain.com/myapp/home.seam?name=damo

And the home.page.xml has:

<param name="name" value="#{person.name}"/>

Then when the page is loaded person.setName("damo") will be called as there is a matching request parameter in the URL.

You can store the value of the param in the link to the next page:

<s:link value="Go to Page 2" view="/page2.xhtml">
  <f:param name="name" value="#{person.name}"/>
</s:link>

When you click the link and navigate to http://mydomain.com/myapp/page2.seam And the page2.page.xml has:

<param name="name" value="#{someOtherBean.name}"/>

Then someOtherBean.setName("damo") will be called.

Page2 may have a s:button like this:

<s:button value="Say Hello" action="#{someOtherBean.sayHello}">
  <f:param name="subject" value="#{someOtherBean.name}"/>
</s:button>

And the method could be:

@Name("someOtherBean")
public class SomeOtherBean {

  @RequestParameter("subject")  //same value as the 'name' in f:param
  private String subject;

  public void sayHello() {
    System.out.println("Hello "+subject);
  }
}

Hope this helps!

like image 159
Damo Avatar answered Nov 15 '22 01:11

Damo


There is already a great answer for this question. I am just trying to add some extra info.

If you are not submitting a form by going from one page to the next, then what are you doing?

  1. Already expalined in @Damo's answer
  2. Do a client side validation or run a javascript before navigating to next page using onclick attribute of the button.
  3. Call a method in bean using the action attribute.

My app involves entering information in a form, hitting a button and then going to a new page that displays results after running a query. It seems I have seen this activity take place with s:button

  1. As mentioned in @Damo's answer <s:button> / <s:link> doesn't submit the form so you may run your query in second page but surely without previously entered data.
  2. But if you have used <a4j:support>/<a4j:ajax> tags with the input fields in your first page, you can access that data in your second page if you are inside a long running conversation or if your bean is session scoped. If you see the form data in your second page this could be the reason.

There is the option of adding @RequestParameter annotation to your backing bean. I gather that is also used when you set f:param in your view. Does that mean the one in page.xml gets overlooked?

        Yes, the value set through the page.xml will be overridden. Look at following example.
Assume that your page.xml has following line.

<param name="name" value="#{myBean.name}"/>

and your bean has getter and setter methods for name property and you define the variable name as below.

@RequestParameter
String name;

Now if you call the page like this.

http://...../app_name/home.seam?name=william

the setName will be called and the name property is set to "william".

Now assume you define your variable like this .

@RequestParameter("userName")
String name;

And call the page like this.

http://...../app_name/home.seam?name=william&userName=tony

Then still setName method is called and the name property is set to "william". But then this value is overridden by the value "tony".

like image 24
prageeth Avatar answered Nov 15 '22 01:11

prageeth