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

发布于 2024-08-28 23:05:00 字数 362 浏览 5 评论 0原文

我正在尝试编写一个自定义 servlet(用于 AJAX/JSON),我想在其中按名称引用我的 @ManagedBeans 。我希望将:

http://host/app/myBean/myProperty

映射到:

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

是否可以从常规 servlet 按名称加载 bean?是否有我可以使用的 JSF servlet 或帮助程序?

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

I'm trying to write a custom servlet (for AJAX/JSON) in which I would like to reference my @ManagedBeans by name. I'm hoping to map:

http://host/app/myBean/myProperty

to:

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

Is it possible to load a bean by name from a regular servlet? Is there a JSF servlet or helper I could use for it?

I seem to be spoilt by Spring in which all this is too obvious.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

蓝海似她心 2024-09-04 23:05:00

在基于 servlet 的工件中,例如 @WebServlet@WebFilter@WebListener,您可以获取“普通”JSF @ManagedBean @RequestScoped by:

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

@ManagedBean @SessionScoped by:

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

@ManagedBean @ApplicationScoped by:

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

请注意,这先决条件是该 bean 已由 JSF 自动创建预先。否则这些将返回null。然后,您需要手动创建 bean 并使用 setAttribute("beanName", bean)


如果您能够使用 CDI @Named而不是自 JSF 2.3 以来已弃用的 @ManagedBean,那么它就更容易了,特别是因为您不再需要手动创建 bean:

@Inject
private Bean bean;

请注意,这不起作用当您使用 @Named @ViewScoped 时,因为该 bean 只能由 JSF 视图状态标识,并且仅在调用 FacesServlet 时才可用。因此,在之前运行的过滤器中,访问 @Injected @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");

另请参阅:

In a servlet based artifact, such as @WebServlet, @WebFilter and @WebListener, you can grab a "plain vanilla" JSF @ManagedBean @RequestScoped by:

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

and @ManagedBean @SessionScoped by:

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

and @ManagedBean @ApplicationScoped by:

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

Note that this prerequires that the bean is already autocreated by JSF beforehand. Else these will return null. You'd then need to manually create the bean and use setAttribute("beanName", bean).


If you're able to use CDI @Named instead of the since JSF 2.3 deprecated @ManagedBean, then it's even more easy, particularly because you don't anymore need to manually create the beans:

@Inject
private Bean bean;

Note that this won't work when you're using @Named @ViewScoped because the bean can only be identified by JSF view state and that's only available when the FacesServlet has been invoked. So in a filter which runs before that, accessing an @Injected @ViewScoped will always throw ContextNotActiveException.


Only when you're inside @ManagedBean, then you can use @ManagedProperty:

@ManagedProperty("#{bean}")
private Bean bean;

Note that this doesn't work inside a @Named or @WebServlet or any other artifact. It really works inside @ManagedBean only.


If you're not inside a @ManagedBean, but the FacesContext is readily available (i.e. FacesContext#getCurrentInstance() doesn't return null), you can also use Application#evaluateExpressionGet():

FacesContext context = FacesContext.getCurrentInstance();
Bean bean = context.getApplication().evaluateExpressionGet(context, "#{beanName}", Bean.class);

which can be convenienced as follows:

@SuppressWarnings("unchecked")
public static <T> T findBean(String beanName) {
    FacesContext context = FacesContext.getCurrentInstance();
    return (T) context.getApplication().evaluateExpressionGet(context, "#{" + beanName + "}", Object.class);
}

and can be used as follows:

Bean bean = findBean("bean");

See also:

離人涙 2024-09-04 23:05:00

我使用以下方法:

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

这允许我以类型化的方式获取返回的对象。

I use the following method:

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

This allows me to get the returned object in a typed manner.

绮烟 2024-09-04 23:05:00

您是否尝试过类似此链接的方法?我不确定 createValueBinding() 是否仍然可用,但这样的代码应该可以从普通的旧 Servlet 访问。这确实需要 bean 已经存在。

http://www.coderanch.com/ t/211706/JSF/java/access-management-bean-JSF-from

 FacesContext context = FacesContext.getCurrentInstance();  
 Application app = context.getApplication();
 // May be deprecated
 ValueBinding binding = app.createValueBinding("#{" + expr + "}"); 
 Object value = binding.getValue(context);

Have you tried an approach like on this link? I'm not sure if createValueBinding() is still available but code like this should be accessible from a plain old Servlet. This does require to bean to already exist.

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);
薄荷梦 2024-09-04 23:05:00

您可以通过传递名称来获取托管 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;
}

You can get the managed bean by passing the name:

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;
}
荒人说梦 2024-09-04 23:05:00

我有同样的要求。

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

我有会话范围的bean。

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

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

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

它解决了我的问题。

I had same requirement.

I have used the below way to get it.

I had session scoped bean.

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

I have used the below code in my servlet doPost() method.

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

it solved my problem.

任谁 2024-09-04 23:05:00

我使用这个:

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

这样您就可以重构代码并毫无问题地跟踪使用情况。

I use this:

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

And then call:

MyManageBean bean = getBean(MyManageBean.class);

This way you can refactor your code and track usages without problems.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文