2011-09-14 48 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"); 
}