2011-09-14 86 views
2

我們允許用戶在我們的Web應用程序中設置一些偏好。當他們登錄到某些網站時,他們被允許做/看到不同的屏幕,而不是他們在另一個網站。我們的一項要求是,我們隱藏了他們在當前登錄網站無法訪問的頁面上的偏好設置。目前我們正在使用Spring MVC來處理這些請求。反射是我最好的選擇嗎?

這裏是我們POJO的簡化示例:

public class Preferences { 
    boolean prefA; //Valid when can do A 
    String prefB; //Valid when can do B 
    Integer prefC; //Valid when can do C 
    .... 
    Long prefZ; //Valid when can do Z 
} 

這裏是控制器的代碼:

@RequestMapping(method = RequestMethod.POST, value = "preferences.xhtml") 
public ModelAndView updateRequestPreferences(@ModelAttribute(USER_PREFERENCES) final Preference preferences, final BindingResult results) 
{ 
    return updatePreferences(preferences, results); 
} 

目前updatePreferences確實反射,並確保它仍然存在的之前的值不爲空輸入首選項 - 這是由於Spring MVC創建首選項的新實例,然後使用UI上的內容填充值。

我們可以做的偏好二傳手如下:

public void setPreferences(Preferences preferences) { 
    if (preferences.getPrefA() != null) { 
    this.preferences.setPrefA(preferences.getPrefA()); 
    } 
    if (preferences.getPrefB() != null) { 
    this.preferences.setPrefB(preferences.getPrefB()); 
    } 
    ... 
    if (preferences.getPrefZ() != null) { 
    this.preferences.setPrefZ(preferences.getPrefZ()); 
    } 
} 

它會得到笨拙,甚至與助手功能,在setter方法所有的檢查(和似乎是一個簡單的步驟時往往忘記創建一個新的偏好);同時反射看起來像是一個警察。有沒有更好的方法來重構這個?

+0

反射/內省不是警察出局。這是很好的設計! – JustinKSU

+0

根據您的首選項對象中的內容,好的老式名稱/值對是否有效? –

+0

@Paul然後我們需要在數據庫中另存一個blob來存儲這些值(如果你看看我之前的一個問題),我寧願避免。我得到了一個「擴展BadDBDesign」的+1 ... – Scott

回答

1

您可以配置Spring MVC來填充預先存在的對象的字段,而不是創建一個新的對象。

例如,您可以使用@SessionAttributes(USER_PREFERENCES)Preferences的實例存儲在呈現表單和處理其提交之間的會話中。

另一種方法是從數據庫中作爲一個隱含的模型屬性加載的Preferences新實例:

@ModelAttribute(USER_PREFERENCES) 
public Preferences loadPreferences(@RequestParam("key") String key) { 
    return loadPreferencesByKey(key); 
} 

注意,在所有情況下(與原來的方案需要它),你需要指定一組允許在@InitBinder方法中允許的字段,以防止惡意用戶修改未在表單中呈現的字段:

@InitBinder(USER_PREFERENCES) 
public void initBinder(WebDataBinder b) { 
    b.setAllowedFields("prefA", "prefB"); 
}