标签: managed-bean

获取CDI托管bean实例的典型方法:BeanManager#getReference()vs Context#get()

我认为有两种通用方法可以获得一个自动创建的CDI托管bean实例BeanManager,只需要一个Bean<T>开始(基于它创建Class<T>):

  1. 通过BeanManager#getReference(),更经常以片段形式显示:

    Bean<TestBean> bean = (Bean<TestBean>) beanManager.resolve(beanManager.getBeans(TestBean.class));
    TestBean testBean1 = (TestBean) beanManager.getReference(bean, bean.getBeanClass(), beanManager.createCreationalContext(bean));
    
    Run Code Online (Sandbox Code Playgroud)
  2. 通过Context#get(),在片段中不常显示:

    Bean<TestBean> bean = (Bean<TestBean>) beanManager.resolve(beanManager.getBeans(TestBean.class));
    TestBean testBean2 = beanManager.getContext(bean.getScope()).get(bean, beanManager.createCreationalContext(bean));
    
    Run Code Online (Sandbox Code Playgroud)

实际上,它们最终完全相同:返回对当前CDI托管bean实例的代理引用,并自动创建bean实例(如果范围中尚不存在).

但是他们做的有点不同:BeanManager#getReference()总是创建一个全新的代理实例,而Context#get()如果之前已经创建过,则重用现有的代理实例.当在现有TestBean实例的action方法中执行上述代码时,这是显而易见的:

System.out.println(testBean1 == testBean2); // false
System.out.println(testBean1 == this); // false
System.out.println(testBean2 == this); // true
Run Code Online (Sandbox Code Playgroud)

的javadocContext#get()是非常明确的在此:

返回某个上下文类型的现有实例,或通过调用Contextual.create(CreationalContext)创建一个新实例并返回新实例.

javadoc中BeanManager#getReference()不够明确在此:

获得某个bean和bean的某个bean类型的上下文引用.

这让我感到困惑.你什么时候使用这一个?对于这两种方式,无论如何都需要一个Bean<T>实例,bean类和bean范围随时可用,这是额外的参数.我无法想象为什么在这种特殊情况下他们需要外部供应.

我可以想象这Context#get()是更高效的内存,因为它不会不必要地创建引用同一个底层bean实例的另一个代理实例,而只是查找并重用现有的代理实例.

这让我想到了以下问题:什么时候BeanManager#getReference() …

cdi managed-bean

38
推荐指数
1
解决办法
1万
查看次数

如何强制应用程序范围的bean在应用程序启动时实例化?

我似乎无法找到一种方法来强制在启动Web应用程序时实例化/初始化应用程序范围的托管bean.似乎应用程序范围的bean在第一次访问bean时会进行惰性实例化,而不是在启动Web应用程序时实例化.对于我的Web应用程序,当第一个用户第一次在Web应用程序中打开页面时,就会发生这种情况.

我想避免这种情况的原因是因为在我的应用程序范围的bean初始化期间发生了许多耗时的数据库操作.它必须从持久存储中检索一堆数据,然后以ListItem元素等形式缓存一些频繁显示给用户的数据.我不希望在第一个用户连接时发生这一切,因此导致长时间的延迟.

我的第一个想法是使用旧式ServletContextListener contextInitialized()方法,并从那里使用ELResolver手动请求我的托管bean的实例(从而强制初始化发生).不幸的是,我无法在此阶段使用ELResolver来触发初始化,因为ELResolver需要FacesContext并且FacesContext仅在请求的生命周期内存在.

有没有人知道另一种方法来实现这一目标?

我使用MyFaces 1.2作为JSF实现,目前无法升级到2.x.

jsf initialization startup managed-bean

37
推荐指数
2
解决办法
3万
查看次数

将输入文本值传递给bean方法,而不将输入值绑定到bean属性

我可以将输入文本字段值传递给bean方法而不将值绑定到bean属性吗?

<h:inputText value="#{myBean.myProperty}" />
<h:commandButton value="Test" action="#{myBean.execute()} />
Run Code Online (Sandbox Code Playgroud)

我可以不进行临时保存#{myBean.myProperty}吗?

jsf parameter-passing managed-bean

37
推荐指数
2
解决办法
9万
查看次数

从java bean重定向的JSF页面

有没有办法如何从Java方法页面重定向到其他页面?

我只能使用以下方式转发它:

FacesContext.getCurrentInstance().getExternalContext().dispatch("/foo.xhtml");
Run Code Online (Sandbox Code Playgroud)

或使用导航规则faces-config.xml.

你有什么想法?

jsf redirect managed-bean

36
推荐指数
1
解决办法
8万
查看次数

WELD-001408:具有限定符@Default的Customer类型的不满意依赖项

我是Java EE新手.我想测试JSF,因此制作了一个简单的程序,但无法部署它.我收到以下错误消息:

cannot Deploy onlineshop-war
deploy is failing=Error occurred during deployment: Exception while loading the app : CDI deployment failure:WELD-001408: Unsatisfied dependencies for type Customer with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject private de.java2enterprise.onlineshop.RegisterController.customer
at de.java2enterprise.onlineshop.RegisterController.customer(RegisterController.java:0)
. Please see server.log for more details.
Run Code Online (Sandbox Code Playgroud)

