JSF 访问private/protected属性 超级class
JSF access private/protected property of a super class
我是 JSF 的新手,这是我从事的第一个项目(jsp 有点太懒了)所以如果问题很简单,请原谅我。
所以我有一个超级 Class 设备
@Entity
@Table(name = "Devices")
public class Device
{
protected bool Authorized
public bool isAuthorized()
{ return this.Authorized;}
public void setAuthorized(bool Authorized)
{ this.Authorized = Authorized;}
}
和扩展超级 Class 设备的子 class SensorDevice
public class SensorDevice extends Device
{
// has its own properties which dont matter
}
和一个托管 Bean UIDeviceManager
@ManagedBean(name = "DeviceManager")
@SessionScoped
public class UIDeviceManager
{
private List<SensorDevice> Pending;
// in constructor, Pending List gets populated with the devices requiring Authorization
}
和一个 xhtml 页面,其中包含一个 Table 用于未决设备
<p:dataTable var="device" value="#{DeviceManager.pending}">
<p:column headerText="Device Authorization">
<h:form>
<p:inputSwitch
value="#{device.isAuthorized()}"
binding="#{AuthorizationInputSwitch}"
offLabel="UnAuthorized"
onLabel="Authorized">
<p:ajax
event="change"
listener="#{device.setAuthorized(AuthorizationInputSwitch.value)}" />
</p:inputSwitch>
</h:form>
</p:column>
现在除非 xhtml 中的语法完全搞砸了(我在那里尽力而为,希望得到指导),否则应该调用该特定设备实例的函数 setAuthorized(即使输入错误,但会对其进行排序稍后通过修改 setter 函数),但这并没有发生, Ajax 没有被调用。相反,inputSwitch 尝试更新其 "value property source" 并尝试在 class SensorDevice 中查找 属性 isAuthorized(),但未能找到。
现在我知道这可以通过在 super class 中设置 Boolean Authorized public 来轻松解决,但如您所见,它也是一个持久保存在数据库中的 JPA 实体跟踪设备,因此唯一的选择是保护它。
那么我如何从 public 函数的托管 Bean 中的子 class 实例更新超级 class 的参数,而不是直接访问参数本身 (我以为 JSF 会寻找 setters 和 getters 但无论如何)
顺便说一句 value="#{device.isAuthorized()}"
工作正常,但如果我直接尝试 属性 它会失败(我想这在这一点上很明显)
最后一件事,如果 approach/architecture 有误,请告知实现此功能的正确布局是什么。我确信有一种标准方法可以集成 JSF 和 JPA 而无需复制实体和包装器
我认为您必须像这样在 InputSwitch 组件的值属性中使用字段名称:
<p:inputSwitch
value="#{device.authorized}"
binding="#{AuthorizationInputSwitch}"
offLabel="UnAuthorized"
onLabel="Authorized">
而不是:
<p:inputSwitch
value="#{device.isAuthorized()}"
binding="#{AuthorizationInputSwitch}"
offLabel="UnAuthorized"
onLabel="Authorized">
JSF 将使用 isAuthorized 和 setAuthorized 方法(使用 Java Beans 标准约定来识别 getter 和 setter 方法)
所以我认为您不需要 ajax 部分来调用 setter 方法。
为了强调 Mojtaba 的回答,这是您在 JSF 中访问属性的方式:
Facelets 页面:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:outputText value="#{myBean.entity.someBool}"/>
</h:body>
</html>
托管 bean:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@ManagedBean
@SessionScoped
public class MyBean {
private SomeEntity entity = new SomeEntity();
public SomeEntity getEntity() {
return entity;
}
}
实体类:
public class SomeEntity extends SomeParent {
}
public class SomeParent {
private boolean someBool = true;
public boolean isSomeBool() {
return someBool;
}
public void setSomeBool(boolean someBool) {
this.someBool = someBool;
}
}
JSF 不知道也不关心您的对象是 JPA 实体,并且适用标准继承和访问规则。
另见
我是 JSF 的新手,这是我从事的第一个项目(jsp 有点太懒了)所以如果问题很简单,请原谅我。 所以我有一个超级 Class 设备
@Entity
@Table(name = "Devices")
public class Device
{
protected bool Authorized
public bool isAuthorized()
{ return this.Authorized;}
public void setAuthorized(bool Authorized)
{ this.Authorized = Authorized;}
}
和扩展超级 Class 设备的子 class SensorDevice
public class SensorDevice extends Device
{
// has its own properties which dont matter
}
和一个托管 Bean UIDeviceManager
@ManagedBean(name = "DeviceManager")
@SessionScoped
public class UIDeviceManager
{
private List<SensorDevice> Pending;
// in constructor, Pending List gets populated with the devices requiring Authorization
}
和一个 xhtml 页面,其中包含一个 Table 用于未决设备
<p:dataTable var="device" value="#{DeviceManager.pending}">
<p:column headerText="Device Authorization">
<h:form>
<p:inputSwitch
value="#{device.isAuthorized()}"
binding="#{AuthorizationInputSwitch}"
offLabel="UnAuthorized"
onLabel="Authorized">
<p:ajax
event="change"
listener="#{device.setAuthorized(AuthorizationInputSwitch.value)}" />
</p:inputSwitch>
</h:form>
</p:column>
现在除非 xhtml 中的语法完全搞砸了(我在那里尽力而为,希望得到指导),否则应该调用该特定设备实例的函数 setAuthorized(即使输入错误,但会对其进行排序稍后通过修改 setter 函数),但这并没有发生, Ajax 没有被调用。相反,inputSwitch 尝试更新其 "value property source" 并尝试在 class SensorDevice 中查找 属性 isAuthorized(),但未能找到。
现在我知道这可以通过在 super class 中设置 Boolean Authorized public 来轻松解决,但如您所见,它也是一个持久保存在数据库中的 JPA 实体跟踪设备,因此唯一的选择是保护它。
那么我如何从 public 函数的托管 Bean 中的子 class 实例更新超级 class 的参数,而不是直接访问参数本身 (我以为 JSF 会寻找 setters 和 getters 但无论如何)
顺便说一句 value="#{device.isAuthorized()}"
工作正常,但如果我直接尝试 属性 它会失败(我想这在这一点上很明显)
最后一件事,如果 approach/architecture 有误,请告知实现此功能的正确布局是什么。我确信有一种标准方法可以集成 JSF 和 JPA 而无需复制实体和包装器
我认为您必须像这样在 InputSwitch 组件的值属性中使用字段名称:
<p:inputSwitch
value="#{device.authorized}"
binding="#{AuthorizationInputSwitch}"
offLabel="UnAuthorized"
onLabel="Authorized">
而不是:
<p:inputSwitch
value="#{device.isAuthorized()}"
binding="#{AuthorizationInputSwitch}"
offLabel="UnAuthorized"
onLabel="Authorized">
JSF 将使用 isAuthorized 和 setAuthorized 方法(使用 Java Beans 标准约定来识别 getter 和 setter 方法)
所以我认为您不需要 ajax 部分来调用 setter 方法。
为了强调 Mojtaba 的回答,这是您在 JSF 中访问属性的方式:
Facelets 页面:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:outputText value="#{myBean.entity.someBool}"/>
</h:body>
</html>
托管 bean:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@ManagedBean
@SessionScoped
public class MyBean {
private SomeEntity entity = new SomeEntity();
public SomeEntity getEntity() {
return entity;
}
}
实体类:
public class SomeEntity extends SomeParent {
}
public class SomeParent {
private boolean someBool = true;
public boolean isSomeBool() {
return someBool;
}
public void setSomeBool(boolean someBool) {
this.someBool = someBool;
}
}
JSF 不知道也不关心您的对象是 JPA 实体,并且适用标准继承和访问规则。