Получить управляемый компонент JSF по имени в любом классе, связанном с сервлетом - PullRequest
98 голосов
/ 14 апреля 2010

Я пытаюсь написать собственный сервлет (для AJAX / JSON), в котором я хотел бы сослаться на мой @ManagedBeans по имени. Я надеюсь на карту:

http://host/app/myBean/myProperty

до:

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

Можно ли загрузить бин по имени из обычного сервлета? Могу ли я использовать для этого сервлет или помощник JSF?

Кажется, я избалован Spring, в котором все это слишком очевидно.

Ответы [ 6 ]

256 голосов
/ 14 апреля 2010

В сервлете вы можете получить запрос bean-объекта фасоли по:

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

и сессионные компоненты в области видимости:

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

и область применения бобов:

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;
10 голосов
/ 10 декабря 2012

Я использую следующий метод:

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 голосов
/ 29 июля 2014

Вы можете получить управляемый бин, передав имя:

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 голосов
/ 14 апреля 2010

Вы пробовали подход как по этой ссылке? Я не уверен, что 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);
0 голосов
/ 27 июня 2016

У меня было такое же требование.

Я использовал следующий способ, чтобы получить его.

У меня был сессионный боб.

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

Я использовал приведенный ниже код в методе doPost () моего сервлета.

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

это решило мою проблему.

0 голосов
/ 11 сентября 2015

Я использую это:

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

Таким образом, вы можете без проблем реструктурировать свой код и отслеживать использование.

...