簡體   English   中英

將自定義事件偵聽器添加到Java bean中以進行設置

[英]Adding a custom event listener into java bean for setters

我有一個具有很多特性的bean,其中一半具有n對n的關系。 我還添加了其他瞬態' isEdited '布爾值,以確保用戶進行了一些更改,以便減少所有實體的數據庫獲取。 我當前的問題有時需要序列化bean,並想將屬性與真實實例進行比較。 我嘗試過的第一個解決方案是來自apache commons-lang => EqualsBuilder.reflectEqual(); 該方法對我而言效果不佳,因為某些繼承項無法以正確的方式實現equals方法,因此我無法對其進行編輯。 我知道我可以添加ajax偵聽器來更新已編輯的屬性,也可以更新每個setter方法或新的equals實現。 但是我正在尋找一些更實用和通用的方法,以便將來也可以使用此實現。

所以我想要什么:(可以說我有一個簡單的bean):

public class Foo {

    private String prop1;

    private String prop2;

    /**
     * @return the prop1
     */
    public String getProp1() {
        return prop1;
    }

    /**
     * @param prop1 the prop1 to set
     */
    public void setProp1(String prop1) {
        this.prop1 = prop1;
    }

    /**
     * @return the prop2
     */
    public String getProp2() {
        return prop2;
    }

    /**
     * @param prop2 the prop2 to set
     */
    public void setProp2(String prop2) {
        this.prop2 = prop2;
    }



}

比我的bean將實現EventListener接口,並且此偵聽器將處理所有的setter。 如果調用了任何setter方法(初始化后),那么edited屬性將設置為true。

所以我的問題是添加動作/事件偵聽器以處理設置程序的正確方法是什么?

編輯**我已經嘗試過PropertyChangeListener,但是沒有得到任何事件輸出。 如果我添加每個設置器pcs.firePropertyChange(); 方法,那么通過這些方法將isEdited設置 true 毫無意義。

您不能擁有Map<String,Boolean>並用每個設置器更新它嗎? prop1為例:

public void setProp1(String prop1) { 
    if(!prop1.equals(this.prop1))
        updateMap.put("prop1", true);
    this.prop1 = prop1;
}

這樣,在保存實體的同時,您將獲得一個帶有“元數據”的地圖。

編輯:有一個缺點很難,因為如果用戶設置一個值然后返回到原始,該地圖將保持不變。 您可以通過使用另一個映射(或克隆您的對象)來使用原始值來比較兩者,從而避免這種情況:

public void setProp1(String prop1) { 
    if(!prop1.equals(this.prop1) && !prop1.equals(ORIGINAL_VALUE))
        updateMap.put("prop1", true);
    else
        updateMap.put("prop1", false);
    this.prop1 = prop1;
}

編輯:亞當是正確的方面,確實,這是一項更改,可能會花費您一些時間。 另外,如果您想使用反射,則還有另一個問題,因為您與方法的結構有關。 將來,如果您想更改方法的名稱或類型,則也必須更新該反射幫助器類。

我建議在保存它們之前先更新時間值,以便您可以將它們與原始值進行比較,但是如果直接訪問字段/對象而沒有獲取方法,那將涉及更改方法。

最后,第三個選項(總是有第三個選項),我認為您可能願意做的是在組件中使用valueChangeListener 例如:

<h:inputText id="prop1Input" value="#{bean.prop1}" valueChangeListener="#{bean.changesListener}"/>

並且您的bean應該具有一個具有以下結構的方法:

public void changesListener(ValueChangeEvent e) {
    //Get the new value
    Object o = e.getNewValue();
    //get the component's id
    String componentId = e.getComponent().getId();
    //Cast the value and compare it, after that you should update a map. You are
    //going to need one anyway to know which field changed.
    boolean valueChanged = //compare against original value
    if(componentId.equals("prop1Input"));
    map.put("prop1", valueChanged);
}

關於此方法的重要說明,偵聽器將在驗證階段執行。 該偵聽器的目的是能夠處理新舊價值,這似乎是您的情況。 因為您還可以知道觸發它的組件,所以應該沒問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM