网站数据统计,wordpress搭建外贸网站,深圳企业网站制作企业,wordpress 备份页面wicketApache Wicket Web框架的核心概念之一是模型和IModel作为其编程接口。 Wicket组件严重依赖模型#xff0c;这使它们成为体系结构的重要组成部分。 Apache Wicket是一个有状态框架#xff0c;将页面及其组件存储到通常位于HTTP会话中的页面存储中。 组件根据模型的内容创… wicket Apache Wicket Web框架的核心概念之一是模型和IModel作为其编程接口。 Wicket组件严重依赖模型这使它们成为体系结构的重要组成部分。 Apache Wicket是一个有状态框架将页面及其组件存储到通常位于HTTP会话中的页面存储中。 组件根据模型的内容创建面向公众的视图。 错误使用模型可能会导致尴尬的副作用例如页面无法更新其内容或应用程序占用大量内存。 从我所看到的新的Wicket用户遇到的大多数问题是正确使用模型。 在这篇博客文章中我将尝试解释在不同的用例中应如何以及应使用哪种模型。 Wicket IModel实现中最基本的是Model类。 它基本上是模型内容的简单占位符。 这非常适合模型内容不占用太多内存并且更像是常量的情况。 一个简单的String可能是Model内容的理想选择。 IModelString name new ModelString(John); 您必须了解即使创建包含模型的页面创建模型对象时其内容也将保持不变。 此行为是由于使用静态模型引起的。 每次从模型询问值时动态模型都可以更改实际内容。 新的Wicket用户经常使用静态模型而不是动态模型。 如果您不清楚静态模型和动态模型的概念则应阅读《 Wicket in Action 》一书中的第4章“了解模型” 。 IModelDate date new ModelDate() {Overridepublic Date getObject() {return new Date();}
}; 上面的动态日期模型是通过重写getObject方法从Model创建为匿名类的。 模型将始终返回包含当前时间的Date的新副本。 Wicket是有状态的Web框架模型通常存储在用户的HTTP会话中。 模型中的数据很可能是从数据库或通过某些Web服务获取的。 如果使用静态模型方法我们将很快吞噬大量内存并且如果重新加载页面将无法从数据源获得全新的视图。 如果我们决定像对Date对象那样使用动态模型则最终可能会在一页加载内进行大量数据库搜索或Web服务调用。 匿名内部类也不是很好看的代码。 Wicket有一个针对此问题的内置解决方案LoadableDetachableModel可以缓存模型的内容直到可以安全丢弃为止从而提供了有效但仍动态的模型。 public class PersonModel extends LoadableDetachableModelPerson {private Long id;private PersonService personService;public PersonModel(final Long id, final PersonService personService) {super();this.id id;this.personService personService;}public PersonModel(final Person person, final PersonService personService) {super(person);this.id person.getId();this.personService personService;}Overrideprotected Person load() {return personService.findById(id);}
} 上面的示例构造了一个可加载和可拆卸的模型用于通过其唯一标识符加载一个人。 该模型有两个构造函数这是有原因的。 之一来创建在拆卸状态下的延迟加载模式将加载内容当getObject方法被调用第一次和一个以在安装状态的模型不需要到PersonService呼叫时的getObject方法是叫。 最好为所有LoadableDetachableModels提供这两个构造函数。 您可以在已拥有内容的情况下以附加状态创建模型或者在只有标识符可用时以分离状态创建模型。 可装载可分离模型的警告是模型的私有字段。 Wicket将模型和组件一起存储在页面存储中这可能需要对模型进行序列化。 当模型被序列化时私有字段也被序列化实际内容被分离。 我们的id字段不是问题因为它可以序列化但是PersonService可能是问题。 通常服务层的接口默认情况下是不可序列化的。 至少有两种不错的解决方案使服务可序列化或者更好的方法是将服务包装在可序列化的代理中。 代理行为可以例如通过与不同的依赖项注入框架例如集成来实现。 春天wicker-spring或Guicewicket-guice。 集成模块可确保在注入服务代理时将它们可序列化。 public class ProfilePage extends WebPage {SpringBeanprivate PersonService personService;public ProfilePage(final PageParameters parameters) {super(parameters);Long id parameters.get(id).toLongObject();IModelPerson personModel new PersonModel(id, personService);add(new ProfilePanel(profilePanel, personModel));}
} 上面的示例使用wicket-spring集成将人员服务注入到所需页面。 SpringBean批注提供了一个可序列化的代理因此当我们创建人员模型时我们不必担心服务的序列化。 Wicket不允许构造函数注入因为当我们调用super构造函数时所有注入魔术实际上都会发生。 这意味着我们在Component的基本构造函数完成之后初始化注入的值。 只需记住对数据使用可序列化的标识符或定位符对服务使用可序列化的代理。 通常在MVC Web框架中视图层使用某种数据传输对象来构建视图。 DTO组成并继承以创建不同类型的视图。 为这些对象建立工厂或映射器可能容易出错或令人沮丧。 Wicket针对此问题提供了不同的解决方案。 在Wicket中您可以认为IModel接口的工作方式类似于关系数据库视图该视图允许您以不同的方式显示域的所需部分。 public class PersonFriendsModel extends AbstractReadOnlyModelString {private IModelPerson personModel;public PersonFriendsModel(final IModelPerson personModel) {super();this.personModel personModel;}Overridepublic String getObject() {Person person personModel.getObject();IterableString friendNames Iterables.transform(person.getFriends(),new PersonNameFunction());return person.getName() s friends are Joiner.on(, ).join(friendNames);}Overridepublic void detach() {personModel.detach();}private class PersonNameFunction implements FunctionPerson, String {public String apply(final Person input) {return input.getName();}}
} 在这里我们构建了一个模型该模型可以构成我们先前创建的PersonModel。 我们将其用作来源以建立该人的好友列表。 我们正在扩展的模型是Wicket提供给我们的AbstractReadOnlyModel。 它基本上是普通模型但不允许设置模型内容。 这非常有道理因为我们正在构建一个连接的String并且解析一个相似的列表并从该列表中设置该人的朋友会很尴尬。 我们仅将此模型用于只读目的以在视图中显示朋友列表。 您可以在此处看到类似的视图我们仍在使用相同的Person域模型但是在模型的帮助下从中公开了一个自定义视图。 请注意我们将detach方法委托给了组合模型。 这可以确保如果我们在任何组件中都没有直接引用组成的模型则仍然可以将其与好友模型分离。 多次调用detach方法无害因此即使从多个组件中使用也很安全。 我们仅创建了一个简单的模型合成示例。 您应该探索Wicket的内置模型实现并花一些时间来研究如何使用域模型来创建合理的模型。 只需记住一件事组成和扩展模型而不是域对象。 我最后要谈的是属性模型。 它们在许多Wicket应用程序中得到了广泛使用甚至《 Wicket in Action》一书也鼓励使用它们但是它们具有一些不需要的功能。 属性模型的代码编写速度快且易于使用但是它们使您的代码成为“字符串类型”。 这是我们不希望使用Java这样的类型安全语言的东西。 PropertyModelString nameModel new PropertyModelString(personModel, name); 我们使用PropertyModel从人的名字创建一个模型。 名称模型可以使用直接的Person对象或为我们提供人物的IModel。 可以通过实现Wicket的IChainingModel接口来实现此功能。 我们这里有两个问题。 第一个是名称模型的类型。 我们定义名称必须为String但实际上编译器无法确保该名称已绑定到String getName JavaBean属性。 第二个问题来自重构我们使用String值定义属性名称。 如果使用IDE重构Person对象并将getName方法挂接到getLastName 则应用程序将损坏 编译器将再次无法注意到这一点。 让我们在这里停留片刻看看IChainingModel接口。 其主要目的是允许使用普通对象或链接模型作为模型的内容。 PropertyModel可以与提供人物的模型或普通人物对象一起使用。 如果查看PropertyModel的源代码则会注意到实现IChainingModel需要转换而我认为还需要样板代码。 可以重构我们先前创建的PersonFriendsModel以实现IChainingModel这样与其仅采用模型作为内容它还可以支持直接采用人员。这真的有必要吗 并不是的。 如果我们要使用普通人则可以从该人创建一个新的静态模型从而为我们提供与IChainingModel相同的功能。 CompoundPropertyModel为模型处理增加了更多的魔力。 它是许多组件的根模型可以通过将属性名称与组件ID匹配来自动绑定到该组件。 public class PersonForm extends FormPerson {public PersonForm(final String id, final IModelPerson personModel) {super(id, new CompoundPropertyModelPerson(personModel));add(new TextFieldString(name));add(new TextFieldInteger(age));}
} 在这里我们创建一个表单以显示该人的姓名和年龄的输入字段。 这两个文本字段均未附加任何模型但是我们仍然能够将“名称”部分绑定到该人的姓名并将“年龄”部分绑定到该人的年龄。 我们在构造函数中创建的复合属性模型是表单的根模型并通过组件ID将表单组件自动绑定到对象的属性。 复合属性模型和属性模型都存在相同的问题但我们甚至还要添加一个。 现在我们将组件ID直接锁定为属性名称。 这意味着我们具有从HTML模板到域对象属性名称的依赖关系。 这听起来不太合理。 如果要使用属性模型则取决于您但是在我看来由于前面所述的问题应避免使用它们。 有诸如bindgen-wicket之类的项目尝试在不损失类型安全性的情况下实现属性模型的行为。 但是即使bindgen在重构中也无法很好地起作用。 我们如何以一种类型实现名称模型并以安全的方式重构呢 public class NameModel implements IModelString {private IModelPerson personModel;public NameModel(final IModelPerson personModel) {this.personModel personModel;}Overridepublic String getObject() {return personModel.getObject().getName();}Overridepublic void setObject(String object) {personModel.getObject().setName(object);}Overridepublic void detach() {personModel.detach();}
} 该模型比属性模型具有更多的行。 是的的确如此但是您是否想失去类型安全性和重构功能并可能很容易破坏应用程序。 该模型位于不同的文件中因此您仍然可以将其用作一个衬纸因此如果使用属性模型或我们刚刚创建的模型则没有任何区别。 您永远可以记住Java是非常冗长的语言这一事实。 Wicket还为我们提供了ResourceModel和StringResourceModel它们提供了为组件创建本地化内容的强大工具。 我不会在本文中讨论它们因为《 Wicket in Action》一书对此有很好的参考。 我试图提出一些现实生活中的示例说明如何使用不同类型的模型以及它们的目的是什么。 我希望这能给您更多有关Wicket模型以及如何正确使用它们的知识。 参考来自RAINBOW WORLDS博客的JCG合作伙伴 Tapio Rautonen 对Wicket模型的一种干净方法 。 翻译自: https://www.javacodegeeks.com/2013/09/a-clean-approach-to-wicket-models.htmlwicket