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