2010-04-13 2 views
90

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

http://host/app/myBean/myProperty

к:

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

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

Я, кажется, испорчен весной, в которой все это слишком очевидно.

+0

Я не уверен, что вы можете использовать эти новые аннотации вне JSF/EL, но я бы начал с рассмотрения спецификации JSR 299: http://jcp.org/en/jsr/detail?id=299 – McDowell

+0

Другие люди, имеющие проблемы с подобными проблемами, также могут проверить https://bpcatalog.dev.java.net/ajax/jsf-ajax/ (связанные с AJAX и обработкой запросов/обработкой, а не получением bean-компонентов по имени) –

ответ

245

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

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

и сессионная область действия фасоли по:

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

и применение области видимости бобов пути:

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

Если вы работаете в инъекции зависимостей, способной рамочным/контейнер и боб управляется КДИ-х @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 следующим образом:

и могут быть использованы следующим образом:

Bean bean = findBean("bean"); 

Однако, когда вы уже внутри @ManagedBean, то с помощью @ManagedProperty более чистый, поскольку он более декларативный.

@ManagedProperty("#{bean}") 
private Bean bean; 
+0

Добро пожаловать. – BalusC

+8

Вы второе предложение о простое впрыскивание боба было настолько удивительно простым, что я полностью его не замечал. Как всегда, ваш ответ прекрасно подходит к делу. Большое спасибо за вашу работу здесь, на SO. – jnt30

+1

@ jnt30: приветствую :) – BalusC

2

Вы пробовали такой подход, как по этой ссылке? Я не уверен, что 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

Это, вероятно, t работать в обычном сервлете. FacesContext - это локально-локальный артефакт для каждого запроса, созданный жизненным циклом JSF (обычно это FacesServlet). – McDowell

+7

ValueBinding устарел после JSF 1.2 более 4 лет назад. – BalusC

+0

@BalusC: Он показывает, насколько я доволен. В случае сбоя, использование поисковой системы для исследовательских методов оказывается контрпродуктивным со всей старой информацией. @McDowell: Это действительно имеет смысл. Я сделаю тест, чтобы посмотреть, что произойдет. –

9

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

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

Это позволяет мне получить возвращенный объект в типизированной форме.

+2

Это уже охвачено принятым в настоящее время ответом и даже более удобным способом (аргумент 'Class' в этой конструкции не нужен). – BalusC

2

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

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; 
} 
+0

Я пытаюсь сделать это с сервлета, но он не работает. –

-1

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

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

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

0

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

Я использовал способ ниже, чтобы получить его.

У меня был сеанс с фасолью.

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

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

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

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

+0

Какой сервлет вы используете? mate –

+1

Это HttpServlet. – Anil

+0

Это не работает для меня, всегда получаю bean = null ... –

Смежные вопросы