Получить управляемый компонент JSF по имени в любом классе, связанном с сервлетом
Я пытаюсь написать пользовательский сервлет (для AJAX/JSON), в котором я хотел бы сослаться на мой @ManagedBeans
по имени. Я надеюсь на карту:
http://host/app/myBean/myProperty
to:
@ManagedBean(name="myBean")
public class MyBean {
public String getMyProperty();
}
можно ли загрузить Боб по имени из обычного сервлета? Есть ли сервлет JSF или помощник, который я мог бы использовать для этого?
Я, кажется, избалован весной, в которой все это слишком очевидно.
6 ответов:
в сервлете вы можете получить бобы с областью запроса:
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);
который можно convenienced следующим образом:
@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 { -------- }
я использовал приведенный ниже код в моем методе servlet 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);
таким образом, вы можете рефакторинг кода и отслеживать использование без проблем.