Получить управляемый компонент JSF по имени в любом классе, связанном с сервлетом
Я пытаюсь написать собственный сервлет (для AJAX/JSON), в котором я хотел бы сослаться на мой @ManagedBeans
по имени. Я надеюсь на карту:
http://host/app/myBean/myProperty
чтобы:
@ManagedBean(name="myBean")
public class MyBean {
public String getMyProperty();
}
Можно ли загрузить бин по имени из обычного сервлета? Есть ли сервлет JSF или помощник, который я мог бы использовать для этого?
Кажется, я избалован весной, в которой все это слишком очевидно.
6 ответов
В сервлете вы можете получить bean-объекты в области запроса по:
Bean bean = (Bean) request.getAttribute("beanName");
и сессионные бобы:
Bean bean = (Bean) request.getSession().getAttribute("beanName");
и область применения бобов:
Bean bean = (Bean) getServletContext().getAttribute("beanName");
Если вы работаете в инфраструктуре / контейнере, поддерживающем внедрение зависимостей, и компонент управляется 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;
Я использую следующий метод:
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);
}
Это позволяет мне получить возвращенный объект печатным способом.
Вы пробовали подход, как по этой ссылке? Я не уверен, если createValueBinding()
все еще доступен, но такой код должен быть доступен из простого старого сервлета. Это требует, чтобы бин уже существовал.
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);
Вы можете получить управляемый бин, передав имя:
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;
}
У меня было такое же требование.
Я использовал следующий способ, чтобы получить его.
У меня был сессионный боб.
@ManagedBean(name="mb")
@SessionScopedpublic
class ManagedBean {
--------
}
Я использовал приведенный ниже код в моем методе doPost() сервлета.
ManagedBean mb = (ManagedBean) request.getSession().getAttribute("mb");
это решило мою проблему.
Я использую это:
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);
Таким образом, вы можете рефакторинг вашего кода и отслеживать использование без проблем.