Saturday, June 3, 2006

Communication in JSF

Notice

This article is targeted on JSF 1.x. For JSF 2.x, please checkout this article.

Passing action parameters from JSF to backing beans

This can be done in several ways, with f:setPropertyActionListener, f:attribute and f:param.

f:setPropertyActionListener: with the h:commandLink and h:commandButton tags you can trigger a method of the backing bean using the action or the actionListener attribute. As you cannot directly pass some method parameters from the JSF to the backing bean, the f:setPropertyActionListener tag might be very useful to dynamically set the bean properties which can be used as parameters. This works in JSF 1.2 or newer only. Here is an example:

<h:form>
    <h:commandLink value="Click here" action="#{myBean.action}">
        <f:setPropertyActionListener target="#{myBean.propertyName1}" value="propertyValue1" />
        <f:setPropertyActionListener target="#{myBean.propertyName2}" value="propertyValue2" />
    </h:commandLink>

    <h:commandButton value="Press here" action="#{myBean.action}">
        <f:setPropertyActionListener target="#{myBean.propertyName1}" value="propertyValue1" />
        <f:setPropertyActionListener target="#{myBean.propertyName2}" value="propertyValue2" />
    </h:commandButton>
</h:form>

This require at least a setter for propertyName1 and propertyName2 in the backing bean:

package mypackage;


public class MyBean {

    // Init --------------------------------------------------------------------------------------

    private String propertyName1;
    private String propertyName2;

    // Actions -----------------------------------------------------------------------------------

    public void action() {
        System.out.println("propertyName1: " + propertyName1);
        System.out.println("propertyName2: " + propertyName2);
    }

    // Setters -----------------------------------------------------------------------------------

    public void setPropertyName1(String propertyName1) {
        this.propertyName1 = propertyName1;
    }

    public void setPropertyName2(String propertyName2) {
        this.propertyName2 = propertyName2;
    }

}

Now the properties propertyName1 and propertyName2 should contain the values propertyValue1 and propertyValue2 respectively.

f:attribute: with the h:commandLink and h:commandButton tags you can also trigger a method of the backing bean using the actionListener attribute. With this you can also use the f:attribute tag to dynamically pass the parameters. Here is an example:

<h:form>
    <h:commandLink value="Click here" actionListener="#{myBean.action}">
        <f:attribute name="attributeName1" value="attributeValue1" />
        <f:attribute name="attributeName2" value="attributeValue2" />
    </h:commandLink>

    <h:commandButton value="Press here" actionListener="#{myBean.action}">
        <f:attribute name="attributeName1" value="attributeValue1" />
        <f:attribute name="attributeName2" value="attributeValue2" />
    </h:commandButton>
</h:form>

Those attributes can be retrieved using getAttributes() of the parent UI component, which on its turn can be retrieved by the ActionEvent passed by the actionListener.

package mypackage;

import javax.faces.event.ActionEvent;

import net.balusc.util.FacesUtil;

public class MyBean {

    // Actions -----------------------------------------------------------------------------------

    public void action(ActionEvent event) {
        String attributeName1 = FacesUtil.getActionAttribute(event, "attributeName1");
        String attributeName2 = FacesUtil.getActionAttribute(event, "attributeName2");

        System.out.println("attributeName1: " + attributeName1);
        System.out.println("attributeName1: " + attributeName1);
    }

}
package net.balusc.util;

import javax.faces.event.ActionEvent;

public class FacesUtil {

    // Getters -----------------------------------------------------------------------------------

    public static String getActionAttribute(ActionEvent event, String name) {
        return (String) event.getComponent().getAttributes().get(name);
    }

}

The variables attributeName1 and attributeName2 now should contain the values attributeValue1 and attributeValue2 respectively.

Take care that each attribute name should be unique and should not overwrite any default component attributes, like "id", "name", "value", "binding", "rendered", etc.

f:param: another way to pass parameters to the backing bean is using the f:param tag. This works on h:commandLink and h:outputLink only. The h:outputLink example is described in the next chapter. Here is the h:commandLink:

<h:form>
    <h:commandLink value="Click here" action="#{myBean.action}">
        <f:param name="parameterName1" value="parameterValue1" />
        <f:param name="parameterName2" value="parameterValue2" />
    </h:commandLink>
</h:form>

Those parameters can be retrieved using getRequestParameterMap() of the FacesContext. With the following utility method you can use the f:param name to request the f:param value of any f:param parameter specified in the command block:

package mypackage;

import net.balusc.util.FacesUtil;

public class MyBean {

    // Actions -----------------------------------------------------------------------------------

    public void action() {
        String parameterName1 = FacesUtil.getRequestParameter("parameterName1");
        String parameterName2 = FacesUtil.getRequestParameter("parameterName2");

        System.out.println("parameterName1: " + parameterName1);
        System.out.println("parameterName2: " + parameterName2);
    }

}
package net.balusc.util;

import javax.faces.context.FacesContext;

public class FacesUtil {

    // Getters -----------------------------------------------------------------------------------

    public static String getRequestParameter(String name) {
        return (String) FacesContext.getCurrentInstance().getExternalContext()
            .getRequestParameterMap().get(name);
    }

}

The variables parameterName1 and parameterName2 now should contain the values parameterValue1 and parameterValue2 respectively.

Back to top

Passing GET parameters from JSF to backing beans

This can be done easily using the h:outputLink tag with f:param:

<h:outputLink value="mypage.jsf">
    <f:param name="parameterName1" value="parameterValue1" />
    <f:param name="parameterName2" value="parameterValue2" />
    <h:outputText value="Click here" />
</h:outputLink>

Define those parameters in the faces-config.xml:

<managed-bean>
    <managed-bean-name>myBean</managed-bean-name>
    <managed-bean-class>mypackage.MyBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <managed-property>
        <property-name>parameterName1</property-name>
        <value>#{param.parameterName1}</value>
    </managed-property>
    <managed-property>
        <property-name>parameterName2</property-name>
        <value>#{param.parameterName2}</value>
    </managed-property>
</managed-bean>

And add those properties to the backing bean MyBean.java:

package mypackage;

public class MyBean {

    // Init --------------------------------------------------------------------------------------

    private String parameterName1;
    private String parameterName2;

    // Getters -----------------------------------------------------------------------------------

    public String getParameterName1() {
        return parameterName1;
    }

    public String getParameterName2() {
        return parameterName2;
    }

    // Setters -----------------------------------------------------------------------------------

    public void setParameterName1(String parameterName1) {
        this.parameterName1 = parameterName1;
    }

    public void setParameterName2(String parameterName2) {
        this.parameterName2 = parameterName2;
    }

}

The #{param} is a predefinied variable referring to the request parameter map which also can be retrieved by FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap(). Invoking a GET request using the following URL will set the parameter values automatically in the managed bean instance, thanks to the managed-property configuration in the faces-config.xml:
http://example.com/mypage.jsf?parameterName1=parameterValue1&parameterName2=parameterValue2

If you want to execute some action directly after setting of the managed properties, then add a method which you annotate using the @PostConstruct annotation.


    @PostConstruct
    public void doSomeAction() {
        // Do your thing here with parameterName1 and parameterName2!
    }

Which is only available as per JSF 1.2 however. If you're still using JSF 1.1 or older, then consider adding 'lazy executing' to the setter (check if the current property is null and then execute some logic before assigning). This is the opposite of 'lazy loading' which can happen in the getter (check if the current property is null and then assign it before returning).


    public void setParameterName1(String parameterName1) {
        if (this.parameterName1 == null) {
            // This will only be executed if the property was null before.
            doSomeAction(parameterName1);
        }
        this.parameterName1 = parameterName1;
    }

    // Or, without passing the parameter (and let the action access the instance variable):

    public void setParameterName2(String parameterName2) {
        boolean wasNull = this.parameterName2 == null;
        this.parameterName2 = parameterName2;
        if (wasNull) {
            // This will only be executed if the property was null before.
            doSomeAction();
        }
    }

Back to top

Passing component attributes from JSF to backing beans

The f:attribute tag can also be used in conjunction with every UI component which is bound to the backing bean using the binding attribute of the UI component. All of those attributes can be retrieved using getAttributes() of the parent UI component. As you cannot directly pass some method parameters from the JSF to the getters and setters of the bound UI component in the backing bean, the f:attribute tag might be very useful to dynamically pass the parameters. Here is a basic JSF example with the h:outputText component bound to the backing bean:

<h:outputText binding="#{myBean.text}" value="#{myBean.textValue}">
    <f:attribute name="attributename" value="attributevalue" />
</h:outputText>

Take care that each attribute name should be unique and should not overwrite any default component attributes, like "id", "name", "value", "binding", "rendered", etc.

Here is the dummy example of the backing bean code:

package mypackage;

import javax.faces.component.html.HtmlOutputText;

public class MyBean {

    // Init --------------------------------------------------------------------------------------

    private HtmlOutputText text;

    // Getters -----------------------------------------------------------------------------------

    public HtmlOutputText getText() {
        return text;
    }

    public String getTextValue() {
        return (String) text.getAttributes().get("attributename");
    }

    // Setters -----------------------------------------------------------------------------------

