【发布时间】:2012-11-01 18:12:59
【问题描述】:
这可能是一种架构问题,但仍然必须有“最佳实践解决方案”或公认标准。
我说的是需要在网站上显示的某种静态数据,例如产品目录、菜单和菜单项列表、面包屑块列表等。我想这个选项在使用任何标准 CMS 时都可用.
但我想使用纯 JSF 解决方案来解决这个问题。
所以,回到这个问题,我的阐述基于以下原则:
-
数据不应该在 facelets 中硬编码,因此我使用数据库来保存值,就像在下面的 db 脚本(在我的例子中是 MYSQL)中一样:
CREATE TABLE CatalogueGroup ( CatalogueGroupName VARCHAR(100) NOT NULL PRIMARY KEY, URLPath VARCHAR(200) NOT NULL, ParentGroupName VARCHAR(100) DEFAULT NULL, FOREIGN KEY (ParentGroupName) REFERENCES CatalogueGroup(CatalogueGroupName) ON UPDATE CASCADE ON DELETE SET NULL )ENGINE=InnoDB DEFAULT CHARSET=utf8; -
然后我想使用要在@ManagedBean 中保存的实体类并将其显示在视图中,例如
public class CatalogueGroup implements Serializable { private String catalogueGroupName; private List<CatalogueGroup> children = new ArrayList<CatalogueGroup>(); private CatalogueGroup parentGroup; //other stuff of this bean } @ManagedBean @SessionScoped public class CatalogueBean implements Serializable { private CatalogueGroup catalogue;//loaded via CatalogueGroupDAO with condition parentGroup == null //other stuff of this bean } //snippet of xhtml view for a two-level catalogue <ul><h:outputText value="#{catalogueBean.catalogue.catalogueGroupName}" /> <ui:rereat value="#{catalogueBean.catalogue.children}" var="group"> <li><h:outputText value="#{group.catalogueGroupName}" /></li> </ui:repeat> </ul>
上述设置有效,但感觉很尴尬。 因此,我想向 jsf 社区提出以下公开的“最佳实践”问题:
- 像这样设置目录 bean 的正确方法是什么:
- 一个
@SessionScopebean,将被加载一次并在每个视图上重新显示或 -
@RequestScopedbean 将在每个页面显示时访问数据库。
- 一个
- 有没有办法在 facelet 视图中设置递归函数,或者我应该将目录嵌套级别限制为 2 或 3。
- 我想显示某种修改后的目录,根据他的角色(在数据库表中添加的列)向登录用户公开更多组,并在没有用户登录时显示基本目录。此外,我想偶尔在目录中插入一些新组,而不是强制用户重新登录,而是立即重新显示正确的数据:
- 我是否应该在业务层过滤组并将过滤后的 CatalogueGroup 公开给 bean,或者我将加载整个目录并将其子项限制在视图中,并设置为 render=false;
- 在会话中公开整个目录是否合适;
- 是否可以在将新数据库条目添加到服务器上所有当前处于活动状态的 CatalogueBean 时发送修改事件,以强制刷新其属性(CatalogueGroup)或实现此功能,我只需要使用
@RequestScopedbean; - 如果使用请求范围的 bean 是唯一的选择,那么明智的做法是访问数据库以频繁获取数据以致很少更改,或者有更智能的处理方式;
- 当用户登录(和注销)时,已经有一个会话范围目录的实例,如何刷新它:我需要在动作/动作侦听器中手动执行它还是需要使会话无效或更合适的操作视情况而定。
【问题讨论】:
标签: jsf-2 managed-bean