Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在任何与Servlet相关的类中按名称获取JSF托管bean_Jsf_Jakarta Ee_Servlets_Jsf 2_Managed Bean - Fatal编程技术网

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

在任何与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

我正在尝试编写一个自定义servlet(用于AJAX/JSON),在其中我想按名称引用我的
@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中复制它,但它不起作用。