在任何与Servlet相关的类中按名称获取JSF托管bean
我正在尝试编写一个自定义servlet(用于AJAX/JSON),在其中我想按名称引用我的在任何与Servlet相关的类中按名称获取JSF托管bean,jsf,jakarta-ee,servlets,jsf-2,managed-bean,Jsf,Jakarta Ee,Servlets,Jsf 2,Managed Bean,我正在尝试编写一个自定义servlet(用于AJAX/JSON),在其中我想按名称引用我的@ManagedBeans。我希望能够绘制: http://host/app/myBean/myProperty 致: 是否可以按名称从常规servlet加载bean?是否有JSFServlet或帮助程序可供我使用 我似乎被春天给宠坏了,在春天里,所有这些都太明显了。你有没有在这个链接上尝试过类似的方法?我不确定createValueBinding()是否仍然可用,但这样的代码应该可以从普通的旧Servle
@ManagedBeans
。我希望能够绘制:
http://host/app/myBean/myProperty
致:
是否可以按名称从常规servlet加载bean?是否有JSFServlet或帮助程序可供我使用
我似乎被春天给宠坏了,在春天里,所有这些都太明显了。你有没有在这个链接上尝试过类似的方法?我不确定
createValueBinding()
是否仍然可用,但这样的代码应该可以从普通的旧Servlet中访问。这确实要求bean已经存在
在基于servlet的工件中,例如
@WebServlet
、@WebFilter
和@WebListener
,您可以通过以下方式获取“普通”JSF@ManagedBean@RequestScoped
:
Bean bean = (Bean) request.getAttribute("beanName");
Bean bean = (Bean) request.getSession().getAttribute("beanName");
Bean bean = (Bean) getServletContext().getAttribute("beanName");
和@ManagedBean@SessionScoped
:
Bean bean = (Bean) request.getAttribute("beanName");
Bean bean = (Bean) request.getSession().getAttribute("beanName");
Bean bean = (Bean) getServletContext().getAttribute("beanName");
和@ManagedBean@ApplicationScoped
:
Bean bean = (Bean) request.getAttribute("beanName");
Bean bean = (Bean) request.getSession().getAttribute("beanName");
Bean bean = (Bean) getServletContext().getAttribute("beanName");
注意,这需要事先由JSF自动创建bean。否则将返回null
。然后需要手动创建bean并使用setAttribute(“bean名称”,bean)
如果您能够使用CDI而不是自JSF 2.3弃用以来的
@ManagedBean
,那么它就更容易了,特别是因为您不再需要手动创建bean:
@Inject
private Bean bean;
请注意,当您使用@Named@ViewScoped
时,这将不起作用,因为bean只能由JSF视图状态标识,并且只有在调用FacesServlet
时才可用。因此,在之前运行的筛选器中,访问@Inject
ed@ViewScoped
将始终抛出ContextNotActiveException
只有在
@ManagedBean
中,才能使用:
请注意,这在@命名的
或@WebServlet
或任何其他工件中都不起作用。它只在@ManagedBean
内部工作
如果您不在
@ManagedBean
中,但FacesContext
随时可用(即FacesContext#getCurrentInstance()
不返回null
),您还可以使用:
其便利性如下:
@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");
另见:
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);
}
publicstatict getBean(最终字符串beanName,最终类clazz){
ELContext ELContext=FacesContext.getCurrentInstance().getELContext();
返回(T)FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(elContext,null,beanName);
}
这允许我以类型化的方式获取返回的对象。您可以通过传递名称来获取托管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;
}
我用这个:
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;
}
通过这种方式,您可以重构代码并跟踪使用情况,而不会出现问题。我也有同样的要求 我用下面的方法得到它 我有会话范围的bean
@ManagedBean(name="mb")
@SessionScopedpublic
class ManagedBean {
--------
}
我在servlet doPost()方法中使用了以下代码
它解决了我的问题。这在常规servlet中可能不起作用。FacesContext是由JSF生命周期(通常是FacesServlet)设置的每个请求线程的本地人工制品。ValueBinding在4年前的JSF 1.2中就被弃用了。@BalusC:它显示了我是多么的最新。在旁注中,使用搜索引擎来研究技术,对于所有的旧信息来说都是适得其反的@麦克道尔:这是有道理的。我将做一个测试,看看会发生什么。我不确定您是否可以在JSF/EL之外使用这些新注释,但我将从JSR 299规范开始:其他有类似问题的人也可以检查(与AJAX和请求映射/处理相关,而不是按名称获取bean)你的第二个建议是注射豆子,这个建议太简单了,我完全忽略了。和往常一样,你的回答非常中肯。非常感谢您在so上所做的工作。同时(说到JSF2.2),方法evaluateExpressionGet似乎用第三个参数进行了扩展,该参数允许指定预期的类,因此不再需要强制转换
PostBean=context.getApplication().evaluateExpressionGet(context,“{beanName}”,PostBean.class)代码>@Marc:从一开始就在。我想这只是一个复制粘贴错误的遗留问题。答案已更正。感谢您的通知。FacesContext
可用,即使static
实用程序方法findBean()
是在普通Java类中定义的。在一个不受JSF管理的普通Java类中,它是如何使用的?@Tiny:它反过来又被同一线程中的JSF工件调用。这已经被当前接受的答案所涵盖,甚至是以一种更方便的方式(class
参数在这个构造中是不必要的)。您使用什么样的servlet?mateIt是HttpServlet。我试图从一个servlet中复制它,但它不起作用。