2011-01-02 4 views
17

necesito pasar un parámetro (POST) a una @managedBean, solía maneja como este:@ManagedProperty (valor = "# {param.id}") propiedades en un no-petición Alcance de la haba

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

Y el alcance del frijol es ViewScope

termino con este error:

Unable to create managed bean receipt. The following problems were found: - The scope of the object referenced by expression #{param.id}, request, is shorter than the referring managed beans scope of view

¿Qué puedo hacer yo?

arjan echar un vistazo:

Mi página: Facelet Título

<form method="post" action="faces/index.xhtml"> 
    <input name="id" value="4" /> 
    <input type="submit" value="submit" /> 
</form> 

<h:form> 
    <h:commandLink value="click" action="index"> 
    <f:param id="id" name="id" value="20"/> 
    </h:commandLink> 
</h:form> 

Respuesta

37

dos maneras:

  1. Realice la solicitud de bean con un alcance e inyecte la vista con un ámbito como otro @ManagedProperty.

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

    La vista con ámbito bean está disponible durante @PostConstruct y de acción métodos de solicitud de ámbito de frijol. Solo debe tener en cuenta que el id puede perderse cuando realiza una devolución de datos a la misma vista sin el parámetro.

  2. O bien, cógelo manualmente desde el mapa de parámetros de solicitud durante la inicialización de bean.

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

    De esta manera el inicial id se encuentra disponible durante todo el alcance vista.

+1

Gracias, ¿es la primera solución (inyectar el viewScoped bean en requestScoped) una práctica buena y popular? – ehsun7b

+0

GlassFish sirve mi aplicación y puedo usar beans CDI también, pero decidí hacer un proyecto con los beans JSF porque soy muy nuevo en JSF, ¿es una buena idea? – ehsun7b

+2

Depende del propósito del 'id'. ¿Desea "actualizarlo" en cada solicitud? Ir por el camino 1. ¿O quieres usar el valor inicial durante todo el alcance de la vista? Ir por el camino 2. – BalusC

6

Como alternativa a agarrar los parámetros directamente de la solicitud en el bean, puede utilizar view parameters.

Estos tienen que ser declarado en la Facelet en el que utiliza el bean gestionado de la siguiente manera:

<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> 

Si ahora solicita esta página, el armador del bean de respaldo será llamada con el valor de petición previsto el parámetro id. Esto funciona para las solicitudes GET y (sin caras) POST.

La ventaja es que aquí puede usar los convertidores y validadores JSF estándar. Por supuesto, si su bean administrado no está vinculado a una vista particular, esta solución es menos ideal.

Una pequeña cosa peculiar a tener en cuenta es que al hacer una devolución de caras normales después de la solicitud inicial que proporcionó el parámetro de vista, se llamará de nuevo al colocador en su bean, incluso si el bean está en alcance de vista y no nuevo valor se proporciona explícitamente.

Para probar que esto funciona, he utilizado el siguiente bean administrado:

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; 
    } 

} 

Y la siguiente 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> 

Introduzca un número en el campo de entrada y haga clic en el botón de envío . Si el número se imprime nuevamente en la pantalla, la prueba ha tenido éxito. Tenga en cuenta que el segundo formulario es un formulario regular y no publica ningún estado JSF. Probé esto en JBoss AS 6 y funciona. También funciona el probar el parámetro id como un parámetro GET.

+0

¡Oh, imaginé que esto solo funciona para GET! ¡gracias hombre! – ehsun7b

+0

No funciona para mí :( – ehsun7b

+0

Por lo que veo en los libros y tutoriales, solo funcionan para obtener parámetros, ¿está seguro de que se pueden usar con los parámetros de publicación? ... – ehsun7b

Cuestiones relacionadas