@ManagedProperty(value = “#{param.id}”) in a non-request Scope Bean

后端 未结 2 1292
耶瑟儿~
耶瑟儿~ 2020-12-23 10:47

I need to pass a parameter (POST) to a @managedBean, I used managed properties like this:

@ManagedProperty(value = \"#{param.id}\")
private int id;


        
相关标签:
2条回答
  • 2020-12-23 11:06

    Two ways:

    1. Make the bean request scoped and inject the view scoped one as another @ManagedProperty.

      @ManagedBean
      @RequestScoped
      public class RequestBean {
      
          @ManagedProperty(value="#{param.id}")
          private Integer id;
      
          @ManagedProperty(value="#{viewBean}")
          private ViewBean viewBean;
      }
      

      The view scoped bean is available during @PostConstruct and action methods of request scoped bean. You only need to keep in mind that the id can get lost when you do a postback to the same view without the parameter.

    2. Or, grab it manually from the request parameter map during bean's initialization.

      @ManagedBean
      @ViewScoped
      public class ViewBean {
      
          private Integer id;
      
          @PostConstruct
          public void init() {
              id = Integer.valueOf(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id"));       
          }
      }
      

      This way the initial id is available during the entire view scope.

    0 讨论(0)
  • 2020-12-23 11:08

    As an alternative to grabbing the parameters directly from the request in your bean, you can use view parameters.

    These need to be declared on the Facelet where you use your managed bean as follows:

    <html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core"
    >
        <h:body>
    
        <f:metadata>
            <f:viewParam id="id" name="id" value="#{myBean.id}" />        
        </f:metadata>
    
        <!-- Rest of Facelet here -->   
    
        </h:body>
    </html>
    

    If you now request this page, the setter of the backing bean will be called with the request value provided for the id parameter. This works for both GET and (non-faces) POST requests.

    The advantage is that you can use the standard JSF converters and validators here. Of course if your managed bean is not tied to a particular view then this solution is less ideal.

    A small peculiar thing to watch out for is that when doing a normal faces postback after the initial request that provided the view parameter, the setter in your bean will be called again, even if the bean is in view scope and no new value is explicitly provided.

    To test that this works, I've used the following managed bean:

    import javax.annotation.PostConstruct;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ViewScoped;
    import javax.faces.event.ActionEvent;
    
    @ManagedBean
    @ViewScoped
    public class MyBean {
    
        Long id;
    
        @PostConstruct
        public void test() {
            System.out.println("post construct called");
        }
    
        public void actionMethod(ActionEvent event) {       
            System.out.println("action called");        
        }
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
    }
    

    And the following Facelet:

    <html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core"
    >
        <h:body>
    
            <f:metadata>
                <f:viewParam id="id" name="id" value="#{myBean.id}" />        
            </f:metadata>
    
            <h:outputText value="#{myBean.id}"/>
    
            <h:form>
                <h:commandButton value="test" actionListener="#{myBean.actionMethod}"/>
            </h:form>
    
            <form method="post">
                <input name="id" value="4" />
                <input type="submit" value="submit" />
            </form>
    
        </h:body>
    </html>
    

    Enter a number in the input field and click the submit button. If the number is printed back on the screen the test has succeeded. Note that the second form is a regular form and does not post any JSF state along. I tested this on JBoss AS 6 and it works. Proving the id parameter as a GET parameter also works.

    0 讨论(0)
提交回复
热议问题