    public void setText(HtmlOutputText text) {
        this.text = text;
    }

}

The value of the h:outputText now should contain the value set in the f:attribute tag.

Back to top

Passing objects from request to request

If you have a request scoped managed bean and you want to reuse a property, parameter and/or object for the next request, without reinitializing it again and again, then just use the h:inputhidden tag to save the object in it. Here is a basic JSF example:

<h:form>
    ...
    <h:inputHidden value="#{myBean.value}" />
    ...
</h:form>

One requirement is that the value should be a String, or Number, or Boolean (where JSF has built-in converters for which automatically converts between them and String) or a primitive, otherwise you have to write a custom converter for it.

You can also use the SessionMap to store the values which should be saved during one user session:

package net.balusc.util;

import javax.faces.context.FacesContext;

public class FacesUtil {

    // Getters -----------------------------------------------------------------------------------

    public static Object getSessionMapValue(String key) {
        return FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(key);
    }

    // Setters -----------------------------------------------------------------------------------

    public static void setSessionMapValue(String key, Object value) {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(key, value);
    }

}

This all is not needed for a session scoped managed bean as the managed bean instance won't be garbaged and re-instantiated on every request. If you want to remove the value from the SessionMap, then set it to null or just invoke sessionMap.remove(key).

If you want to store static-like variables which are equal and accessible for all sessions, then you can use the ApplicationMap:

package net.balusc.util;

import javax.faces.context.FacesContext;

public class FacesUtil {

    // Getters -----------------------------------------------------------------------------------

    public static Object getApplicationMapValue(String key) {
        return FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().get(key);
    }

    // Setters -----------------------------------------------------------------------------------

    public static void setApplicationMapValue(String key, Object value) {
        FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().put(key, value);
    }

}

Of course this one is also not needed for an application scoped managed bean.

An alternative to the above is the Tomahawk's t:saveState tag. It is similar the h:inputHidden, with the biggest difference that you can pass non-standard object types (such as managed beans, collections, custom objects, etc) along it while the h:inputHidden only accepts standard object types (String, Number, Boolean) as long as you don't supply a Converter.

Back to top

Passing new hidden values to backing beans

If you want to pass new hidden input values to the backing beans, then there are two general ways. One way where you use a plain vanilla HTML hidden input field with the hardcoded value and another way where you use the JSF h:inputHidden whose value is manipulated with Javascript.

Here is the hardcoded example, you can use a plain vanilla HTML hidden input field with a form-unique name. Its value will be available in the getRequestParameterMap(). You can obtain it directly in the action method or even define a managed property for it in the backing bean. The example below makes use of the managed-property entry.

<h:form>
    <h:commandButton value="submit" action="#{myBean.action}" />
    <input type="hidden" name="hiddenInput" value="foo" />
</h:form>

The relevant part of the faces-config.xml:

<managed-bean>
    <managed-bean-name>myBean</managed-bean-name>
    <managed-bean-class>mypackage.MyBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <managed-property>
        <property-name>hiddenInput</property-name>
        <value>#{param.hiddenInput}</value>
    </managed-property>
</managed-bean>

The backing bean (the getter is indeed not required):

package mypackage;

import javax.faces.context.FacesContext;

public class MyBean {

    // Init --------------------------------------------------------------------------------------

    private String hiddenInput;

    // Actions -----------------------------------------------------------------------------------

    public void action() {
        System.out.println("hiddenInput: " + hiddenInput);
        
        // It is also available as follows:
        System.out.println(FacesContext.getCurrentInstance().getExternalContext()
            .getRequestParameterMap().get("hiddenInput"));
        // In this case the property as well as managed-property are redundant.
    }

    // Setters -----------------------------------------------------------------------------------

    public void setHiddenInput(String hiddenInput) {
        this.hiddenInput = hiddenInput;
    }

}

Here is the Javascript way, you can just use the h:inputHidden component and manipulate its value using Javascript. All what you need to know in the Javascript side is the client ID of the h:inputHidden component. Check the generated HTML source if you're unsure.

<h:form id="form">
    <h:commandButton value="submit" action="#{myBean.action}"
        onclick="document.getElementById('form:hiddenInput').value = 'foo';" />
    <h:inputHidden id="hiddenInput" value="#{myBean.hiddenInput}" />
</h:form>

The relevant part of the faces-config.xml, there is no managed property needed:

<managed-bean>
    <managed-bean-name>myBean</managed-bean-name>
    <managed-bean-class>mypackage.MyBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

The backing bean:

package mypackage;

public class MyBean {

    // Init --------------------------------------------------------------------------------------

    private String hiddenInput;

    // Actions -----------------------------------------------------------------------------------

    public void action() {
        System.out.println("hiddenInput: " + hiddenInput);
    }

    // Getters -----------------------------------------------------------------------------------

    public String getHiddenInput() {
        return hiddenInput;
    }

    // Setters -----------------------------------------------------------------------------------

    public void setHiddenInput(String hiddenInput) {
        this.hiddenInput = hiddenInput;
    }

}
Back to top

Communication between managed beans

You can have more than one managed bean in a scope. If required by design, then you can use getSessionMap() of the FacesContext to communicate between the managed beans during one browser session. This can be very useful for user-sessions by example.

An example of two managed beans in the faces-config.xml:

<managed-bean>
    <managed-bean-name>myBean1</managed-bean-name>
    <managed-bean-class>mypackage.MyBean1</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

<managed-bean>
    <managed-bean-name>myBean2</managed-bean-name>
    <managed-bean-class>mypackage.MyBean2</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

The managed beans myBean1 and myBean2 are instances of the backing beans MyBean1.java and MyBean2.java, which can be accessed by JSF pages. It don't matter whether the managed-bean-scope is set to request or session. With the managed-bean-scope set to session, the same instance of the backing bean will be used during the whole session. When the scope is set to request, then each request (form action) will create a new instance of the backing bean everytime.

You can use the getSessionMapValue() and setSessionMapValue() of the FacesUtil which is mentioned in the former paragraph to get and set values in the SessionMap. Here is an use example:

package mypackage;


import net.balusc.util.FacesUtil;

public class MyBean1 {

    // Actions -----------------------------------------------------------------------------------

    public void action() {
        String value = "value1";
        FacesUtil.setSessionMapValue("MyBean1.value", value);
    }

}
package mypackage;

import net.balusc.util.FacesUtil;

public class MyBean2 {

    // Actions -----------------------------------------------------------------------------------

    public void action() {
        String value = (String) FacesUtil.getSessionMapValue("MyBean1.value");
    }

}

The variable value now should contain the value value1. Of course only if already set by another managed bean.

Back to top

Injecting managed beans in each other

You can also inject the one managed bean in the other managed bean as a property. This may be useful if you have an application scoped bean for e.g. configurations and you want to use it in a session or request scoped bean. This is also useful if you want to keep the large data of datatables in session scope and the form actions in request scope.

Here is an example of an application scoped and request scoped managed bean in the faces-config.xml where the application scoped bean is injected in the request scoped bean:

<managed-bean>
    <managed-bean-name>myBean1</managed-bean-name>
    <managed-bean-class>mypackage.MyBean1</managed-bean-class>
    <managed-bean-scope>application</managed-bean-scope>
</managed-bean>

<managed-bean>
    <managed-bean-name>myBean2</managed-bean-name>
    <managed-bean-class>mypackage.MyBean2</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <managed-property>
        <property-name>myBean1</property-name>
        <value>#{myBean1}</value>
    </managed-property>
</managed-bean>

Where the MyBean2 look like:

package mypackage;

public class MyBean2 {

    // Init --------------------------------------------------------------------------------------

    private MyBean1 myBean1;

    // Getters -----------------------------------------------------------------------------------

    public MyBean1 getMyBean1() {
        return myBean1;
    }

    // Setters -----------------------------------------------------------------------------------

    public void setMyBean1(MyBean1 myBean1) {
        this.myBean1 = myBean1;
    }

}
Back to top

Accessing another managed bean

If you have more than one managed bean in a scope and you want to get the current instance of the another managed bean and get access to its properties, then there are eight ways to get the instance using the FacesContext. You can use getRequestMap, getSessionMap, getApplicationMap, getVariableResolver, createValueBinding, getELResolver (since JSF 1.2), createValueExpression (since JSF 1.2) or evaluateExpressionGet (since JSF 1.2). The first three ways will not implicitly create the bean if it is not already created by JSF or yourself. The last five ways will do.

An example of two managed beans in the faces-config.xml:

<managed-bean>
    <managed-bean-name>myBean1</managed-bean-name>
    <managed-bean-class>mypackage.MyBean1</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

<managed-bean>
    <managed-bean-name>myBean2</managed-bean-name>
    <managed-bean-class>mypackage.MyBean2</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

The managed beans myBean1 and myBean2 are instances of the backing beans MyBean1.java and MyBean2.java, which can be accessed by JSF pages. It don't matter whether the managed-bean-scope is set to request or session. Only take care that you can use the getRequestMap method only when the scope of the another managed bean is set to request, and you can use the getSessionMap only when the scope of the another managed bean is set to session.

The JSF use example:

