JSF Component state Save process

JSF can save state of component tree in either session or on clients machine inform of serialized data .
While creating component tree JSF creates a key and keep all objects of component tree as UIViewRoot in session with against it.For next JSF request it will use same key to restore that view 🙂
For client side saving has performance issues like it has to serialize whole tree and write it in response ship in form of gzip to client.Next time when same client make JSF request from same page it de-serialize it and inflate all objects in corresponding state .

Setting for state saving is done in web.xml.

Server side state saving is where the component tree and all component state are stored within the user’s session. This entry within the session is tracked by writing a key in the response that is used to lookup the entry on subsequent post-backs.

Client side state saving doesn’t leverage the server side session mechanism at all, instead, the component tree and state will be serialized using Java Serialization, GZIP compressed (at least that is the default), Base64 encoded, and written to the response. When a post-back occurs, the encoding process will be reversed which will result in the tree and state we started with.

Setting in web.xml

  <context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>

Why does JSF need to save the state of UI components on the server side ?

Because HTTP is stateless and JSF is stateful. The JSF component tree is subject to dynamic (programmatic) changes. JSF simply needs to know the exact state as it was when the form had been displayed to the enduser, so that it can successfully process the whole JSF lifecycle based on the information provided by the original JSF component tree when the form has been submitted back to the server. The component tree provides information about the request parameter names, the necessary converters/validators, the bound managed bean properties and action methods.

As a logged-in user on the application navigates though pages, will the state of components keep on accumulating on the server?

Technically, that depends on the implementation. If you’re talking about page-to-page navigation (just GET requests) then Mojarra won’t save anything in session. If they are however POST requests (forms with commandlinks/buttons), then Mojarra will save state of each form in session until the max limit. This enables the enduser to open multiple forms in different browser tabs in the same session.

Or, when the state saving is set to client, then JSF won’t store anything in session. You can do that by the following context param in web.xml:

<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
</context-param>

It will then be serialized to an encrypted string in a hidden input field with the name javax.faces.ViewState of the form.

Happy learning with Vinay in techartifact

Set value in attribute in binding in Oracle ADF

Requirement – how to set value of attribute value in binding…

Solutions – you can use this expression –

JsfUtils.setExpressionValue("#{ManagedBean.empName}", "Vinay"); 

You have to add this method in JsfUtils class.

Note to call the getters and setters via your EL expression, you don’t include the get/set prefix.

 public static void setExpressionValue(String expression, Object newValue) {
    FacesContext facesContext = getFacesContext();
    Application app = facesContext.getApplication();
    ExpressionFactory elFactory = app.getExpressionFactory();
    ELContext elContext = facesContext.getELContext();
    ValueExpression valueExp = elFactory.createValueExpression(elContext, expression, Object.class);

    //Check that the input newValue can be cast to the property type
    //expected by the managed bean.
    //If the managed Bean expects a primitive we rely on Auto-Unboxing
    //I could do a more comprehensive check and conversion from the object
    //to the equivilent primitive but life is too short
    Class bindClass = valueExp.getType(elContext);
    if (bindClass.isPrimitive() || bindClass.isInstance(newValue)) {
      valueExp.setValue(elContext, newValue);
    }
  }

Happy coding in Techartifact with Vinay…

Dynamic Creation of cascading Lov in oracle ADF or model driven Lov in Oracle ADF.

Requirement – I am working on tricky requirement where i have two child component and one child LOV.How to do that?

Solution- Well if you have working knowledge of cascading LOV in then we pass bind parameter of parent LOV attribute in child LOV View Accessor(VA) . But in this scenario , we have two master LOV. then we will be doing by passing through managed bean, using Application module session .

What i have done.I have used HR schema .

I have 3 view object. one as country table of HR schema.One View object for location table.One view which have all transient attribute and consider to be main view object.

As i found this approach in Jobinesh’s blog- i write a custom method in applicationModuleImpl.java as below –

    public void setLocationIDSessionData(String locId){
          System.out.println("hello 232323&&&"+locId);
        this.getSession().getUserData().put("LocationId", locId);
        
      }

I have getUserData method of applicationModule interface which returns a java.util.Hashtable which may be used to store user specific context that is related to this application session.

Read all other method related to this
http://docs.oracle.com/cd/E12839_01/apirefs.1111/e10653/oracle/jbo/ApplicationModuleHandle.html

Ok, coming back to this requirement – I used a managed bean in backing bean scope where i executed the binding of applicationModuleImpl custom method as below –

    public void executec(String valueChangeEvent) {
    BindingContext bctx = BindingContext.getCurrent();
           BindingContainer bindings = bctx.getCurrentBindingsEntry();
           OperationBinding op =
               (OperationBinding)bindings.getOperationBinding("setLocationIDSessionData");
           op.getParamsMap().put("locId",valueChangeEvent);
           op.execute();
    }

Here we are passing the value of both LOV to locationId to custom applicationModuleImpl method.In both parent LOV , i create valuechangeEvent method , which get the current selected countryId and pass to custom applicationModuleImpl method. that is below –

    public void VC(ValueChangeEvent valueChangeEvent) {
      System.out.println("hello &&&"+valueChangeEvent.getNewValue());
      
       
        executec(valueChangeEvent.getNewValue().toString());
    }

    public void vc2(ValueChangeEvent valueChangeEvent) {
        System.out.println("hello &&&34343"+valueChangeEvent.getNewValue());
        executec(valueChangeEvent.getNewValue().toString());
    }

Now we have final task, we have to set the value of child lov bind parameter in child View Accessor as adf.userSession.userData.LocationId

That’s it.now we will run the jspx , which have all 3 lov.2 parent and one child LOV.
for displaying LOV , we need to click on create button.after click you can see all 3 LOVs.

After selecting county as CH from countryLov1 , we will see different values in location ID.

Now we will select country as IN from countryLov2 , we will see different values in location ID.

You can download the sample application here.

ModelDrivernCascadingLOVs

Happy coding with Vinay kumar in techartifact….