JSF访问超类的私有/受保护属性

时间:2016-04-20 21:49:46

标签: jsf jsf-2 primefaces properties superclass

我是JSF的新手,这是我工作的第一个项目(对jsp有点太懒)所以请原谅我,如果问题是微不足道的。 所以我有一个超级设备

@Entity
@Table(name = "Devices")
public class Device
{
    protected bool Authorized

    public bool isAuthorized()
      { return this.Authorized;}
    public void setAuthorized(bool Authorized)
      { this.Authorized = Authorized;}
}

和扩展超类设备的子类SensorDevice

public class SensorDevice extends Device
{
  // has its own properties which dont matter
}

和Managed 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页面,其中包含待处理设备的表

<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尝试更新其&#34;值属性源&#34;并尝试在SensorDevice类中查找属性isAuthorized(),但无法找到它。

现在我知道这可以通过在超类中使布尔授权公共来轻松解决,但正如您所看到的那样,它也是一个持久存储在数据库中以跟踪设备的JPA实体,所以这是唯一的选项是保护它。

那么如何从公共函数更新Managed Bean中的子类实例来更新Super类的参数,而不是直接访问参数本身(我认为JSF寻找setter和getter,但无论如何)

顺便说一句value="#{device.isAuthorized()}"正常工作,但如果我直接尝试该属性就会失败(我猜这在此时很明显)

最后一点,如果方法/架构错误,请告知实现此功能的正确布局。我确信有一种标准方法可以集成JSF和JPA,而无需复制实体和包装器

2 个答案:

答案 0 :(得分:2)

我认为你必须在InputSwitch组件的value属性中使用字段名,如下所示:

<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方法。

答案 1 :(得分:1)

为了强调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实体,并且适用标准继承和访问规则。

另见