<h:form>
    <h:commandButton action="#{myBean1.action1}" value="action1" />
    <h:commandButton action="#{myBean1.action2}" value="action2" />
    <h:commandButton action="#{myBean1.action3}" value="action3" />
    <h:commandButton action="#{myBean1.action4}" value="action4" />
    <h:commandButton action="#{myBean1.action5}" value="action5" />
    <h:commandButton action="#{myBean1.action6}" value="action6" />
    <h:commandButton action="#{myBean1.action7}" value="action7" />
    <h:commandButton action="#{myBean1.action8}" value="action8" />
    <h:outputText binding="#{myBean2.text}" />
</h:form>

Here is the first bean, MyBean1.java. Note that you should access the another managed bean by the managed-bean-name as definied in the faces-config.xml.

package mypackage;

import javax.faces.context.FacesContext;

public class MyBean1 {

    // Actions -----------------------------------------------------------------------------------

    // Using RequestMap. NOTE: myBean2 should be request scoped and already created!
    public void action1() {
        MyBean2 myBean2 = (MyBean2) FacesContext.getCurrentInstance().getExternalContext()
            .getRequestMap().get("myBean2");
                            
        // This only works if myBean2 is request scoped and already created.
        if (myBean2 != null) {
            myBean2.getText().setValue("action1");
        }
    }

    // Using SessionMap. NOTE: myBean2 should be session scoped and already created!
    public void action2() {
        MyBean2 myBean2 = (MyBean2) FacesContext.getCurrentInstance().getExternalContext()
            .getSessionMap().get("myBean2");
                            
        // This only works if myBean2 is session scoped and already created.
        if (myBean2 != null) {
            myBean2.getText().setValue("action2");
        }
    }

    // Using ApplicationMap. NOTE: myBean2 should be application scoped and already created!
    public void action3() {
        MyBean2 myBean2 = (MyBean2) FacesContext.getCurrentInstance().getExternalContext()
            .getApplicationMap().get("myBean2");
                            
        // This only works if myBean2 is application scoped and already created.
        if (myBean2 != null) {
            myBean2.getText().setValue("action3");
        }
    }

    // Using VariableResolver. NOTE: this is deprecated since JSF 1.2!
    public void action4() {
        FacesContext context = FacesContext.getCurrentInstance();
        MyBean2 myBean2 = (MyBean2) context.getApplication()
            .getVariableResolver().resolveVariable(context, "myBean2");

        myBean2.getText().setValue("action4");
    }

    // Using ValueBinding. NOTE: this is deprecated since JSF 1.2!
    public void action5() {
        FacesContext context = FacesContext.getCurrentInstance();
        MyBean2 myBean2 = (MyBean2) context.getApplication()
            .createValueBinding("#{myBean2}").getValue(context);

        myBean2.getText().setValue("action5");
    }

    // Using ELResolver. NOTE: this is implemented since JSF 1.2!
    public void action6() {
        FacesContext context = FacesContext.getCurrentInstance();
        MyBean2 myBean2 = (MyBean2) context.getELContext()
            .getELResolver().getValue(context.getELContext(), null, "myBean2");

        myBean2.getText().setValue("action6");
    }

    // Using ValueExpression. NOTE: this is implemented since JSF 1.2!
    public void action7() {
        FacesContext context = FacesContext.getCurrentInstance();
        MyBean2 myBean2 = (MyBean2) context.getApplication().getExpressionFactory()
            .createValueExpression(context.getELContext(), "#{myBean2}", MyBean2.class)
                .getValue(context.getELContext());

        myBean2.getText().setValue("action7");
    }

    // Using evaluateExpressionGet. NOTE: this is implemented since JSF 1.2!
    public void action8() {
        FacesContext context = FacesContext.getCurrentInstance();
        MyBean2 myBean2 = (MyBean2) context.getApplication()
            .evaluateExpressionGet(context, "#{myBean2}", MyBean2.class);

        myBean2.getText().setValue("action8");
    }

}

The second bean, MyBean2.java:

package mypackage;

import javax.faces.component.html.HtmlOutputText;

public class MyBean2 {

    // Init --------------------------------------------------------------------------------------

    private HtmlOutputText text;

    // Getters -----------------------------------------------------------------------------------

    public HtmlOutputText getText() {
        return text;
    }

    // Setters -----------------------------------------------------------------------------------

    public void setText(HtmlOutputText text) {
        this.text = text;
    }

}

You'll probably question: Which is the best way then?? Use the evaluateExpressionGet approach (which is by the way just a shorthand for the ValueExpression approach). For ones who are still sitting with the ancient JSF 1.1 or older, then go ahead with ValueBinding approach.

Back to top

Returning current managed bean instance of self

You can also let the backing bean return the current managed bean instance of self using a static method. Here is an example with a request scoped managed bean:

<managed-bean>
    <managed-bean-name>myBean1</managed-bean-name>
    <managed-bean-class>mypackage.MyBean1</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

<managed-bean>
    <managed-bean-name>myBean2</managed-bean-name>
    <managed-bean-class>mypackage.MyBean2</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

Where the MyBean1 look like:

package mypackage;

import javax.faces.context.FacesContext;

public class MyBean1 {

    // Init --------------------------------------------------------------------------------------

    private static final String MANAGED_BEAN_NAME = "myBean1";

    // Actions -----------------------------------------------------------------------------------

    public static MyBean1 getCurrentInstance() {
        return (MyBean1) FacesContext.getCurrentInstance().getExternalContext()
            .getRequestMap().get(MANAGED_BEAN_NAME);
    }

}

So you can get the current instance of MyBean1 in the another bean as follows:

package mypackage;

public class MyBean2 {

    // Actions -----------------------------------------------------------------------------------

    public void action() {
        MyBean1 myBean1 = MyBean1.getCurrentInstance();
    }

}

You can find an use example in the FriendlyUrlAction bean in the Friendly URL's in JSF article.

Back to top

Lookup the managed bean name inside the backing bean

You can have more than one managed bean instance of the same backing bean. This might be useful if you want to implement different ways to use the backing bean. When you need to know the assigned managed bean name inside the current instance of the backing bean, then you need to lookup the values of the requestmap, sessionmap or applicationmap and compare them with the current instance of the backing bean. If it is equal, then the associated key is the same as the managed bean name.

package net.balusc.util;

import java.util.Map;

import javax.faces.context.ExternalContext;

public class FacesUtil {

    // Helpers -----------------------------------------------------------------------------------

    public static String lookupManagedBeanName(Object bean) {
        ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();

        // Get requestmap.
        Map<String, Object> requestMap = externalContext.getRequestMap();
    
        // Lookup the current bean instance in the request scope.
        for (String key : requestMap.keySet()) {
            if (bean.equals(requestMap.get(key))) {
                // The key is the managed bean name.
                return key;
            }
        }
    
        // Bean is not in the request scope. Get the sessionmap then.
        Map<String, Object> sessionMap = externalContext.getSessionMap();

        // Lookup the current bean instance in the session scope.
        for (String key : sessionMap.keySet()) {
            if (bean.equals(sessionMap.get(key))) {
                // The key is the managed bean name.
                return key;
            }
        }

        // Bean is also not in the session scope. Get the applicationmap then.
        Map<String, Object> applicationMap = externalContext.getApplicationMap();

        // Lookup the current bean instance in the application scope.
        for (String key : applicationMap.keySet()) {
            if (bean.equals(applicationMap.get(key))) {
                // The key is the managed bean name.
                return key;
            }
        }

        // Bean is also not in the application scope.
        // Is the bean's instance actually a managed bean instance then? =)
        return null;
    }

}

You can call it as follows:

package mypackage;

import net.balusc.util.FacesUtil;

public class MyBean {

    // Actions -----------------------------------------------------------------------------------

    public void action() {
        String managedBeanName = FacesUtil.lookupManagedBeanName(this);
    }

}

Although remember that this is not always a good practice. If you can, rather subclass (extend) the backing bean into another backing bean and if necessary override or add some more code. Then assign another managed bean name to the subclassed backing bean.

Back to top

Accessing the FacesContext inside HttpServlet or Filter

Other Servlets than the FacesServlet and all Filters cannot directly access the FacesContext in the same web container, because they are sitting in the ServletContext outside the FacesContext. The FacesServlet is namely the one responsible for creating the FacesContext, so when it isn't invoked at that point, then the FacesContext will not be available, you'll get FacesContext.getCurrentInstance() == null.

Theoretically, you can precreate the FacesContext yourself as follows:

package mypackage;

import java.io.IOException;
import java.util.Map;

import javax.faces.context.FacesContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.balusc.util.FacesUtil;

public class MyServlet extends HttpServlet {

    // Actions -----------------------------------------------------------------------------------

