1 2 Previous Next 15 Replies Latest reply on Sep 24, 2012 5:09 PM by vctlzac

    How to replace @KeepAlive in RF4? @ViewScoped is not working...

    etercap

      Greetings all

       

      I need to migrate a small project to RF4 from RF 3.3.3 and have started with a small piece of code.

      I want to display a list of customers with their names rendered as links, so when the user clicks a name, it raises a popup containing a form filled with the customer data. With v3.3.3 it worked as it should, but now with v4, the popup doesn't appear and the method selectCustomer doesn't execute. It's like the bean was @RequestScoped instead of @ViewScoped. Am I missing something?

       

      Here is the relevant code:

       

      File customers.xhtml

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

      <h:form prependId="false">

           <rich:dataTable id="table" value="#{customerBean.customers}" var="customer">

                <!--...headers...-->

                <h:column>

                     <a4j:commandLink action="#{customerBean.selectCustomer(customer)}" value="#{customer.name}"

                     oncomplete="#{rich:component('popup_customer_edition)}.show();" render="form_customer_edition"/>

                </h:column>

                <h:column>${customer.address}</h:column>

           </rich:dataTable>

      </h:form>

       

      <rich:popupPanel id="popup_customer_edition" modal="true" width="400" height="240" autosized="true">

              <h:form id="form_customer_edition" prependId="false">

                   <!--...form fields...-->

              </h:form>

      </rich:popupPanel>

       

       

      File CustomerBean.java

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

      @ManagedBean

      @ViewScoped  //It was @KeepAlive before, and it worked

      public class CustomerBean

      {

           private Customer selectedCustomer;

           private String name;

           private String address;

       

           //...Getters and setters...

       

           public String selectCustomer(Customer customer)

           {

                selectedCustomer = customer;

                name = selectedCustomer.getName();

                address = selectedCustomer.getAddress();

       

                return null;

           }

      }

       

      I'm using RichFaces 4, Tomcat 7.0.11, Spring 3.0.5 and Hibernate 3.6.2

       

      Thanks in advance

        • 1. Re: How to replace @KeepAlive in RF4? @ViewScoped is not working...
          lfryc

          Hi Byron,

           

          you are using @ViewScoped correctly but though I verified on simplified sample and it works fine:

           

           

           

          <h:form prependId="false">
                    <h:dataTable value="#{richBean.list}" var="customer">
                              <h:column>
                                        <a4j:commandLink action="#{richBean.select(customer)}"
                                                  value="Name #{customer}"
                                                  oncomplete="#{rich:component('popup_customer_edition')}.show();"
                                                  render="form_customer_edition" />
                              </h:column>
                    </h:dataTable>
          </h:form>
          
          
          <rich:popupPanel id="popup_customer_edition" modal="true" width="400"
                    height="240" autosized="true">
                    <h:form id="form_customer_edition" prependId="false">
                              <h:outputText
                                        value="#{richBean.selectedCustomer} = #{richBean.number}" />
                              <a onclick="#{rich:component('popup_customer_edition')}.hide();">Hide</a>
                    </h:form>
          </rich:popupPanel>
          
          

           

           

          @ManagedBean
          @ViewScoped
          public class RichBean implements Serializable {
          
          
                    private Map<String, Integer> numbers = new HashMap<String, Integer>() {
                              public Integer get(Object key) {
                                        if (!super.containsKey(key)) {
                                                  return 0;
                                        }
                                        return super.get(key);
                              }
                    };
          
                    private String selectedCustomer;
          
                    public String select(String customer) {
                              selectedCustomer = customer;
                              increment();
                              return null;
                    }
          
                    public void increment() {
                              int number = numbers.get(selectedCustomer);
                              numbers.put(selectedCustomer, number + 1);
                    }
          
                    public String getSelectedCustomer() {
                              return selectedCustomer;
                    }
          
                    public int getNumber() {
                              return numbers.get(selectedCustomer);
                    }
          
                    public List<String> getList() {
                              return Arrays.asList(new String[] {"a", "b", "c"});
                    }
          
          
          }
          
          
          • 2. Re: How to replace @KeepAlive in RF4? @ViewScoped is not working...
            etercap

            Your sample works, but in my case the data (customer list) is being pulled from a database, like this:

             

            Rest of "CustomerBean.java"

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

            @PostConstruct

            public void init()

            {

                 /*...Perform some initialization operations...*/

                 System.out.println("Post Construct");          //To see when it executes;

            }

             

            private List<Customer> customers;

            private String searchCriteria;

             

            public void searchCustomers()

            {

                 customers = getCustomersFromDatabase(searchCriteria);

                 return null;

            }

             

            public List<Customer> getCustomers()

            {

                 return customers;

            }

             

            /*...Others getters and setters...*/

             

             

             

            Then, on file "customers.xhtml", there is a button which performs the search:

             

            <h:inputText id="search_criteria" value="#{customerBean.searchCriteria}" />

             

            <a4j:commandButton id="search" value="Search"

                 action="#{customerBean.searchCustomers}"

                 execute="search_criteria"

                 render="table_panel"/>

             

            <h:panelGroup id="table_panel">

                 <!--Table shown above-->

            </h:panelGroup>

             

             

            Data is retrieved and table is rendered with no problems. However, the first time i click on a customer name, the @PostConstruct-ed method executes again (as if the supposedly @ViewScoped bean is re-created), and the popup doesn't appear, neither the "selectCustomer" method executes.

            • 3. How to replace @KeepAlive in RF4? @ViewScoped is not working...
              codo

              Hello,

               

              I've just noticed that you  have this code:  oncomplete="#{rich:component('popup_customer_edition)}.show();", so your popup_customer_edition is not enclosed in single quotes correctly.

               

              Greetings

              • 4. How to replace @KeepAlive in RF4? @ViewScoped is not working...
                iabughosh

                Hi Byron,

                try adding (return false;) after the show() method :

                #{rich:component('popup_customer_edition')}.show();return false;

                 

                regards.

                • 5. How to replace @KeepAlive in RF4? @ViewScoped is not working...
                  etercap

                  Thanks, but that was not the problem.

                  • 6. How to replace @KeepAlive in RF4? @ViewScoped is not working...
                    raid3n

                    Me too, I have problems with ViewScoped beans and RF4 final.

                     

                    I tried the Lukas' example but it seems the richbean is not managed. I have a blank page.

                     

                    I use RF4 Final and tomcat 6.0.32/7.0.11.

                     

                    What's wrong?

                    • 7. How to replace @KeepAlive in RF4? @ViewScoped is not working...
                      raid3n

                      What jsf cdi do you use Byron?

                      • 8. Re: How to replace @KeepAlive in RF4? @ViewScoped is not working...
                        apalmeira

                        I have the same problem. When I try to open a new page using the same MB, the page doesnt show the data.

                         

                        Does anyone knows how to solve this problem?

                         

                        Tks

                        • 9. Re: How to replace @KeepAlive in RF4? @ViewScoped is not working...
                          rogerionj

                          I have the same problem. Is solved?

                          • 10. Re: How to replace @KeepAlive in RF4? @ViewScoped is not working...

                            Issues with JSF 2 view scope:

                            - bean is destroyed on navigation

                            - after navigation new view will have new instance of the bean if it is referenced there

                            - after navigation old view will have new instance of the bean too, so original page will not work as expected (navigation can happen in new window with <h:commandLink target="_blank")

                            http://stackoverflow.com/questions/4831888/does-view-scope-bean-survive-navigation-jsf

                             

                            Here is solution which allows request scope bean to:

                            - act like view scope bean on ajax requests

                            - survive navigation (like request scope bean)

                             

                            Implementation (idea is based on RichFaces 3 keep alive):

                            - bean is attached to view when it is created

                            - this bean instance is pushed back to request scope on every request when view is restored (JSF will use this instance instead of creating new one)

                             

                            1) Define bean @ManagedBean(name = "testBean") @RequestScoped

                            2) Define phase listener in faces-config.xml

                                <lifecycle>

                                    <phase-listener>test.JSFPhaseListener</phase-listener>

                                </lifecycle>

                             

                            public class JSFPhaseListener implements PhaseListener {

                             

                                private static final long serialVersionUID = -3689434283608539768L;

                             

                                public void afterPhase(PhaseEvent event) {

                                    if (PhaseId.RESTORE_VIEW.equals(event.getPhaseId())) {

                                        FacesContext facesContext = FacesContext.getCurrentInstance();

                                        Map<String, Object> map = (Map<String, Object>) facesContext.getViewRoot().getAttributes().get("keepAliveMap");

                                        if (map != null) {

                                            Map<String, Object> requestMap = facesContext.getExternalContext().getRequestMap();

                                            requestMap.putAll(map);

                                        }

                                    }

                                }

                             

                                public void beforePhase(PhaseEvent event) {

                                }

                             

                                public PhaseId getPhaseId() {

                                    return PhaseId.ANY_PHASE;

                                }

                             

                            }

                             

                            3) In bean @PostConstruct call

                                @PostConstruct

                                public void init() {

                                    Map<String, Object> viewRootAttributes = FacesContext.getCurrentInstance().getViewRoot().getAttributes();

                                    Map<String, Object> keepAliveMap = (Map<String, Object>) viewRootAttributes.get("keepAliveMap");

                                    if (keepAliveMap == null) {

                                        keepAliveMap = new HashMap<String, Object>();

                                        viewRootAttributes.put("keepAliveMap", keepAliveMap);

                                    }

                                    keepAliveMap.put("testBean", this);

                                }

                             

                            If anyone has feedback on this please let me know.

                            • 11. Re: How to replace @KeepAlive in RF4? @ViewScoped is not working...
                              vctlzac

                              Hi Nick Dev,

                               

                              I implement your code, but I have the following error:

                               

                               

                              java.lang.UnsupportedOperationException

                                        at org.apache.myfaces.context.servlet.RequestMap.putAll(RequestMap.java:72)

                                        at br.com.package.myapp.faces.common.JSFPhaseListener.afterPhase(JSFPhaseListener.java:27)

                                        at org.apache.myfaces.lifecycle.PhaseListenerManager.informPhaseListenersAfter(PhaseListenerManager.java:117)

                                        at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:185)

                                        at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)

                                        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:197)

                                        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)

                                        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)

                                        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:311)

                                        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)

                                        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)

                                        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)

                                        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)

                                        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)

                                        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:101)

                                        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)

                                        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)

                                        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)

                                        at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:146)

                                        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)

                                        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)

                                        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)

                                        at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)

                                        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)

                                        at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)

                                        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)

                                        at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:182)

                                        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)

                                        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)

                                        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)

                                        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)

                                        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)

                                        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173)

                                        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)

                                        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)

                                        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)

                                        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)

                                        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)

                                        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)

                                        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)

                                        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)

                                        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)

                                        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)

                                        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)

                                        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)

                                        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)

                                        at java.lang.Thread.run(Thread.java:662)

                              • 12. Re: How to replace @KeepAlive in RF4? @ViewScoped is not working...

                                I see you use MyFaces as JSF implementation. My solution works with JSF Mojarra 2.1.8 and RichFaces 4.2.2.Final.

                                 

                                As far as I see in MyFaces code putAll is defined as:

                                @Override
                                public void putAll(final Map<? extends String, ? extends Object> t)
                                {
                                    throw new UnsupportedOperationException();
                                }

                                 

                                Can you just try using requestMap.put in a loop?

                                • 13. Re: How to replace @KeepAlive in RF4? @ViewScoped is not working...
                                  vctlzac

                                  Method "putAll" of the MyFaces is equals that you post.

                                   

                                  What do you mean by using loop?

                                   

                                  My Class:

                                   

                                  public class JSFPhaseListener implements PhaseListener {

                                            private static final long serialVersionUID = -51179752120719421L;

                                   

                                            @Override

                                            public void afterPhase(PhaseEvent event) {

                                                      try {

                                                                if (PhaseId.RESTORE_VIEW.equals(event.getPhaseId())) {

                                                                          FacesContext facesContext = FacesContext.getCurrentInstance();

                                   

                                                                          Map<String, Object> map = (Map<String, Object>) facesContext

                                                                                              .getViewRoot().getAttributes().get("keepAliveMap");

                                   

                                                                          if (map != null) {

                                                                                    Map<String, Object> requestMap = facesContext

                                                                                                        .getExternalContext().getRequestMap();

                                   

                                                                                    requestMap.putAll(map);

                                                                          }

                                                                }

                                                      } catch (Exception e) {

                                                                e.printStackTrace();

                                                      }

                                            }

                                   

                                            @Override

                                            public void beforePhase(PhaseEvent event) {

                                                      // TODO Auto-generated method stub

                                            }

                                   

                                            @Override

                                            public PhaseId getPhaseId() {

                                                      return PhaseId.ANY_PHASE;

                                            }

                                  }

                                   

                                  BEAN:

                                   

                                  @SuppressWarnings("serial")

                                  @ManagedBean(name = "myBean")

                                  @RequestScoped

                                  public class LoteMBean implements Serializable {

                                   

                                  @PostConstruct

                                  public void init() {

                                   

                                       Map<String, Object> viewRootAttributes = FacesContext.getCurrentInstance().getViewRoot().getAttributes();

                                       Map<String, Object> keepAliveMap = (Map<String, Object>) viewRootAttributes.get("keepAliveMap");

                                   

                                       if (keepAliveMap == null) {

                                            keepAliveMap = new HashMap<String, Object>();

                                            viewRootAttributes.put("keepAliveMap", keepAliveMap);

                                        }

                                            keepAliveMap.put("myBean", this);

                                  }

                                   


                                   

                                   

                                  Thanks Nick.

                                  • 14. Re: How to replace @KeepAlive in RF4? @ViewScoped is not working...

                                    for (Map.Entry<String, Object> entry : map.entrySet()) {

                                         requestMap.put(entry.getKey(), entry.getValue());

                                    }

                                    1 2 Previous Next