Servlet ile ilgili herhangi bir sınıfta JSF tarafından yönetilen fasulyeyi ada göre alın


101

Kendi adıma başvurmak istediğim özel bir sunucu uygulaması (AJAX / JSON için) yazmaya çalışıyorum @ManagedBeans. Haritaya koymayı umuyorum:

http://host/app/myBean/myProperty

to:

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

Normal bir sunucu uygulamasından adıyla bir fasulye yüklemek mümkün mü? Bunun için kullanabileceğim bir JSF sunucu uygulaması veya yardımcısı var mı?

Tüm bunların aşikar olduğu Bahar beni şımartıyor.


Bu yeni ek açıklamaları JSF / EL dışında kullanıp kullanamayacağınızdan emin değilim, ancak JSR 299 spesifikasyonuna bakarak başlayabilirim: jcp.org/en/jsr/detail?id=299
McDowell

Ayrıca kontrol edebilirsiniz benzer sorunlara sahip diğer kişiler bpcatalog.dev.java.net/ajax/jsf-ajax (AJAX ve istek haritalama / elleçleme, adıyla fasulye almıyor ilgili)
Konrad Garus

Yanıtlar:


263

Bir servlet dayalı bir yan gibi ise @WebServlet, @WebFilterve @WebListener, bir "düz vanilya" JSF yakala @ManagedBean @RequestScopedtarafından:

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

ve @ManagedBean @SessionScopedtarafından:

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

ve @ManagedBean @ApplicationScopedtarafından:

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

Bu, çekirdeğin önceden JSF tarafından otomatik olarak oluşturulmasını gerektirdiğini unutmayın. Aksi takdirde bunlar geri dönecek null. Daha sonra fasulyeyi manuel olarak oluşturmanız ve kullanmanız gerekir setAttribute("beanName", bean).


@NamedJSF 2.3'ün kullanımdan kaldırılmasından bu yana CDI kullanabiliyorsanız , bu @ManagedBeandaha da kolaydır, özellikle artık fasulyeleri manuel olarak oluşturmanız gerekmediğinden:

@Inject
private Bean bean;

@Named @ViewScopedÇekirdek yalnızca JSF görünüm durumuyla tanımlanabildiğinden ve bu yalnızca FacesServletçağrıldığında kullanılabilir olduğundan, bunu kullanırken bunun işe yaramayacağını unutmayın . Bundan önce çalışan bir filtrede, bir @Injected'e erişim @ViewScopedher zaman atacaktır ContextNotActiveException.


Yalnızca içerideyken @ManagedBeanşunları kullanabilirsiniz @ManagedProperty:

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

Bunun bir @Namedveya @WebServletbaşka bir yapının içinde çalışmadığını unutmayın . Gerçekten @ManagedBeansadece içeride çalışıyor .


A'nın içinde değilseniz @ManagedBean, ancak FacesContextkullanıma hazırsa (yani FacesContext#getCurrentInstance()geri dönmüyorsa null), şunları da kullanabilirsiniz Application#evaluateExpressionGet():

FacesContext context = FacesContext.getCurrentInstance();
Bean bean = context.getApplication().evaluateExpressionGet(context, "#{beanName}", Bean.class);

aşağıdaki gibi uygun hale getirilebilir:

@SuppressWarnings("unchecked")
public static <T> T findBean(String beanName) {
    FacesContext context = FacesContext.getCurrentInstance();
    return (T) context.getApplication().evaluateExpressionGet(context, "#{" + beanName + "}", Object.class);
}

ve aşağıdaki şekilde kullanılabilir:

Bean bean = findBean("bean");

Ayrıca bakınız:


9
Fasulyeyi enjekte etmekle ilgili ikinci öneriniz o kadar şaşırtıcı derecede basitti ki, tamamen görmezden gelmiştim. Her zaman olduğu gibi, cevabınız mükemmel. SO'daki çalışmanız için çok teşekkürler.
jnt30

2
Bu arada (JSF 2.2'den bahsedersek), evalExpressionGet yöntemi, beklenen sınıfı belirtmeye izin veren üçüncü bir parametre ile genişletilmiş gibi görünüyor, böylece çevrim artık gerekli olmayacak. PostBean bean = context.getApplication().evaluateExpressionGet(context, "#{beanName}", PostBean.class);
Marc Juchli

1
@Marc: Başından beri buradaydı. Sanırım bir kopya macundan arta kalanlardı. Cevap düzeltildi. Haber verdiğiniz için teşekkürler.
BalusC

FacesContextstaticyardımcı program yöntemi findBean()sade bir Java sınıfı içinde tanımlanmış olsa bile kullanılabilir . Orada, JSF tarafından yönetilmeyen basit bir Java sınıfında nasıl bulunur?
Minik

1
@Tiny: Sırayla aynı iş parçacığı içindeki bir JSF yapısı tarafından çağrılır.
BalusC

11

Aşağıdaki yöntemi kullanıyorum:

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

Bu, döndürülen nesneyi yazılı bir şekilde elde etmemi sağlıyor.


3
Bu, halihazırda kabul edilen cevapta ve hatta daha uygun bir şekilde kapsanmıştır ( Classargüman, yani bu yapıda gereksizdir).
BalusC

3

Bu bağlantıdaki gibi bir yaklaşım denediniz mi? createValueBinding()Hala mevcut olup olmadığından emin değilim , ancak bunun gibi bir koda düz, eski bir Servlet'ten erişilebilir. Bu, fasulyenin zaten var olmasını gerektirir.

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

Bu muhtemelen normal bir sunucu uygulamasında çalışmayacaktır. FacesContext, JSF yaşam döngüsü (genellikle FacesServlet) tarafından kurulan istek başına iş parçacığı yerel bir yapıdır.
McDowell

7
ValueBinding, 4 yıl önce JSF 1.2'den beri kullanımdan kaldırıldı.
BalusC

@BalusC: Ne kadar güncel olduğumu gösteriyor lol. Diğer yandan, teknikleri araştırmak için bir arama motoru kullanmak, oradaki tüm eski bilgilerle ters etki yaratıyor. @McDowell: Bu gerçekten mantıklı. Ne olacağını görmek için bir test yapacağım.
James P.

3

Adı geçerek yönetilen fasulyeyi alabilirsiniz:

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

Bunu bir sunucu uygulamasından yapmaya çalışıyorum ama işe yaramıyor.
Fernando Pie

0

Benim de aynı şartım vardı.

Bunu elde etmek için aşağıdaki yolu kullandım.

Seansa fasulyeyi inceledim.

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

Servlet doPost () yöntemimde aşağıdaki kodu kullandım.

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

sorunumu çözdü.


Ne tür bir servlet kullanıyorsunuz? mate
Fernando Pie

1
HttpServlet'tir.
Anil

-1

Bunu kullanıyorum:

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

Ve sonra arayın:

MyManageBean bean = getBean(MyManageBean.class);

Bu şekilde kodunuzu yeniden düzenleyebilir ve kullanımları sorunsuz bir şekilde izleyebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.