    public void doGet(HttpServletRequest request, HttpServletResponse response) {
        doSomething(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) {
        doSomething(request, response);
    }

    private void doSomething(HttpServletRequest request, HttpServletResponse response) {

        // Get the FacesContext inside HttpServlet.
        FacesContext facesContext = FacesUtil.getFacesContext(request, response);

        // Now you can do your thing with the facesContext.
    }

}

And here is how you can precreate the FacesContext:

package net.balusc.util;

import javax.faces.FactoryFinder;

import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextFactory;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.lifecycle.LifecycleFactory;
import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class FacesUtil {

    // Getters -----------------------------------------------------------------------------------

    public static FacesContext getFacesContext(
        HttpServletRequest request, HttpServletResponse response)
    {
        // Get current FacesContext.
        FacesContext facesContext = FacesContext.getCurrentInstance();

        // Check current FacesContext.
        if (facesContext == null) {

            // Create new Lifecycle.
            LifecycleFactory lifecycleFactory = (LifecycleFactory)
                FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY); 
            Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);

            // Create new FacesContext.
            FacesContextFactory contextFactory  = (FacesContextFactory)
                FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
            facesContext = contextFactory.getFacesContext(
                request.getSession().getServletContext(), request, response, lifecycle);

            // Create new View.
            UIViewRoot view = facesContext.getApplication().getViewHandler().createView(
                facesContext, "");
            facesContext.setViewRoot(view);                

            // Set current FacesContext.
            FacesContextWrapper.setCurrentInstance(facesContext);
        }

        return facesContext;
    }

    // Helpers -----------------------------------------------------------------------------------

    // Wrap the protected FacesContext.setCurrentInstance() in a inner class.
    private static abstract class FacesContextWrapper extends FacesContext {
        protected static void setCurrentInstance(FacesContext facesContext) {
            FacesContext.setCurrentInstance(facesContext);
        }
    }     

}

However, think twice about this practice and don't abuse it! If you're using a Filter and you really, really need to access the FacesContext, then rather use a PhaseListener instead and listen on the first phase (the PhaseId.RESTORE_VIEW). If you just want to share data between the filter or servlet and JSF managed beans, then rather use the getAttribute() and setAttribute() methods of the HttpServletRequest (which reflects to the RequestMap), or the HttpSession (which reflects to the SessionMap), or the ServletContext (which reflects to the ApplicationMap).

The HttpSession is accessible in the HttpServlet using HttpServletRequest#getSession() and the ServletContext is accessible in the HttpServlet using the inherited method getServletContext().

Back to top

Copyright - There is no copyright on the code. You can copy, change and distribute it freely. Just mentioning this site should be fair.

(C) June 2006, BalusC

142 comments:

Joachim said...

Thanks, fine article about parameters in JSF action calls. But you should add a note that commas in ths "attrvalue1" string causes lot of trouble.

Feba said...

This section is one of the most referred section, during our development, which is in JSF. Thanks a lot for all your tips, and also to your posts in related topics in Sun's forum.

Cheers !!

Feba Mary

Gunjan Bohra said...

Thanks for this fine artical .
And thank for you effort on Sun forum ...

Noah said...

Thanks for the tips. One additional comment about "Accessing the FacesContext inside HttpServlet or Filter". This approach works great, but we found that if we were calling different servlets that used this approach, we need to call "context.release()" at the end of each servlet call. If you look at the source code in the FacesServlet, you can see the same approach is used.

Thanks,
Noah

Sandro Mancuso said...

Thank you very much for your article. It is very well written and helpful.
The best that I read so far about the topic.

Cheers.

Sandro

frosted said...

Great article! Do you know of a way to pass parameters to the rendered attribute of an inputText or any other such field?

Cheers!

BalusC said...

Use f:attribute. See the section "Passing component attributes from JSF to backing beans".

frosted said...

Thanks for the VERY quick response. I think the problem is that rendered expects to see a property of a backing bean rather than a method call, thus there is no UIComponent being passed to the method, if I am correct. I believe "action" and "actionListener" behave differently, and execute a set method signature, whereas rendered only looks for a "getProperty" method with no args. I could be wrong, though...it's happened before...a few hundred times :)

BalusC said...

That section actually demonstrates exactly what you need. In your specific case just replace the h:outputText by h:inputText, the HtmlOutputText by HtmlInputText, the value="" by rendered="" and public String getTextValue() by public boolean isRendered() -or so. Inside the isRendered() method, the attribute value is available to you the same way.

frosted said...

Yes, you are correct. Thank you so much again! One more quick question, is there any way in said method (isRendered(), for example) to get a reference to the current element on which the rendered attribute method is being executed. I am trying to set up a generic enough security-related method that will not have to be written for each component. A daunting task, for sure. Again, thanks for all the help so far :)

demonm said...

Hello! I tried to adopt example with attributes to use it with dataTable, but had problems with null here. Maybe problem in using non-standard components, because I use ICEfaces (AJAX on background). I posted my problem on it support forum here
http://www.icefaces.org/JForum/posts/list/0/6520.page

Maybe somebody can help me with solution. Thanks in advance!

BalusC said...

During the first time that the component binding getter is invoked, the attribute will indeed return null, simply because it is not set yet. Obtain the attribute in the action method or in the getter of the datalist.

Nicolas said...

To begin with, thanks for the article and all your help at the Java Forums. I'm left with a doubt, though. Have you found any "tidy" ways to pass a collection from two beans in request scope?
As in <h:inputHidden id="items" value="#{myBean.myCollection}">

Thanks again and happy new year.

BalusC said...

Nicolas: for non-String and non-Number typed objects you'll have to write a Converter or, in this case better, to use the RequestMap.

Nicolas said...

Hi Balus. I've been trying your suggestion and focused on using the RequestMap. My problem is that the collection items are being passed from/to the same backing bean. In other words, I've got the same page in faces-context from-view-id and to-view-id. When filling values with requestMap.put(..) in that situation, I find that they're not loaded afterwards.
If this is the wrong place to be asking you questions, and you still want to help, you can reach me at gmail with username s.nico.zeitlin
Thanks again!

merkas said...

If I have session scoped beans what's the benefits using ELResolver to access another managed bean instead of using SessionMap?

BalusC said...

The only benefit is that you don't need to specify the scope. If you ever change the scope in the faces-config.xml, you'll also have to change the codings.

dim5b said...

Great article, i am looking to create a login based application therefore I have a request scope bean loginBean and within the login action create UserBean(usernane,pwd)which is session scoped. here begins my problem.. i am looking to use ajax push (icefaces)
http://www.icefaces.org/JForum/posts/list/4351.page
In this post they instruct to create a request scoped bean to update the PersistentFacesState of the session bean were do I inject this ...

nohacks said...

Great stuff...Thanks for all the work !!

I have a question.

When I use this:

((h:form))
((h:commandLink value="Click here" actionListener="#{myBean.action}"))
((f:attribute name="attributeName1" value="attributeValue1" /))
((f:attribute name="attributeName2" value="attributeValue2" /))
((/h:commandLink))

((h:commandButton value="Press here" actionListener="#{myBean.action}"))
((f:attribute name="attributeName1" value="attributeValue1" /))
((f:attribute name="attributeName2" value="attributeValue2" /))
((/h:commandButton))
((/h:form))



package mypackage;

import javax.faces.event.ActionEvent;

import net.balusc.util.FacesUtil;

public class MyBean {

// Actions -----------------------------------------------------------------------------------

public void action(ActionEvent event) {
String attributeName1 = FacesUtil.getActionAttribute(event, "attributeName1");
String attributeName2 = FacesUtil.getActionAttribute(event, "attributeName2");

System.out.println("attributeName1: " + attributeName1);
System.out.println("attributeName1: " + attributeName1);
}

}

-----------------------------

I am calling MyBean.Action.

Works great for passing value to bean from JSP. How do I use that bean Action to move to the next JSP page? Since it is a void and does not return anything for faces-config.xml to navigate??

Thanks
Phil

nohacks said...

Hey,

I fixed my issue..

thanks for your time.

Nohacks

Phil

harpreet said...

Thanks Baluc

It helped me great.
Awsome blog.


Harry

cptnRidesFaster said...

Hi,

Just wanted to thank you for your blog.

While much of what is out there focuses on solutions to highly specialized esoteric problems which I probably won't ever encounter, your blog contains examples of how to solve and implement very simple and usable solutions.

This is extremely important. Keep the examples rolling. Nothing is ever too simple.

Leonardo said...

Great!!! It saved my life!

Dj said...

I'm learning JSF from your blog and I noticed an interesting behavior when using f:setPropertyActionListner. It works great when passing in strings but if fails when I pass it a value expression (value expression does evaluate correctly). ex:

h:commandButton value="Press here" action="#{myBean.action}"
f:setPropertyActionListener target="#{myBean.propertyName1}" value="#{bean2.propertyValue1}"
...

have you noticed this from your experience?

BalusC said...

Apparently bean2 is request scoped and the getter of its propertyValue1 returns null in the next request. Either put it in the session scope or use h:inputHidden to retain this value for the next request.

Dj said...

now i see the light!:) how did you become so good at jsf? what do you recommend I do to come up to speed? i'm currently reading your blog and writing a sample app so I can learn the framework.
Thanks.

Luke said...

Great article.
I've a question for pass parameter to backing bean.

