我使用布尔切换器来解决应用程序的选定行为,例如SAVEACCEPTED启用表单的SAVE按钮。
<h:commandButton action="#{bean.save}" disabled="#{!bean.saveaccepted}">
JSF需要私有布尔值及其getter和setter,但若我想解析应用程序服务器中的一些内部逻辑,就必须将其定义为静态逻辑。例如
IF (USERFOUND) SAVEACCEPTED = true;
所以,我使用的是settings类,并且定义了公共静态布尔值。在bean中有getter和setter指向Settings。可变
Settings.java
public static boolean SAVEACCEPTED = false;
Bean.java
public static boolean isSaveAccepted() {
return Settings.SAVEACCEPTED;
}
问题是,公共布尔值只有一个,如果有多个用户使用一个应用程序,当第一个切换变量时,它会影响第二个用户表单
我该如何解决这个问题,是否有一些标准的解决方案?
不要使用static
变量。使用@SessionScoped
或@ViewScoped
bean分别为每个用户存储设置。
@Named
@SessionScoped
public class Settings
{
private boolean saveAccepted = false;
public boolean isSaveAccepted()
{
return saveAccepted;
}
public void setSaveAccepted(boolean saveAccepted)
{
this.saveAccepted = saveAccepted;
}
}
和
<h:commandButton action="#{bean.save}" disabled="#{!settings.saveaccepted}">
如果我需要在另一个bean(而不是JSF)中设置saveAccepted=true,该怎么办?它不起作用,因为在这种情况下,saveAccepted必须是静态的。
不要使用静态变量
如果需要在另一个bean中设置值,可以@Inject
一个实例:
@Named
@RequestScoped
public class SomeOtherBean
{
@Inject
private Settings settings;
public boolean getSaveAccepted()
{
return settings.getSaveAccepted();
}
public void setSaveAccepted(boolean saveAccepted)
{
settings.setSaveAccepted(saveAccepted);
}
}
CDI将为您提供正确的CCD_ 5实例。
BalusC评论:
根据问题历史,OP正在使用Tomcat,它只是一个简单的servlet容器。
由于看起来您没有使用完整的JavaEE6容器,因此可以使用@ManagedBean
代替@Named
,使用@ManagedProperty
代替@Inject
。
@ManagedBean
@RequestScoped
public class SomeOtherBean
{
@ManagedProperty
private Settings settings;
public boolean getSaveAccepted()
{
return settings.getSaveAccepted();
}
public void setSaveAccepted(boolean saveAccepted)
{
settings.setSaveAccepted(saveAccepted);
}
}
我很抱歉让你走上了一条更复杂的道路!
在这种情况下使用静态变量并不理想。根据定义,静态字段在类的所有实例之间共享。因此,正在发生的事情是,您存储的值正在为托管bean的所有实例共享。
我建议您使用@ViewScoped
将其保存在请求范围中,或者使用<managed-bean-scope>
在faces-config.xml中定义它。