我认为有两种通用方法可以获得一个自动创建的CDI托管bean实例BeanManager
,只需要一个Bean<T>
开始(基于它创建Class<T>
):
通过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)通过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)
该的javadoc的Context#get()
是非常明确的在此:
返回某个上下文类型的现有实例,或通过调用Contextual.create(CreationalContext)创建一个新实例并返回新实例.
而javadoc中的BeanManager#getReference()
不够明确在此:
获得某个bean和bean的某个bean类型的上下文引用.
这让我感到困惑.你什么时候使用这一个?对于这两种方式,无论如何都需要一个Bean<T>
实例,bean类和bean范围随时可用,这是额外的参数.我无法想象为什么在这种特殊情况下他们需要外部供应.
我可以想象这Context#get()
是更高效的内存,因为它不会不必要地创建引用同一个底层bean实例的另一个代理实例,而只是查找并重用现有的代理实例.
这让我想到了以下问题:什么时候BeanManager#getReference() …
我似乎无法找到一种方法来强制在启动Web应用程序时实例化/初始化应用程序范围的托管bean.似乎应用程序范围的bean在第一次访问bean时会进行惰性实例化,而不是在启动Web应用程序时实例化.对于我的Web应用程序,当第一个用户第一次在Web应用程序中打开页面时,就会发生这种情况.
我想避免这种情况的原因是因为在我的应用程序范围的bean初始化期间发生了许多耗时的数据库操作.它必须从持久存储中检索一堆数据,然后以ListItem元素等形式缓存一些频繁显示给用户的数据.我不希望在第一个用户连接时发生这一切,因此导致长时间的延迟.
我的第一个想法是使用旧式ServletContextListener contextInitialized()方法,并从那里使用ELResolver手动请求我的托管bean的实例(从而强制初始化发生).不幸的是,我无法在此阶段使用ELResolver来触发初始化,因为ELResolver需要FacesContext并且FacesContext仅在请求的生命周期内存在.
有没有人知道另一种方法来实现这一目标?
我使用MyFaces 1.2作为JSF实现,目前无法升级到2.x.
我可以将输入文本字段值传递给bean方法而不将值绑定到bean属性吗?
<h:inputText value="#{myBean.myProperty}" />
<h:commandButton value="Test" action="#{myBean.execute()} />
Run Code Online (Sandbox Code Playgroud)
我可以不进行临时保存#{myBean.myProperty}
吗?
有没有办法如何从Java方法将页面重定向到其他页面?
我只能使用以下方式转发它:
FacesContext.getCurrentInstance().getExternalContext().dispatch("/foo.xhtml");
Run Code Online (Sandbox Code Playgroud)
或使用导航规则faces-config.xml
.
你有什么想法?
我是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中的托管bean调用(执行)JavaScript函数?
如果这是相关的,我也使用PrimeFaces.
我已经阅读了如何使用JSF发送参数但是如果用户companyId
在访问其登录页面时在URL中键入它们会怎么样?例如,
http://my.company.url/productName/login.faces?companyId = acme.
我们现在的方式是,有一些scriptlet代码可以从请求中获取值,然后在会话中设置它.该参数从登录页面开始改变其外观,因此每个客户可以具有不同的登录页面视图.在切换到JSF之前,我们正在使用extj.
有没有办法使用JSF 2或PrimeFaces?
我希望能够从JSF 2托管bean内部的消息包中检索字符串.这可以在将字符串用作FacesMessage
抛出异常中的消息中的摘要或详细信息参数的情况下完成.
我想确保托管bean为用户的语言环境加载正确的消息包.我不清楚如何使用JSF API调用从托管bean执行此操作.
我的配置是:
注意:我确实看到了类似的问题,但这取决于我的配置中不可用的功能
编辑:我在原来的问题上犯了一个错误.我想要问的是"如何从托管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:绑定到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文本框是否为空.
嗨,我有一个带有一些函数的托管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)
是否有任何方法可以从这样的托管函数调用对话框
managed-bean ×10
jsf ×9
cdi ×2
jsf-2 ×2
primefaces ×2
el ×1
java-ee ×1
javascript ×1
modal-dialog ×1
query-string ×1
redirect ×1
startup ×1
tomcat ×1