代码之家  ›  专栏  ›  技术社区  ›  Konrad Garus

在任何与servlet相关的类中按名称获取JSF托管bean

  •  96
  • Konrad Garus  · 技术社区  · 15 年前

    我正在尝试编写一个自定义servlet(用于Ajax/JSON),在其中我想引用 @ManagedBeans 按名字。我希望能画出:

    http://host/app/myBean/myProperty

    到:

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

    是否可以从常规servlet中按名称加载bean?我是否可以使用JSF servlet或helper?

    我似乎被春天宠坏了,因为春天的一切太明显了。

    6 回复  |  直到 9 年前
        1
  •  253
  •   BalusC    11 年前

    在servlet中,您可以通过以下方式获得请求范围的bean:

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

    会话范围的bean是:

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

    和应用程序范围的bean:

    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;
    
        2
  •  10
  •   John Yeary    12 年前

    我使用以下方法:

    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
  •  3
  •   James P. PachinSV    15 年前

    您是否尝试过类似于此链接的方法?我不确定是否 createValueBinding() 仍然可用,但类似这样的代码应该可以从普通的旧servlet访问。这要求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);
    
        4
  •  3
  •   Subodh Joshi    10 年前

    您可以通过传递名称来获取托管bean:

    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;
    }
    
        5
  •  0
  •   Anil    9 年前

    我也有同样的要求。

    我用下面的方法得到它。

    我有会话范围的bean。

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

    我在servlet dopost()方法中使用了以下代码。

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

    它解决了我的问题。

        6
  •  -1
  •   ChRoNoN    10 年前

    我用这个:

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

    通过这种方式,您可以重构代码并毫无问题地跟踪用法。

    推荐文章