<sql:query sql = "SELECT PLI_ITEM_NO,PLI_TRNH_LEN,PLI_TRNH_WID,PLI_TRNH_DEP FROM PLI_PLAN_ITEM WHERE PLI_PLAN_ID = ${pid} AND PLI_ITEM_NO = ${iid}" var = "itemresult" dataSource="${db}">
</sql:query>
<table id="ro-item" cellspacing="0" cellpadding="3" border="0">
<c:forEach var="itemrow" items="${itemresult.rows}">
<c:set var="irl" value="${itemrow.PLI_TRNH_LEN}"/>
<c:set var="irw" value="${itemrow.PLI_TRNH_WID}"/>
<c:set var="ird" value="${itemrow.PLI_TRNH_DEP}"/>
<tr><td>Length:</td*lt;
<td><h:inputText id="itemlength" value="#{irl}" size="6"></h:inputText>m</td></tr>
<tr><td>Width:</td>
<td><h:inputText id="itemwidth" value="#{irw}" size="6"></h:inputText>m
</td></tr>
<tr><td>Depth:</td>
<td><h:inputText id="itemdepth" value="#{ird}" size="6"></h:inputText>m</td></tr>
</c:forEach>
</table>
<h:commandButton id="submit" value="Submit" actionListener="#{planBean.action}">
<f:attribute name="attributeName1" value="attributeValue1" />
<f:attribute name="attributeName2" value="attributeValue2" />
</h:commandButton>

When user clicks the commandbutton, it will throw a NullPointException. I wonder why I can't pass the variable to the backing bean. Thank you in advance.

bvh said...

This is a fantastic article especially for JSF beginners like me. I have tried the samples and everything works great.
However I could not understand how I can specify what action should be executed if I provide the user with a url such as:

http://mycompany.com/product.jsp?product_id=123

How can I specify that the above link should execute MyBean.abcAction and if the result is “success” then user gets redirected to the product’s page otherwise to an error page?

I have the task of sending emails to users and in these emails I have to provide users with links to the latest products added to the database. In a pure JSP the link would look like the one above.

I am not sure if this can be done with commandButton or commandLink as they seem to use the session id which will be invalid in an email.

I would very much appreciate if somebody could help me with this.

Regards,
Byurhan

Luke said...

Sorry I made a mistake. Instead of <f:attribute name="attributeName1" value="attributeValue1" />
It should be <f:attribute name="attributeName1" value="#{irl}" />
Thank you.

dmanohar said...

Excellent article
so handy to refer

chandra shekar yeruva said...

hi Baluc can you please let me know how to pass value in input hidden.
My scenario as folllows..
I am getting some additional inforamtion from request and i need to get that info from request and need to pass to a bean to refer somewhere.how can i do that one.

h:inputHidden id="hidden value 1" value = "value got from servlet request."

how can i set the value "value got from servlet request" to a bean property.?

Can anyone help me on this I am a new guy to JSF.

calfred56 said...

Hi,

Great site. I've been able to use the posts on storing/accessing user objects in the various Faces contexts.

I have a JSF prototype application that is deployed in Tomcat 5.5. When using a browser that supports tabs connects to this application on more than one tab, I'm finding that the tabs seem to share a common JSF Session.

Is there a way to force different tabs to use different sessions?

If not, is there a technique for tracking when the user switches between browser tabs?

Thanks,
Charlie

Bauke said...

There is not.

To solve your problem, keep the data in question request scoped instead of session scoped. You can use h:inputHidden or requestMap to transfer data from request to request.

calfred56 said...

Thanks. I was afraid that was going the be answer :-)

Irina said...

I have application that displays customer data in the table form. I don’t know the data structure in advance, so I came up with the following architecture:

I have report.jsp page that include reporttable.jsp or custom reportable.jsp

report.jsp
...
<f:subview id="invTable">
<jsp:include page="#{reportBean.tableJsp}"/>
</f:subview>
...


tableJsp string is pointed to /reporttable.jsp or /customer1/reporttable.jsp depending on the customer needs.

reporttable.jsp
...
<h:dataTable id="tableData" value="#{reportBean.reportData}" var="rpt" >
<c:forEach items="#{reportBean.columnNames}" var="name">
<h:column>
<f:facet name="header">
<h:outputText value="#{name}" />
</f:facet>
<h:outputText value="#{rpt[name]}"/>
</h:column>
</c:forEach>
</h:dataTable>
...


For the customer that need something different I create customer1Bean that will return customized reportDate

/customer1/reportable.jsp
It maybe different from the generic jsp, but also can be almost the same except the bean it calls
...
<h:dataTable id="tableData" value="#{customer1Bean.reportData}" var="rpt" >
...

I am wondering, if there is a way to call correct bean dynamically, so I don’t have to duplicate pages if they are the same.

I would appreciate any suggestions.
Irina.

calfred56 said...

Hi Irina,

Is it possible to have your list beans implement a common Java interface? Especially one that can support generic methods like:

Object getValue(String name) and
void setValue(String name, Object value)?

If so, it might be possible to stash the field (column) names in hidden inputs, and pass the values in as the 'name' argument.

I haven't actually tried this, but it seems like it has the potential to work.

Charlie

Raja Nagendra Kumar said...

This is Awsome knowlege on JSF.. Your insites into jsf programing is great..

Regards,
Raja Nagendra Kumar,
C.T.O
www.tejasoft.com

f0rsa said...

Hi first thanks for article..

Do you have any idea how to pass an h:inputText value as an attributes.I have try lots of thing but I couldn't manage .

Manoj said...

Thanks Balu,

I am facing one problem i am using ui:param tag when i included same jspx page in two diffrent jspx i am passing two diffrent parameters using ui:param , but problem is its always taking the first page parameters. its not taking the new parameters.

Roshan said...

This is the best article out of all articles i have seen.The information you provided is just like a guide for me in my JSF project.Thank u it's simply superb Balu.

Tom Dong said...

This is a very useful article. Thank you!

All said...

Passing new hidden values to backing beans: you have passed hardcoded value i want to pass the value which is set from javascript into a hidden field and also i dont want to use command button

BalusC said...

@All: also not a commandLink? Then look for an Ajaxical solution. The value must be sent to the server side anyhow.

All said...

what I am doin is when a row is clicked. I call javascript function and set index of the row in hidden field h:inputHidden (I refered your code for UsingDataTables : HighlightRowsOnClick for this )
I have a commandlink on my page when a commandLink is clicked I call action in the action I want this index value which is now in Hidden Field on my JSF . Please can you tell me how to do that?

All said...

I have a Datatable. what I am doin is when a row is clicked. I call javascript function and set index of the clcicked row in hidden field h:inputHidden (I refered your code for UsingDataTables : HighlightRowsOnClick for this )
I have a commandlink on my page when a commandLink is clicked I call action.In the action I want this index value which is now in Hidden Field on my JSF . Please can you tell me how to retrieve the hidden field value to my backing bean?

Ravi said...

Hi Balu,
Thank you very much for the JSF information that you have given us. It is very helpful.
I have small problem here, when I used the sessionmap to store my data in the session, for every request the size of the session variable is increasing tough I am using .remove method to remove vales from map. Can you suggest me the best way to store the objects in a session variable and which do not increase for every request.

Once again thanks for the article.

chamika deshan said...

Your articles are very helpful. Thank you very much!

munawar said...

Its informative article about JSF.
Thanks
Roshu

wei said...

thanks it is very practical.I had a question on "Passing GET Parameters From JSF To Backing Beans":
I had tried your method.there still is a limitation:
the backing bean being injected must be in a request scope
now the problem is: the backing bean's scope is "none",which is managed by another bean;and the backing bean is developeed by the third party,so I can give it a value using
"FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap() "( I can't change the backing bean's source code)
is there another way?

BalusC said...

Create your own request scoped bean and make the bean with the 'none' scope a managed property of the request scoped bean. See 'Injecting beans in each other' section. Inside your own request scoped bean decorate (wrap) the setters of the bean with the 'none' scope.

wei said...

it is an good idea,and I wrap the none bean inside request bean and set setter to evaluate it.and make a configration in faces-config.xml.BUT the ONLY PROBLEM is:the request bean never got chance been invoked.so never send the value to the none bean before it is used!so the only way is still changed the code in none bean!but it is not editable if developed by third party.if you had email,i will send you and example by eclipse.thanks anyway.

Goethe-Ist-Taoist said...

Thanks for u great job. i have tried out: Passing GET parameters from JSF to backing beans

And this may have side effects, if
have more similar Backing-Beans for one page.
i.e: MyBean1 and MyBean2 may have the same structure.
GET-Parameters will be assigned to both beans, one of which may not wanted.

chirayu said...

hi ,
It is very great article to read. got my all answers from it. thanks fro it.

Varsha said...

I am running into a strange kind of problem with jsf. I have a web application has a main page, other jsf pages say page 1, page 2 and so on. Now from main page I go to Page 1, on page 1 there are some dynamically generated records and I can select any of those to go to Page 2.Page 2 has input text boxes showing the details of the selected record which can be changed. From Page 2 I can click a link to return to the main page. Now when I go to page 1 and then select any other record it shows me the value of the previously selected record in the text box of Page 2. On page 2 I have if I capture this using the outputText I get the values of the currently selected record from the bean. Looks like get method is not being called for the input text box. Any help on this would be greatly appreciated.

Raams said...