我的代码如下:Customer.java:

package de.java2enterprise.onlineshop.model;

public class Customer {
    private String email;
    private String password;
}
Run Code Online (Sandbox Code Playgroud)

registerController.java:

package de.java2enterprise.onlineshop;

import java.io.Serializable;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
import javax.inject.Inject;
import de.java2enterprise.onlineshop.model.*;

@Named
@RequestScoped
public class RegisterController {

    private static final …
Run Code Online (Sandbox Code Playgroud)

jsf dependency-injection java-ee cdi managed-bean

36
推荐指数
2
解决办法
9万
查看次数

从托管bean调用JavaScript函数

有没有办法从JSF中的托管bean调用(执行)JavaScript函数?

如果这是相关的,我也使用PrimeFaces.

javascript jsf primefaces managed-bean

31
推荐指数
4
解决办法
8万
查看次数

如何在页面加载时处理辅助bean中的GET查询字符串URL参数?

我已经阅读了如何使用JSF发送参数但是如果用户companyId在访问其登录页面时在URL中键入它们会怎么样?例如,

http://my.company.url/productName/login.faces?companyId = acme.

我们现在的方式是,有一些scriptlet代码可以从请求中获取值,然后在会话中设置它.该参数从登录页面开始改变其外观,因此每个客户可以具有不同的登录页面视图.在切换到JSF之前,我们正在使用extj.

有没有办法使用JSF 2或PrimeFaces?

jsf query-string jsf-2 managed-bean http-request-parameters

31
推荐指数
3
解决办法
4万
查看次数

如何从托管bean中获取消息包字符串?

我希望能够从JSF 2托管bean内部的消息包中检索字符串.这可以在将字符串用作FacesMessage抛出异常中的消息中的摘要或详细信息参数的情况下完成.

我想确保托管bean为用户的语言环境加载正确的消息包.我不清楚如何使用JSF API调用从托管bean执行此操作.

我的配置是:

  • 使用Tomcat 7作为容器,因此解决方案不能依赖于仅在完整应用程序服务器容器中工作的API调用
  • 使用JSF 2参考实现(Mojarra)
  • 不使用任何允许CDI的库

注意:我确实看到了类似的问题,但这取决于我的配置中不可用的功能

编辑:我在原来的问题上犯了一个错误.我想要问的是"如何从托管bean中获取资源包字符串"?BalusC给了我正确的答案.我实际要问的解决方案非常相似:

public static String getResourceBundleString(
            String resourceBundleName,
            String resourceBundleKey)
        throws MissingResourceException {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ResourceBundle bundle = 
        facesContext.getApplication().getResourceBundle(
            facesContext, resourceBundleName);
    return bundle.getString(resourceBundleKey);
}
Run Code Online (Sandbox Code Playgroud)

此外,这里还有一个链接到另一个问题,解释了"消息"包和"资源"包之间的区别.

jsf jsf-2 managed-bean message-bundle

30
推荐指数
3
解决办法
6万
查看次数

如何以编程方式设置-Dorg.apache.el.parser.COERCE_TO_ZERO = false

这个问题类似于:

jsf:绑定到UI中的inputtext的整数属性在提交时设置为零

但我对解决方案并不完全满意.上下文是相同的:我有一个需要Integer值的Web表单.如果文本框留空,我希望我的整数字段为'null',而EL解析器会自动将我的id字段设置为'0'.

我可以通过在本地Tomcat VM中设置JVM参数来解决问题:

-Dorg.apache.el.parser.COERCE_TO_ZERO = FALSE

但是,这对我们客户的机器不起作用.是否可以在"代码内"设置/更改此JVM参数.

更新:我发现这是请求,但如果其他人有任何其他解决方法,我也想听到.

https://issues.apache.org/bugzilla/show_bug.cgi?id=48813

更新2:我无法将值从"0"更改为"null",因为我的应用程序应将"0"视为实际ID.所以我需要在运行时知道id文本框是否为空.

jsf tomcat el jvm-arguments managed-bean

25
推荐指数
1
解决办法
2万
查看次数

从Managed Bean函数调用Primefaces对话框

嗨,我有一个带有一些函数的托管bean,基于该函数中的一些条件,我想调用一个对话框

托管bean函数如下

public String editStudent(){    
    setReadOnly(false);     
    setButton(true, true, true, false, true, true,true);
    LockItem lItem;
    if(selectStudent !=null){
        lItem = (LockItem) services.getbyId("LockItem", condition);
        if (lItem == null){
            System.out.println("Student Avalibale for process :::"); 
            studentRedirect();
            return "studentEdit.jsf?faces-redirect=true";
        } else {
             //To show dialog from here
             System.out.println("Student Not Avalibale : Locked By " + lItem.getLockedBy());
        }
    } else {
        FacesMessage msg;
        msg = new FacesMessage("Please select the record.");
        FacesContext.getCurrentInstance().addMessage(null, msg);
        return show("menu");
    }
}
Run Code Online (Sandbox Code Playgroud)

是否有任何方法可以从这样的托管函数调用对话框

jsf modal-dialog primefaces managed-bean

24
推荐指数
3
解决办法
9万
查看次数