Получить JSF bean по имени в любом классе, связанном с Servlet
Я пытаюсь написать собственный сервлет (для AJAX/JSON), в котором я хотел бы ссылаться на мой @ManagedBeans
по имени. Я надеюсь на карту:
http://host/app/myBean/myProperty
to:
@ManagedBean(name="myBean")
public class MyBean {
public String getMyProperty();
}
Можно ли загрузить bean по имени из обычного сервлета? Я могу использовать сервлет или помощник JSF для этого?
Кажется, я испорчен Spring, в котором все это слишком очевидно.
Ответы
Ответ 1
В сервлете вы можете получить запрос beans с помощью:
Bean bean = (Bean) request.getAttribute("beanName");
и область сеанса beans:
Bean bean = (Bean) request.getSession().getAttribute("beanName");
и область приложения beans:
Bean bean = (Bean) getServletContext().getAttribute("beanName");
Если вы работаете в платформе/контейнере с поддержкой зависимостей, а bean управляется CDI @Named
вместо JSF @ManagedBean
, это еще проще:
@Inject
private Bean bean;
Независимо от области действия, когда вы находитесь внутри FacesContext
(т.е. текущий HTTP-запрос был отправлен через FacesServlet
), тогда обычный способ JSF2 использует Application#evaluateExpressionGet()
:
FacesContext context = FacesContext.getCurrentInstance();
Bean bean = context.getApplication().evaluateExpressionGet(context, "#{beanName}", Bean.class);
который может быть созван следующим образом:
@SuppressWarnings("unchecked")
public static <T> T findBean(String beanName) {
FacesContext context = FacesContext.getCurrentInstance();
return (T) context.getApplication().evaluateExpressionGet(context, "#{" + beanName + "}", Object.class);
}
и может использоваться следующим образом:
Bean bean = findBean("bean");
Однако, когда вы уже находитесь в @ManagedBean
, используйте @ManagedProperty
является более чистым, поскольку он более декларативный.
@ManagedProperty("#{bean}")
private Bean bean;
Ответ 2
Я использую следующий метод:
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);
}
Это позволяет мне получить возвращаемый объект типизированным образом.
Ответ 3
Вы пробовали такой подход, как по этой ссылке? Я не уверен, что createValueBinding()
все еще доступен, но такой код должен быть доступен из простого старого сервлета. Это требует, чтобы bean уже существовал.
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);
Ответ 4
Вы можете получить управляемый bean, передав имя:
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;
}
Ответ 5
У меня было такое же требование.
Я использовал метод ниже, чтобы получить его.
У меня был сеанс bean.
@ManagedBean(name="mb")
@SessionScopedpublic
class ManagedBean {
--------
}
Я использовал приведенный ниже код в моем методе doPost() сервлета.
ManagedBean mb = (ManagedBean) request.getSession().getAttribute("mb");
он решил мою проблему.
Ответ 6
Я использую это:
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;
}
И затем вызовите:
MyManageBean bean = getBean(MyManageBean.class);
Таким образом вы можете без проблем реорганизовать свой код и отслеживать использование.