A good article.
I have one superclass and multiple subclasses. Superclass and subclasses are managed beans.
Super class has few variables.
In my JSF I called superclass bean to get the values for the components. Based on user action I will call any one of the subclass bean. I got a NULL POINTER EXCEPTION while accessing a variable which is declared in super class because both managed bean altogether is different.
But how can I access the value which is assigend to a super class bean variable from sub class bean?

Code:
Super class:
public class GrantingBaseAction{
protected SLEGeographyValue grantingGeographyValue = new SLEGeographyValue();
protected GrantingGeographyCriteriaValue geographyCriteriaValue = new GrantingGeographyCriteriaValue();

public SLEGeographyValue getGrantingGeographyValue() {
return grantingGeographyValue;
}

public void setGrantingGeographyValue(SLEGeographyValue grantingGeographyValue) {
this.grantingGeographyValue = grantingGeographyValue;
}
public GrantingGeographyCriteriaValue getGeographyCriteriaValue() {
return geographyCriteriaValue;
}

public void setGeographyCriteriaValue(
GrantingGeographyCriteriaValue geographyCriteriaValue) {
this.geographyCriteriaValue = geographyCriteriaValue;
}
}

Subclass
--------
public class GrantingMNCAction extends GrantingBaseAction {
public String globalExpand() throws Exception {
for (SLEMarketValue marketValue : grantingGeographyValue.getMarketList()) {
//Somoe action

}

return null;
}

In this class while accessing grantingGeographyValue, i received Nullpointer Exception.

How to resolve this?

BalusC said...

You declared them as two separate beans, did you? That's not the way how super/subclassing works.

Just inject the one bean in the other as managed property.

Raams said...

I declared them as two separate beans. But how can I use the property of first bean from second bean? (Since the property is also accessed from sub class bean.

BalusC said...

Read the "Injecting managed beans in each other", "Accessing another managed bean" and/or "Returning current managed bean instance of self" parts of this article.

It's a huge misunderstanding that an instance of a certain subclass would "automagically" be merged with a random instance of its superclass. That's not how Java works.

Atul Singhal said...

Thanks Baluc for this article. It really helped in our development.

I am facing one problem while developing the web application in JSF and not getting the solution how to handle it.

Problem Description:

1. Each web page is divided in two parts left navigation and content.
2. In the left navigation we have links which are linked to the content pages.
3. Those content pages containing some sort of form having some input text fields
4. Now, user clicked on, say Link1 in the left navigation linked "xhtml page" is openend in the content area and now user input some values in the text field and clicked on other link "say Link2" then how to populate popup having choice either move or cancel. if move then the Link2 page should get displayed else will remain on the same page.

can you please provide some workaround of this?

Thanks in advance.

BalusC said...

This goes beyond the scope of JSF. You need to control it at the client side. Javascript is suitable for this. Best what you can do is to make use of the onbeforeunload event. Most recent webbrowsers expect of Opera supports it.

Are You Special Out Here said...

hi BalusC , really a nice job , thaks for nice and informative articles

I am very new to JSF working in JDevloper IDE.

I want to access some value passed to JSF page as query string in its back bean class

my URL is like this for calling JSF page form some html pg is somewhat like this "http://127.0.0.1:7101/m-CA-ViewController-context-root/faces/BMsg.jspx?recID=12"

I want to access it my back bean mthd I am doing it as ..
but it always return a null value

public class BMsg {

// ....

public String retRecID()
throws IOException {
ExternalContext ectx = FacesContext.getCurrentInstance().getExternalContext();
HttpServletRequest req=(HttpServletRequest)ectx.getRequest();
String s=req.getParameter("recID");

return s;

}

}

can u please make me correct or suggest me anything , thanks in advance..

BalusC said...

This bit is already explained here: Passing GET parameters from JSF to backing beans. Good luck.

Mr President said...

This is really great stuff. Extremely thorough. Thanks for sharing!

milos said...

This is so classy!
thank you

Mirco Attocchi said...

Thanks!!

andy said...

I was struggling to find how to do all this !!! thnx !

srinivas said...

Hi, thanks for giving this information about JSF , and i want some code to transfor data or attributes between one JSF page to another JSF page that means if i entered any value(in inputText) in one JSF page,that value should display in the second JSF page, can u please help me

BalusC said...

Use a managed bean.

srinivas said...

hi, thanks for giving this information, and i want some code, if i enter any value in one JSF page that must be displayed in second JSF page with out using the bean, can any one please help me

BalusC said...

If you don't want to use a managed bean, then why JSF? Go for plain vanilla JSP/Servlet if you don't want to use beans.

Jaimico said...

Hello BalusC:

Excelent article, thanks!!

In a response to another comment you wrote: Apparently bean2 is request scoped and the getter of its propertyValue1 returns null in the next request. Either put it in the session scope or use h:inputHidden to retain this value for the next request

I tried that and it works when going from page1 to page2 (which also have the hidden inputs), but while going to page2 to page3 I get the following error:

javax.el.PropertyNotFoundException: Target Unreachable, 'concesion' returned null

(concesion is an atribute of the request managed bean, it is an object -kind of big- and I have the converter for it)

Is it recommended to pass the object in hidden fields?, if so, can you point me to a good tutorial or best practices lectures for passing entire objects from request to request?

In another response you recommended to use RequestMap, is in my case also recommended? Because I feel that using it can cause me problems of loading incorrect objects if the user clicks de back browser button.

Thanks in advance!!!! :)

BalusC said...

Instead of h:inputHidden you can also use Tomahawk's t:saveState. This component doesn't require a converter for non-standard types. You can even cache complete beans for the next request.

Jaimico said...

Thanks for your help BalausC, it worked perfectly...

I had some problems because objects needed to be serialized... and some objects contain ImpuStream's, but following instructions on this page (http://oreilly.com/catalog/javarmi/chapter/ch10.html) helped me to solve it.

But I ended up with havy posts and Glassfish complaining of "Post too large", I found that adding %<property name="maxPostSize" value="...."/> to the domain.xml (inside http-service) could solve the problem... but I dont know if it's recommended to send too large post (some of my objects have pdf files).

Perhaps I should use the RequestMap, does it last only for one request or do I have to use something else?

Thanks!!!

BalusC said...

Ouch, InputStreams .. I'd rather to keep them where they belong (filesystem or database) and use some ID to associate with them so that it can be re-retrieved again.

Jaimico said...

You're right BalusC, I'll keep them on Data Base and retrieve them only when needed =P.

Thank you very much for your help!!!! I'll be keeping an eye on your blogs.

TC Flyers said...

coooooooooooooool, wonderful article, I really appreciate this work.
Bravo

Thomas said...

Thanks for great article!

manas said...

Hi BalusC,

Is there a way to call Bean method through outputlink in JSF

Cheers,
manas

BalusC said...

The constructor and -if any- the managed property setter will be invoked. Just make use of it.

Phil said...

Passing objects from request to request

If you have a request scoped managed bean and you want to reuse a property, parameter and/or object for the next request, without reinitializing it again and again, then just use the h:inputhidden tag to save the object in it. Here is a basic JSF example:


Great Page BalusC..

I have a question. I want to put the whole request bean back into the request. I see that I can use a hidden field on the JSP page for one field but what about the whole bean?

I am using a request bean to hold the search parms that loads the bean. This works great.

The problem is when I use the rich:datascroller for the next page.
It goes back to the bean and the request scope bean is empty. This holds the search values.

How do I put this back into the request after each process??

Thanks
Phil

BalusC said...

Use a4j:keepAlive.

Phil said...

Works Great !!!!

a4j:keepAlive beanName = "SearchFormBean"/


Thanks again this will help keep memory requirements down with less session beans. Also it works correctly..!!


Thanks
Phil

ipapag said...

Thanks, this was so helpful!

Marcel said...

Great article and blog.
I'm just starting to learn JSF and I was wondering if you can provide a little advice.

I want to create a component that will present a bunch of different images that would need to be provided to the component as inputs along with some presentation configuration attributes (what transitions to apply, transition durations, etc).

Would the standard approach to do this be:

i:imageComponent imageUrls="http://imageUrl1,http://imageUrl2" etc

or

i: imageComponent
i: image url="http://imageUrl1" width="480" height="320"
i: image url="http://imageUrl2"
i: imageComponent

The second approach seems more flexible but in my case it's the imageComponent that would do all the rendering work so I'm just looking for the standard way to pass in a list of inputs to a component. I hope you can understand this without the tags - they don't seem to be allowed in comments

BalusC said...

Create a bean representing the image details. Have a List of beans, use t:dataList to iterate over it and apply the bean properties on the h:graphicImage.

pìsmíkrøp said...

excellent solution. thanks a lot.

பார்த்தசாரதி செல்லதுரை said...

very useful information relate to JSF r there. This is very useful for me.

Jalead said...

Thanks for sharing such great information about JSF.

I found it very useful. It really helped to get the most out of the topic.

Cheers!

Waheed said...

Its very good article

my question is that i not found this class,
import net.balusc.util.FacesUtil;

it syor ownclass or its a jsf class?

Trevor said...

I'm working on master-detail pages in a JSF 1.1 portal environment and just figured out a variation of "Passing GET parameters from JSF to backing beans" that I thought I'd share.

The code under "Passing GET parameters from JSF to backing beans" didn't work for me. I think the reason is because the JSF navigation handler is always doing a redirect. Replacing or reconfiguring the navigation handler was not an option, nor was upgrading to JSF 1.2 or 2.0.

The solution I came up with was to create a class called ParameterHelper with an action handler called 'forward'. When this executes it grabs all the parameters from the request and sets them on the next request, effectively getting around the problem of parameters existing when the form submit is processed, but disappearing by the time the next page loads.

The code for this is:

import java.util.Iterator;
import java.util.Map;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.portlet.ActionResponse;

public class ParameterHelper
{
public void forward(ActionEvent event)
{
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
Map parameters = context.getRequestParameterMap();
ActionResponse response = (ActionResponse) context.getResponse();

for (Iterator iter = parameters.keySet().iterator(); iter.hasNext(); )
{
String name = (String) iter.next();
Object value = parameters.get(name);

if (value != null)
{
response.setRenderParameter(name, value.toString());
}
}
}
}

The backing bean has its properties set in the same way as described in "Passing GET parameters from JSF to backing beans" by using the #{param.parameterName1} syntax.

The only addition is that the h:commandLink must have an 'actionListener' attribute which points to the 'forward' method of the ParameterHelper class.

<h:commandLink action="edit" value="Edit" actionListener="#{parameters.forward}">
<f:param name="id" value="#{row['id']}" />
</h:commandLink>

With this solution, master-detail pages can be created under JSF 1.1 without putting backing beans in session scope. Hope this helps someone.

Rammy said...

Thanks for the great article. this was the most referred article by me for JSF.

Currently im having trouble passing the EL as value in "f:attribute "

e.g: f:attribute name="testName" value="#{bean.attr}"

im getting null from event.getComponent().getAttributes().get("testName");

If facelets tag is compile time is there any other way of acheiving this. Any Ideas?

BalusC said...

Then its getter didn't return the desired value at the desired moment.

Philip said...

Hi BalusC,

Would you know if is possible to retrieve the current id of a component from a deferred el expression.

[a4j:commandButton]

[h:inputHidden value="#{testAction.saveId( somehowgetIDOfParentComponent )}" /]

[/a4j:commandButton]

in the above example I am looking for the id of the a4j:commandButton.

KaBoZ said...

in jsf 1.1, I'm handling the required and conversion errors automatically and overriding the messages for required and conversion errors in a .properties file, however, I want to display the name of the field that generated the error in the error message, I tried using the {0} but searching the internet I found it's not possible with jsf 1.1 , any advice on how to accomplish this when forced to use jsf 1.1 ?

KaBoZ said...

thank you in advance and sorry it's a little off-topic

vishnu.bola said...

Hi BalusC,

Thanks very much for this wonderful article
I have a question regarding managed property. I have a managed property called accountID(int) which i set in my faces-config.xml . but when i access it in my backing bean it gives me zero. Not sure where i have gone wrong. My URL : http://localhost:8080/for/adminbean.jsp?accountID=123

Here is my code:

In my backing Bean i want to load adminbean object and display its details on screen. Since the loading can happen only after the bean construction i have a lazy loading in the bean getter method
public class AdminController {


private Integer accountID;
private AdminBean adminbean;
public AdminController (){


}

public Integer getAccountID(){
return accountID;
}

public void setAccountID(Integer accountID) {
this.accountID = accountID;
}

//Load the admin bean
public AdminBean getAdminbean(){
if(adminbean==null){
try {
loadAdminBeanInfo();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

return this.adminbean;
return accountID;
}

public void setAdminbean(AdminBean adminbean) {
this.adminbean = adminbean;
}


public void loadAdminBeanInfo(){

System.out.println("Account data"+this.getAccountID());

}




}


So in the load if i print accountID it gives me zero instead of 123. Please advise.

Thank you

BalusC said...

You already have posted the question at the sun forum before.

Tamás said...

Hi BalusC,

This page is an excellent guide, thanks for that.

I'd like to ask you a question:
I'm developing an application using Icefaces on Liferay. I have one controller bean in request scope, and a few managedbeans registered in session scope. I have two pages. One creates a list, following a link from that list another page opens containing detailed data. My problem happens when the second page opens: sometimes (it's non-deterministic for me now) the values get re-set after the page opens correctly. Sometimes they don't get re-set, and then it's fine. This holds true only for the selectOneMenu or selectOneRadio elements. The selected values of these are set correctly at first, but then they are re-set to default. This re-setting can even be seen on the page in case of the radio list. Input boxes work just fine.

Do you have any idea what could be causing this? I already tried different icefaces versions (1.7.0, 1.8.2), tried to replace the value="#.." with binding="#.." - no luck so far. Also, I couldn't really find relevant threads in other forums.

Thanks in advance.

chuong said...

@BalusC: I used your context.getApplication().evaluateExpressionGet but I got this error: class file for javax.el.ELException not found. I have Tomcat 6.0.20 and Mojarra JSF 1.2_13-b01-FCS. What class am I missing?

MRUTTUNJAYA said...

Thanks a lot for ur article ,, thank you very much

Jose said...

Hi,

I am going to introduce my code,














































and it does not work. On Luke said (April 1, 2008 7:14 AM) I know I have to pass the value of the inputText tag instead of its id, but anyway it does not work.

What is going on?

Thanks for your greatfull blog.

Jose said...

Here is my code. I do not know what was wrong.

This is my idea: for the inputtext tags I pass the values of a Customer that is a property of the backing bean
The method details lists the properties of Customer. And what I need is to get in the commandButton tag update
those values even if some of them are new values.

((h:form))
((h:panelGrid columns="2" bgcolor="#eff5fa"))

((h:outputLabel value="Customer ID:"/))
((h:inputText id="customerId" value="#{customer.details.customerId}" disabled="true"/))
((h:outputLabel value="Customer Name:"/))
((h:inputText id="customerName" value="#{customer.details.name}"/))
((h:outputLabel value="Credit Limit:"/))
((h:inputText id="creditLimit" value="#{customer.details.creditLimit}"/))
((h:outputLabel value="Discount Code"/))
((h:selectOneMenu id="discountCode" value="#{customer.details.discount}"))
((f:selectItems value="#{customer.discountCodes}"/))
((/h:selectOneMenu))((h:outputLabel value="Email:"/))((h:inputText id="email" value="#{customer.details.email}"/))((h:outputLabel value="Phone:"/))((h:inputText id="phone" value="#{customer.details.phone}"/))((h:outputLabel value="Fax:"/))((h:inputText id="fax" value="#{customer.details.fax}"/))
((h:outputLabel value="Address (Line 1):"/))
((h:inputText id="address1" value="#{customer.details.addressline1}"/))((h:outputLabel value="Address (Line 2):"/))
((h:inputText id="address2" value="#{customer.details.addressline2}"/))((h:outputLabel value="State:"/))((h:inputText id="state" value="#{customer.details.state}"/))((h:outputLabel value="City:"/))((h:inputText id="city" value="#{customer.details.city}"/))((h:outputLabel value="Zip:"/>
((h:inputText id="zip" value="#{customer.details.zip.zipCode}"/))((/h:panelGrid))
((h:commandButton id="back" value="Back" action="#{customer.list}"/))
((h:commandButton id="update" value="Update" actionListener="#{customer.update}"))
((f:attribute name="attName" value="#{customer.details.name}" /))
((f:attribute name="attCreditLimit" value="#{customer.details.creditLimit}" /))
((f:attribute name="attDiscountCode" value="#{customer.details.discountCode.discountCode}" /))
((f:attribute name="attEmail" value="#{customer.details.email}" /))
((f:attribute name="attPhone" value="#{customer.details.phone}" /))
((f:attribute name="attFax" value="#{customer.details.fax}" /))
((f:attribute name="attAddressline1" value="#{customer.details.addressline1}" /))
((f:attribute name="attAddressline2" value="#{customer.details.addressline2}" /))
((f:attribute name="attState" value="#{customer.details.state}" /))
((f:attribute name="attCity" value="#{customer.details.city}" /))
((f:attribute name="attZip" value="#{customer.details.zip.zipCode}" /))
((/h:commandButton))
((/h:form))


Thanks in advance

manas said...

Hi,

How to know javascript enabled or not on server side on pagerefresh in JSF?

Cheers,
Manas

phoenic said...

Thank u very much BalusC C:

sandip said...

When onbeforeunload fires I am opening confirmation popup to ask user if he want to navigate to other page.
If user click 'ok', hidden field hdnUserSelection assigned a value 'yes'.
If user click 'cancel', hidden field hdnUserSelection assigned a value 'no'.


In filter I am doing
String userselection = request.getParameter('hdnUserSelection');

Here for userselection, I am always getting null.

Can you please help ?

Abhishek Dhote said...

Hi BalusC, Thanks for the useful tutorial on JSF, it helps me a lot!

Abhishek Dhote said...

Hi Balusc, I wanna use f:param with h:commandButton. I read your atricle about f:param with h:commandButton but I cannot use the same, so can you help?
Regards,
Abhi

BalusC said...

As stated in the article, use f:attribute.

Abhishek Dhote said...

Thanks for the prompt response!
Actully my problem is on the button click on want the url like shown below:

http://localhost/MyPage.jsf?paramName=paramValue

is there any way we can achieve this!

BalusC said...

Use CSS to make link look like a button.

Jigar said...

Hey,
i want to handle an event when context gets initilized,

so i have


import javax.faces.context.FacesContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyApplicationContextListener implements ServletContextListener {


DataBean var;

public MyApplicationContextListener() {
}

public DataBean getVar() {
return var;
}

public void setVar(DataBean var) {
this.var = var;
}

public void contextInitialized(ServletContextEvent event) {
System.out.println("contextInitialized >>>>>>>>>>>>>>>>>>>"+ var);
System.out.println("" + findBean("bookBean", DataBean.class));
}

public void contextDestroyed(ServletContextEvent event) {
System.out.println("contextDestroyed >>>>>>>>>>>>>>>>>>>>>>>");
}

public static T findBean(String managedBeanName, Class beanClass) {
FacesContext context = FacesContext.getCurrentInstance();
return beanClass.cast(context.getApplication().evaluateExpressionGet(context, "#{" + managedBeanName + "}", beanClass));
}
}











PhaseTracker




bookBean
DataBean
session


myApplicationContextListener
MyApplicationContextListener
application

var
#{bookBean}






but @ initilization of context in
context initilied method i am getting 'var' as null

BalusC said...

Create bean yourself and put it in application scope.

crazeesheng said...

Thanks BalusC!!!
For all the efforts!

Martín Agüero said...

Hi BalusC

You should write and publish a book about all these JSF knowledge. Is really the most comprehensive and accurate Java/JSF information source.

Thanks.

Martin

Picanha said...

Thanks. Well written, organized, and very very useful.

Cheers!

petar said...

This became a reference sheet for me each time I forget details. Please never delete it.

Thanks for putting this together with simple and sufficient examples.

Petar

BiBoN said...

Great article! Thanks!!

Taysay said...

BalusC you are simply a blessing. Tanx for your invaluable gift . May God crown your every effort with absolute success.

mervet said...

hi,
i need to communicate managed beans but i must do it in JSF 2.0.

I like your way to injecting managed beans in each other using faces-config.xml

but

is it appropriate to use a faces-config.xml?

can you advise an other smart way without using facesContext, i hate it.

thanks for any respond

BalusC said...

@mervet, use @ManagedProperty annotation.

See also bottom of this stackoverflow answer for an overview how to convert faces-config to the new JSF 2.0 annotations.

Thomas said...

Wonderful article and it has come in very handy, in fact all of your writings are bookmarked on most of our developers browsers. I am using sessionMap to keep variables that are needed from request to request and then clearing when done. We were using processScope when we used ADF which was simple because in your pages you could reference #{ProcessScope.variable} for both input and output but we are trying to move away from ADF. Is there a simple way to display the value of a specific entity in the session map on a JSF page without having to create a method in the managedBean to drill down into FacesContext?

BalusC said...

Just referencing the session map key in EL like #{key} ought to be sufficient. If you however want to explicitly reference in the session scope because you've another object on the same key in the request scope (the search order for EL is request-session-application), then use`#{sessionScope.key}.

Thomas said...

Thanks and keep up the good work!

Livio said...

Hi BalusC, I need a suggestion.
I made a page reachable via a url having in the query string the ID of the product to show. The backing bean has properties whose getter method uses the product ID to read the db. In the page there is a form to place an order and when I submit it, the view is restored but the product ID is null and the getter methods fail. This happen even if I save the bean in view scope. Why? Isn't the same view? It works fine only if I save the bean in session scope. But here I need a suggestion on how to clear the session of unused beans...

BalusC said...

@Livio: use <f:viewParam>. Assuming that you have an URL like product.jsf?id=123 and a managed bean "Products" with a property "id" (with setter), then add the following to the view to set it from the param:

<f:metadata>
    <f:viewParam name="id" value="#{products.id}" />
</f:metadata>

You can then do the database action in a @PostConstruct method.

@PostConstruct
public void init() {
product = productDAO.find(id);
}

Brian said...

Excellent information, it just saved me a whole bunch of time and frustration!

Tomás García said...

Hey BalusC, small world this one :) This morning on stackOverflow, now here :D

Nice article, quite complete and helpful!

Thanks again!

Almir Campos (Zona8) said...

Very nice article! It helped me so much!

pixelstix said...

Regards,

"Passing action parameters from JSF to backing beans

f:setPropertyActionListener: with the h:commandLink and h:commandButton tags you can trigger a method of the backing bean using the action or the actionListener attribute."

An empirical test (under JSF 1.2) shows the order of events on postback is:

1. Call h:commandButton's actionListener
2. Call the f:setPropertyActionListener bean set methods
3. Call the h:commandButton's action

This means that f:setPropertyActionListener is really only useful with action.

Regards!

valsaraj said...

Simply great!

zeeshanakhter2009 said...

That's Awesome try
nice to see so helpful data from there...
May Allah bless u

Marcoaam said...

Great article! Helped me a great deal in the question of passing parameters to "Rendered" attribute, in JSF 1.2. Thanks to frosted, for having asked it in the first place, and to BalusC for the response and the great article.

Bryan said...

It seems that instead of using an f:attribute tag you can just add the attribute to the action. For example:

<h:commandLink attributeName1="attributeValue1"<

Is this a new feature, or are there drawbacks to using this?

Bauke Scholtz said...

@Bryan: this construct didn't work in JSF 1.x on JSP, where this article is based on. By the way, if you're using JSF 2.x, I recommend reading Communication in JSF 2.0 instead.

Venugopal Sathyanarayanan said...

Hi balusc,

I am using jsf 1.2. I want to map the get request params passed through the url directly to my managed bean properties. In the get params section of this blog you have mentioned about passing get params through URL. But i would like to know how it will get mapped to the corresponding managed bean.

Thanks,
Venu

Venugopal Sathyanarayanan said...

One more thing my url will be in the following format:

https://example.com/mypage.xhtml?parameterName1=parameterValue1&parameterName2=parameterValue2

Venugopal Sathyanarayanan said...

Hi BalusC,

Could you give me an example for getting the url parameters using phase listener and passing the parameters to the managed bean. Please guide me in this regard.

Sebastián Marichal said...

Hi BalusC, i-m trying to make a SecurityFilter to perform ACL checks.

My first attempt was to use a
PhaseListener in RENDER_RESPONSE Phase and an FunctionalityID in each .xhtml like this:



In my PhaseListener i get this value from the viewRoot:

String idFunctionality = facesContext.getViewRoot().getAttributes().get("idFunct");

if(!doACL(idFunctionality)){
//Redirect
try {
response.sendRedirect("/paginas/ErrorSecurity.faces");
} catch (IOException e) {
e.printStackTrace();
}
}


That worked fine but in some point it started to giving to me problems when performing redirection and always throwing this exception:

Exception when handling error trying to reset the response.: java.lang.IllegalStateException
at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:436) [jbossweb-7.0.13.Final.jar:]
at javax.servlet.http.HttpServletResponseWrapper.sendRedirect(HttpServletResponseWrapper.java:170) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
at org.jboss.weld.servlet.ConversationPropagationFilter$1.sendRedirect(ConversationPropagationFilter.java:83) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
....
...


So i decided to implement a filter instead of a PhaseListener, but my main problem is that i cannot access to FacesContext to get my idFunct from the view root. I saw your warning about the abuse of the method described to access FacesContext, so i'm not sure if it is a good idea to put that code in my ACL Filter.

Do you know what is going on wrong in my PhaseListener when i try to redirect?

Do you have any idea to implement ACL in this context? I think that another approach can be use a filter and just get the url from the request and map the path string to a idfunct, but i need to include an extra table in my BD... what do you think?

Thanks you!!!

Sebastián Marichal said...

Well i managed to resolve one of the issues, the exception when redirecting :


That worked fine but in some point it started to giving to me problems when performing redirection and always throwing this exception:

Exception when handling error trying to reset the response.: java.lang.IllegalStateException
at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:436) [jbossweb-7.0.13.Final.jar:]
at javax.servlet.http.HttpServletResponseWrapper.sendRedirect(HttpServletResponseWrapper.java:170) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
at org.jboss.weld.servlet.ConversationPropagationFilter$1.sendRedirect(ConversationPropagationFilter.java:83) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
....

i put a return; immediately of the redirect and that fixed the problem in both cases (PhaseListener and Filter).

So my question now goes in a theoretical way, which is the best approach for the ACL check? PhaseListener or ServletFilter? If i choose ServletFilter i can't access to the idFunct attribute in the view root, but i read somewhere that the most appropriate way is to use a filter to to ACL checks instead of a PhaseListener.

Regards!

Sebastián Marichal said...

Hi guys, do you have some advise about my question?

Thanks!

csmatyi said...

Sometimes you have this in your code:

import net.balusc.util.FacesUtil;

Could you make this available for us?

Thanks, Matthew

Khadija Mahfoud said...

Thanks for this fine artical ; but i would be see how do i for passing the paramater the page to another page