我正在尝试在XPage项目中实现适当的图层分离。理想情况下,我试图达到XPage中的XML不包含SSJS并仅使用EL来访问Java对象的程度。
到目前为止,我已经研究了如何将我的所有数据从domino数据库加载到Java Bean(其中1个文档= 1个对象,或多或少),我正在将视图内容读入Java Maps或Lists,而我我们设法在重复控件中显示这些集合的内容。
我不确定的是如何在不引用多米诺骨牌文档的情况下显示单个文档的“表单”的内容。特别是,我不确定如何处理“新文件”案件。我想我创建了一个空对象,然后将该对象设置为Xpage的数据源。
我知道我必须使用ObjectDataSource,但我不确定在哪里存储它。我读了Stephan Wissel的一篇文章,说不应该把它们放在托管bean中,那么我在哪里可以把它放进去?在其中一个范围变量,如viewScope?
现在我写了一个'ApplicationBean',它是一个会话范围的Managed Bean,我存储了所有的对象。
最佳做法是什么?似乎有许多不同的方法来实现这一目标。目前我正在探索ChristianGüdemann的XPages工具包,这听起来非常有前途。我知道Samir Pipalia,John Daalsgard和Frank van der Linden已经制定了自己的框架。
那我应该怎么做呢?有任何陷阱吗?
答案 0 :(得分:5)
这确实是一个很大的话题。正如Paul所提到的,Tim的文档模型类是如何清楚地做到这一点的一个很好的例子,Tim在后续的NotesIn9系列剧集中详细介绍了。我自己的Framework模型对象非常相似,但我还添加了collection managers来处理访问视图的脏业务。无论好坏,几乎每个XPage开发人员都以独特的方式解决了这个问题。
有很多方法可以实现这类事情,在正常情况下,一些差异并不是非常重要(例如,在构建模型时是否预先加载文档中的所有数据只在需要的时候反对或延迟抓取到后端),但肯定有几个要解决的首要问题。
正如您在问题中提到的,其中一个重大问题是您如何从XPage实际访问模型对象 - 如何从数据库中提取对象或重新创建对象。我的框架模型对象使用了一个自负的经理&#34;对象,它们是应用程序范围的bean,允许获取命名集合(映射到视图),通过UNID建模对象,或通过关键字&#34; new&#34;获取新模型对象。通常,这些模型(可序列化)然后通过<xp:dataContext/>
,<xe:objectData/>
或框架自己的<ff:modelObjectData/>
存储在页面的视图范围内。 / p>
我发现避免使用托管bean来表示单个对象非常明智(例如&#34; CurrentWhatever&#34;然后你会在每个页面上填充数据),因为这会弄乱你的face-config在最好的情况下或遇到最坏的会话问题(如果你把它放在会话范围,我很少使用)。
如何实施&#34; new&#34; vs.&#34; fetched&#34;模型对象在很大程度上取决于你在第一时间编写模型时所采用的方法,但大多数情况下归结为有两个构造函数:一个用UNID(至少)指向现有文档,另一个用于创建一个新文档。如果你去&#34;用getter和setter&#34;在对象中明确地写出每一个。 route,后者还会使用默认值初始化所有字段,而不是从文档中读取它们。在内部,您应该有字段来存储文档的UNID,这可以指示它是否是新的 - 然后,您的保存方法可以检查此字段是否为空并在需要时创建新文档(然后存储新文件的UNID在该领域。)
听起来你已经将你的模型集合读入List
,这很好。然而,其中一个缺点是可伸缩性:如果收集量很小(少于100个),您可能不会遇到任何加载速度问题,但事后在初始页面加载时会因为代码而变慢提前读取整个视图。您可以使用efficient view reading稍微缓解此问题,但这是一个限制。内置视图通常很快,因为它们只根据需要加载数据(它们也像地狱一样欺骗,但这是另一个问题)。
这是一个以自己为目标的崇高目标,但这样做是为了涵盖所有案例no small feat:你最终会遇到FT搜索,栏目诉求,高效数据预加载的问题(你不要这样做)想要重新打开View对象只能一次读入一个条目,但是你也不想阅读整篇文章,在viewPanel
和其他人(需要专门的接口)中使用,扩展/折叠类别等等。它是large sub-topic on its own。
您也可能会遇到其他比您更难以思考的领域,例如&#34;正确的&#34;富文本处理和文件附件。特别是附件需要direct conflict with the XSP framework才能使用自定义模型对象和标准上传/下载控件正常运行。
字段名称中的区分大小写是另一个潜在的麻烦区域。如果您要为所有字段编写getter和setter,那么这是一个没有实际意义的问题,但是如果您正在使用&#34; thin wrapper&#34;路由(我更喜欢),以一种处理&#34; FOO&#34;的方式对任何中间缓存/查找进行编码很重要。和&#34; foo&#34; (基本上)与Notes的项目名称相同,但在Java中是不同的。我采取的方法是制作extensive use of TreeMap
s:如果您将String.CASE_INSENSITIVE_ORDER
作为参数传递给构造函数,它会在用作键时将处理字符串视为通常不区分大小写。
让你的模型对象与所有标准控件一起工作,这可能是也可能不是优先考虑 - 我发现它很有价值,所以我做了大量的工作来实现我的框架,但如果你&#39;我只想做一些基本的弦乐和数字模型,你不必担心。
所以......是的,这是一个很大的话题!根据您对Java和XPage undergirding的信心程度,我建议您选择使用相当简单的bean和getters and setter&#34;对于您的对象或通过查看现有框架之一(我自己或您提到的框架)的实现细节。可悲的是,随着代码变得越来越复杂,有许多小问题会出现,其中很多都是不明显的。
答案 1 :(得分:2)
Jesse Gallagher的Scaffolding框架也可以访问Java对象而不是dominoDocument数据源。我在NotesIn9的“使用Java XPage系列丛书”中使用(并修改过)Tim Tripcony的Java对象(第一个是episode 132。他所做的源代码是BitBucket。将dominoDocument转换为Map。它不包括MIME(Rich Text)或附件。如果它有用,我可以分享我所做的修改(例如,使字段名称完全相同,以确保它仍适用于现有文档,其中可以使用LotusScript创建字段。
答案 2 :(得分:0)
安德鲁 - 杰西是这里的专家之一,所以我仔细阅读了他的回复。
我做的是我采用了Jesses更大框架的一个关键部分 - “pageControllers”,我使用了那个HEAVILY。所以我最终得到了每个XPage的Java类作为控制器。 “所有”Jesse的页面控制器框架确实让它更容易消费。因此,您可以在每个页面上将其作为“控制器”引用,并且不要为它们制作单独的托管bean。
我仍然会在XPage上使用SOMES SSJS,如果我真的需要像按钮事件这样的东西..一些没有正确的getter和setter的方法。例如HashMap.size()。但是大量的代码都进入了Java类。也不再需要viewScope变量。
在“新文档”的情况下..在控制器中,我将创建一个代表“当前文档”的新Java对象。我将所有字段绑定到那个。如果是新的,我创建一个新的Object并将其分配给私有变量。如果我在某处加载表单,那么我将获取该变量并加载我想要的文档。
我已经开始尝试在最近的NotesIn9中详细说明这一点。尤其是Java for Xpages开发人员的小系列。我想我已经足够了解你需要知道什么。我计划尽快在这个主题上做更多的事情。