web-dev-qa-db-fra.com

Obtenir le bean géré JSF par nom dans n’importe quelle classe liée à Servlet

J'essaie d'écrire un servlet personnalisé (pour AJAX/JSON) dans lequel je voudrais référencer mon @ManagedBeans par son nom. J'espère cartographier:

http://Host/app/myBean/myProperty

à: 

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

Est-il possible de charger un nom de bean à partir d'un servlet normal? Existe-t-il un servlet ou un assistant JSF que je pourrais utiliser pour cela?

Il semble que je sois gâté par le printemps dans lequel tout cela est trop évident.

96
Konrad Garus

Dans un Servlet, vous pouvez obtenir une demande de haricots Scoped en:

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

et session haricot haricot par:

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

et application haché haricots par:

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

Si vous utilisez un framework/conteneur capable d'injection de dépendance et que le bean est géré par le @Named du CDI au lieu du/ @ManagedBean de JSF, c'est encore plus simple:

@Inject
private Bean bean;

Indépendamment de la portée, lorsque réellement est à l'intérieur de FacesContext (c'est-à-dire que la demande HTTP actuelle a été traitée par le biais de FacesServlet ), la manière habituelle de JSF2 utilise Application#evaluateExpressionGet() :

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

qui peut être organisé comme suit:

@SuppressWarnings("unchecked")
public static <T> T findBean(String beanName) {
    FacesContext context = FacesContext.getCurrentInstance();
    return (T) context.getApplication().evaluateExpressionGet(context, "#{" + beanName + "}", Object.class);
}

et peut être utilisé comme suit:

Bean bean = findBean("bean");

Cependant, lorsque vous êtes déjà dans un @ManagedBean , alors utiliser @ManagedProperty est plus propre car il est plus déclaratif.

@ManagedProperty("#{bean}")
private Bean bean;
253
BalusC

J'utilise la méthode suivante:

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

Cela me permet d’obtenir l’objet retourné de manière typée.

10
John Yeary

Vous pouvez obtenir le bean géré en passant le nom:

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

Avez-vous essayé une approche comme sur ce lien? Je ne sais pas si createValueBinding() est toujours disponible, mais un code comme celui-ci devrait être accessible à partir d'un ancien Servlet. Cela nécessite de bean d'exister déjà.

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);
3
James P.

J'ai eu la même exigence. 

J'ai utilisé le moyen ci-dessous pour l'obtenir. 

J'ai eu une séance de haricot. 

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

J'ai utilisé le code ci-dessous dans ma méthode doPost () de servlet. 

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

cela a résolu mon problème.

0
Anil