Showing posts with label JSF Portlet. Show all posts
Showing posts with label JSF Portlet. Show all posts

How to reset JSF Portlets to initial state

For a JSF based portlet, if you have a scenario where a user is navigating between screens and that portlet is having 2 or 3 screens, if the user went to 3rd screen and he comes back and clicked on the link it is going to 3rd screen instead of 1st screen.

To render 1st jsp from within portlet,we specify init parameter for first jsp in portlet.xml as follows

<init-param>
    <name>com.ibm.faces.portlet.page.view</name>
    <value>/jsp/html/view/HelloView.jsp</value>
</init-param>


Now in case, when you want to reset JSF Portlets to its initial view when user comes back, set "com.ibm.faces.portlet.page.view" attributed to session.


portletSession.setAttribute("com.ibm.faces.portlet.page.view", <path of jsp to render>);

JSF portlet file upload

File upload functionality is very common to most of the portlet/web applications.
In portlet, file upload is treated a bit different than usual web application file uploads.
If it is a non-jsf portlet, you might need to use any third party file upload component like Apache commons file upload portlet.

Here I am writing steps to implement file upload functionality in JSR JSF portlet.

1) JSP code
  1.1) Declaring enctype attribute of form
        Form enctype attribute value should be set to multipart/form-data
      
 <h:form styleClass="create-listing-form" enctype="multipart/form-data">


   1.2) Component to browse file from file system
 
            <hx:fileupload id="logoUpload"
            tabindex="26">
                <hx:fileProp name="fileName" />
                <hx:fileProp name="contentType" />                              
            </hx:fileupload>  

2) JSF managed bean code
   
protected HtmlFileupload logoUpload;  // declare this as instance variable
  
    2.1) Method to get HtmlFileUpload object for the uploaded file
  
        protected HtmlFileupload getLogoUpload() {
              
            if (logoUpload != null) {
               logoUpload = (HtmlFileupload) findComponentInRoot("logoUpload");
             }
                return logoUpload;  
        }
  
 2.2) UploadFile method to get file bytestream and process it further to store in DB or onto file system as per the requirement.
  
         public void uploadFile(){
      
       ContentElement content = (ContentElement) getLogoUpload().getValue();
               

         if(content!=null){
               

// further validation can be applied with the help of ContentElement object to check type of file(image,text,doc) or maximum upload size to be allowed
                  
              ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(content.getContentValue());
                   

// convert to inputStream to set as BinaryStream to CallableStatement object


                    InputStream inputStream = byteArrayInputStream;
              
                    // writing to another file on the file system
                  
                    File outputFilename = new File(<FilePath>);
    
                    BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(<OutputFilename>));
                    int data;
                    while((data=byteArrayInputStream.read())!=-1) {
                        char ch = (char)data;
                        bufferedOutputStream.write(ch);
                    }
          
                    bufferedOutputStream.flush();
                    bufferedOutputStream.close();
                    byteArrayInputStream.close();
                    inputStream.close();
              
                }
      
         }

JSF portlet - multiple action execution

This feature is used by IBM WebSphere Portal to stop processing the same Action request twice (for example, browser Back button feature).

wps.multiple.action.execution is a portlet initialization parameter that can be set in the portlet’s deployment descriptor (that is, portlet.xml).

If this protection feature is left on (wps.multiple.action.execution=true), WebSphere Portal would treat a repeated Action URL as a Render URL with no repetition of portlet action, rather portlet would just be rendered.
This is achieved by storing executed Action results and state in a session to prevent the multiple actions.

JSF JSR portlet - calling JSF bean attribute within a JSTL tag

Recently I have expericened that when you call a JSF bean attribute from within a JSTL tag specially inside a conditional tag like <c:when... > , doesn't work at first and will not show you updated value of a bean attribute.
When you do a page refresh then jsf bean attribute updated value will be shown when invoked inside a jstl tag.

So be cautious when calling jsf bean attribute tag from within a jstl tag.

Let me explain in here with an example.

When jsf page renders, jsf backing bean getters are called. Now if any of the getter are being called from a jstl tag, then this getter will not give you updated value of bean attribute.

if you have code like this
<c:when test="${customerBean.fname}">, in this case, when your page renders, this customerBean.fname will not give you the udpated value and when you do a page refresh then this getter will display the updated value of fname.

<c:choose>
<c:when test="${customerBean.fname=='Neeraj'}">
   <c:out value="hello"/>
</c:when>
<c:otherwise>
   <c:out value="Bye"/>
</c:otherwise>
</c:choose>


Set some default value of bean attribute fname to "MyName" and on run time assign fname value to "Neeraj".

In above lines of code, with your first page render, you will find result as Bye and when do a page refresh you will see result as hello.

Solution to this kind of scenario is to use JSF panel group tag with rendered attribute as shown below.


<h:panelGroup rendered="#{customerBean.fname=='Neeraj'}">
   <c:out value="Hello">
</h:panelGroup>
<h:panelGroup rendered="#{customerBean.fname!='Neeraj'}">
   <c:out value="Bye">
</h:panelGroup>

How to change JSF JSR portlet page views

In JSF portlet( 168 or 286 portlet), the very first portlet content is rendered based on jsp path declared in init parameter in portlet.xml, as shown below...

Portlet.xml
        <init-param>
            <name>com.ibm.faces.portlet.page.view</name>
            <value>/jsp/html/MyJSFView.jsp</value>
        </init-param>
       
What if you want to render content from another jsp based on some action performed in portlet?   

JSF stores this init paramter (com.ibm.faces.portlet.page.view) value in session.
So, if you want to render your custom jsp based on action performed, change this value in session in your portlets doView method,

request.getPortletSession().setAttribute("com.ibm.faces.portlet.page.view", <path to jsp>);

Render behavior of JSF forms


I was just reading some tech notes and found this JSF portlet related information.
Very useful tech note, hope will be helpful for readers as well...