2010-04-13 19 views
90

Estoy tratando de escribir un servlet personalizado (para AJAX/JSON) en el que me gustaría hacer referencia a mi @ManagedBeans por su nombre. Estoy esperando para mapear:Obtener bean gestionado JSF por nombre en cualquier clase relacionada con Servlet

http://host/app/myBean/myProperty

a:

@ManagedBean(name="myBean") 
public class MyBean { 
    public String getMyProperty(); 
} 

¿Es posible cargar un frijol por su nombre desde un servlet regular? ¿Hay algún servlet o ayudante JSF que pueda usar?

Me parece estar mimado por Spring en el que todo esto es demasiado obvio.

+0

No estoy seguro de si puede usar estas nuevas anotaciones fuera de JSF/EL, pero comenzaría mirando la especificación JSR 299: http://jcp.org/en/jsr/detail?id=299 – McDowell

+0

Otras personas que tienen problemas con problemas similares también pueden consultar https://bpcatalog.dev.java.net/ajax/jsf-ajax/ (relacionado con AJAX y solicitar el mapeo/manejo, sin obtener frijoles por su nombre) –

Respuesta

245

en un servlet, se puede obtener petición en ámbito de las habas por:

Bean bean = (Bean) request.getAttribute("beanName"); 

y sesión en el ámbito granos por:

Bean bean = (Bean) request.getSession().getAttribute("beanName"); 

y aplicación en el ámbito granos por:

Bean bean = (Bean) getServletContext().getAttribute("beanName"); 

Si se está ejecutando en una inyección de dependencias capaz marco/envase y el grano es gestionado por el CDI de @Named en lugar de JSF de @ManagedBean, es aún más fácil:

@Inject 
private Bean bean; 

Independientemente de el alcance, cuando está en realidad dentro de FacesContext (es decir, la solicitud HTTP actual se ha servido a través de la FacesServlet), entonces la forma normal JSF2 está utilizando Application#evaluateExpressionGet():

FacesContext context = FacesContext.getCurrentInstance(); 
Bean bean = context.getApplication().evaluateExpressionGet(context, "#{beanName}", Bean.class); 

que puede ser convenienced como sigue:

y se puede utilizar de la siguiente manera:

Bean bean = findBean("bean"); 

Sin embargo, cuando ya estás dentro de un @ManagedBean, luego usando @ManagedProperty es más limpio ya que es más declarativo.

@ManagedProperty("#{bean}") 
private Bean bean; 
+0

De nada. – BalusC

+8

Tu segunda sugerencia acerca de solo inyectar el frijol fue tan increíblemente simple que lo había pasado por alto totalmente. Como siempre, tu respuesta es perfecta para el punto. Muchas gracias por su trabajo aquí en SO. – jnt30

+1

@ jnt30: De nada :) – BalusC

2

¿Has probado un método como este en este enlace? No estoy seguro de si createValueBinding() aún está disponible, pero se debe poder acceder al código de este tipo desde un simple Servlet antiguo. Esto requiere que bean ya exista.

http://www.coderanch.com/t/211706/JSF/java/access-managed-bean-JSF-from

FacesContext context = FacesContext.getCurrentInstance(); 
Application app = context.getApplication(); 
// May be deprecated 
ValueBinding binding = app.createValueBinding("#{" + expr + "}"); 
Object value = binding.getValue(context); 
+0

Esto probablemente ganó ' Trabajar en un servlet regular. El FacesContext es un artefacto local de subproceso solicitado por el ciclo de vida JSF (generalmente, el FacesServlet). – McDowell

+7

ValueBinding está en desuso desde JSF 1.2 hace más de 4 años. – BalusC

+0

@BalusC: Muestra cómo estoy actualizado jajaja. En una nota al margen, usar un motor de búsqueda para técnicas de investigación resulta ser contraproducente con toda la información anterior. @McDowell: Eso realmente tiene sentido. Haré una prueba solo para ver qué pasa. –

9

utilizo el siguiente método:

public static <T> T getBean(final String beanName, final Class<T> clazz) { 
    ELContext elContext = FacesContext.getCurrentInstance().getELContext(); 
    return (T) FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(elContext, null, beanName); 
} 

Esto permite que consiga el objeto devuelto de manera escrita.

+2

Esto ya está cubierto por la respuesta actualmente aceptada e incluso de una manera más conveniente (el argumento de 'Clase' es innecesario en este constructo). – BalusC

2

Usted puede obtener el bean gestionado pasando el nombre:

public static Object getBean(String beanName){ 
    Object bean = null; 
    FacesContext fc = FacesContext.getCurrentInstance(); 
    if(fc!=null){ 
     ELContext elContext = fc.getELContext(); 
     bean = elContext.getELResolver().getValue(elContext, null, beanName); 
    } 

    return bean; 
} 
+0

Intento hacerlo desde un servlet pero no funciona. –

-1

utilizo este:

public static <T> T getBean(Class<T> clazz) { 
    try { 
     String beanName = getBeanName(clazz); 
     FacesContext facesContext = FacesContext.getCurrentInstance(); 
     return facesContext.getApplication().evaluateExpressionGet(facesContext, "#{" + beanName + "}", clazz); 
    //return facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, nomeBean); 
    } catch (Exception ex) { 
     return null; 
    } 
} 

public static <T> String getBeanName(Class<T> clazz) { 
    ManagedBean managedBean = clazz.getAnnotation(ManagedBean.class); 
    String beanName = managedBean.name(); 

    if (StringHelper.isNullOrEmpty(beanName)) { 
     beanName = clazz.getSimpleName(); 
     beanName = Character.toLowerCase(beanName.charAt(0)) + beanName.substring(1); 
    } 

    return beanName; 
} 

y luego llamar a:

MyManageBean bean = getBean(MyManageBean.class); 

esta manera se puede refactorizar su codificar y rastrear usos sin problemas.

0

Tenía el mismo requisito.

He utilizado la forma siguiente para obtenerlo.

Tuve una sesión con ámbito de frijol.

@ManagedBean(name="mb") 
@SessionScopedpublic 
class ManagedBean { 
    -------- 
} 

He utilizado el siguiente código en mi método de servlet doPost().

ManagedBean mb = (ManagedBean) request.getSession().getAttribute("mb"); 

resolvió mi problema.

+0

¿Qué tipo de servlet usas? mate –

+1

Es HttpServlet. – Anil

+0

No funciona para mí, siempre obtengo bean = null ... –

Cuestiones relacionadas