1 2 Previous Next 15 Replies Latest reply: Sep 24, 2012 5:09 PM by Victor Lippi Zaccariotto RSS

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

Byron Delgado Newbie

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...
    Lukáš Fryč Master

    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...
    Byron Delgado Newbie

    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 Newbie

    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 Master

    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...
    Byron Delgado Newbie

    Thanks, but that was not the problem.

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

    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 Newbie

    What jsf cdi do you use Byron?

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

    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...
    Rogério Napoleão Jr Newbie

    I have the same problem. Is solved?

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

    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...
    Victor Lippi Zaccariotto Newbie

    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...
    Nick Dev Newbie

    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...
    Victor Lippi Zaccariotto Newbie

    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...
    Nick Dev Newbie

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

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

    }

1 2 Previous Next