在任何与Servlet相关的类中获取JSF托pipebean的名称

我试图编写一个自定义的servlet(对于AJAX / JSON),我想通过名字引用我的@ManagedBeans 。 我希望能够映射:

http://host/app/myBean/myProperty

至:

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

是否有可能从一个普通的servlet名称加载一个bean? 有没有我可以使用的JSF servlet或helper?

我似乎被spring宠坏了,这一切都太明显了。

在一个Servlet中,你可以通过以下方式获得请求范围的bean:

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

和会话范围的bean:

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

和应用程序范围的bean:

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

如果您运行的是dependency injection的框架/容器,并且该bean由CDI的@Named而不是JSF的@ManagedBean ,那么它更加简单:

 @Inject private Bean bean; 

不pipe范围如何,当你真正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; 

我使用以下方法:

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

这使我能够以types化的方式获取返回的对象。

你有没有尝试像这个链接的方法? 我不确定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); 

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

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

我有同样的要求。

我已经使用下面的方式来获取它。

我有会话范围的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); 

这样你就可以重构你的代码并且可以毫无问题的跟踪使用。