我正在尝试编写一个自定义 servlet(用于 AJAX/JSON),我想在其中按名称引用我的 @ManagedBeans
。我希望绘制 map :
http://host/app/myBean/myProperty
至:
@ManagedBean(name="myBean")
public class MyBean {
public String getMyProperty();
}
是否可以从常规 servlet 按名称加载 bean?是否有我可以使用的 JSF servlet 或帮助程序?
我似乎被Spring宠坏了,这一切都太明显了。
请您参考如下方法:
在基于 servlet 的工件中,例如 @WebServlet
、@WebFilter
和 @WebListener
,您可以获取“普通”JSF @ManagedBean @RequestScoped
作者:
Bean bean = (Bean) request.getAttribute("beanName");
和@ManagedBean @SessionScoped
:
Bean bean = (Bean) request.getSession().getAttribute("beanName");
和@ManagedBean @ApplicationScoped
:
Bean bean = (Bean) getServletContext().getAttribute("beanName");
请注意,这先决条件是 JSF 已预先自动创建了该 bean。否则这些将返回null
。然后,您需要手动创建 bean 并使用 setAttribute("beanName", bean)
。
如果您能够使用 CDI @Named
而不是自 JSF 2.3 弃用的 @ManagedBean
以来,它就更简单了,特别是因为您不再需要手动创建 bean:
@Inject
private Bean bean;
请注意,当您使用 @Named @ViewScoped
时,这将不起作用,因为该 bean 只能由 JSF View 状态标识,并且仅当 FacesServlet
时才可用> 已被调用。因此,在之前运行的过滤器中,访问 @Inject
ed @ViewScoped
将始终抛出 ContextNotActiveException
。
只有当您位于@ManagedBean
内时,您才可以使用 @ManagedProperty
:
@ManagedProperty("#{bean}")
private Bean bean;
请注意,这在 @Named
或 @WebServlet
或任何其他工件内不起作用。它确实仅在 @ManagedBean
内部有效。
如果您不在 @ManagedBean
内,但 FacesContext
随时可用(即 FacesContext#getCurrentInstance()
不可用返回null
),您也可以使用 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");
<小时 />