日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Wicket模型的干净方法

發布時間:2023/12/3 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Wicket模型的干净方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Apache Wicket Web框架的核心概念之一是模型和IModel作為其編程接口。 Wicket組件嚴重依賴模型,這使它們成為體系結構的重要組成部分。 Apache Wicket是一個有狀態框架,將頁面及其組件存儲到通常位于HTTP會話中的頁面存儲中。 組件根據模型的內容創建面向公眾的視圖。 錯誤使用模型可能會導致尷尬的副作用,例如頁面無法更新其內容或應用程序占用大量內存。 從我所看到的情況來看,新的Wicket用戶遇到的最多問題是正確使用模型。 在這篇博客文章中,我將嘗試解釋在不同的用例中應該如何以及使用哪種模型。

Wicket IModel實現中最基本的是Model類。 它基本上是模型內容的簡單占位符。 這非常適合模型內容不占用太多內存且更像是常量的情況。 一個簡單的String可能是Model內容的理想選擇。

IModel<String> name = new Model<String>("John");

您必須了解,即使創建包含模型的頁面,創建模型對象時其內容也將保持不變。 此行為是由于使用靜態模型引起的。 每次從模型詢問值時,動態模型都可以更改實際內容。 新的Wicket用戶經常使用靜態模型而不是動態模型。 如果您不清楚靜態模型和動態模型的概念,則應閱讀《 Wicket in Action 》一書中的第4章“了解模型” 。

IModel<Date> date = new Model<Date>() {@Overridepublic Date getObject() {return new Date();} };

通過覆蓋getObject()方法,可以從Model創建上述動態日期模型為匿名類。 模型將始終返回包含當前時間的Date的新副本。

Wicket是有狀態的Web框架,模型通常存儲在用戶的HTTP會話中。 模型中的數據很可能是從數據庫或通過某些Web服務獲取的。 如果使用靜態模型方法,則很快將消耗大量內存,并且如果重新加載頁面,將無法從數據源獲得全新視圖。 如果我們決定像對Date對象那樣使用動態模型,則最終可能會在一頁加載中進行大量數據庫搜索或Web服務調用。 匿名內部類也不是很好看的代碼。 Wicket有一個針對此問題的內置解決方案,LoadableDetachableModel可以緩存模型的內容,直到可以安全丟棄為止,從而提供了有效但仍動態的模型。

public class PersonModel extends LoadableDetachableModel<Person> {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)或Guice(wicket-guice)。 集成模塊確保在注入服務代理時將它們可序列化。

public class ProfilePage extends WebPage {@SpringBeanprivate PersonService personService;public ProfilePage(final PageParameters parameters) {super(parameters);Long id = parameters.get("id").toLongObject();IModel<Person> 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 AbstractReadOnlyModel<String> {private IModel<Person> personModel;public PersonFriendsModel(final IModel<Person> personModel) {super();this.personModel = personModel;}@Overridepublic String getObject() {Person person = personModel.getObject();Iterable<String> 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 Function<Person, String> {public String apply(final Person input) {return input.getName();}} }

在這里,我們建立一個模型,該模型可以構成我們先前創建的PersonModel。 我們將其用作來源,以建立該人的好友列表。 我們正在擴展的模型是Wicket提供給我們的AbstractReadOnlyModel。 它基本上是普通模型,但不允許設置模型內容。 這非常有道理,因為我們正在構建一個聯接的String,并且解析一個相似的列表并從該列表中設置該人的朋友會很尷尬。 我們僅將此模型用于只讀目的,以在視圖中顯示朋友列表。 您可以在此處看到視圖的類比,我們仍在使用相同的Person域模型,但是在模型的幫助下公開了自定義視圖。 請注意,我們將detach方法委托給了組合模型。 這可以確保,如果我們在任何組件中都沒有直接引用組成的模型,則仍然可以將其與好友模型分離。 多次調用detach()方法無害,因此即使從多個組件中使用也很安全。

我們僅創建了一個簡單的模型合成示例。 您應該探索Wicket的內置模型實現,并花一些時間來研究如何使用它們從領域模型中創建合理的模型。 只需記住一件事:組成和擴展模型,而不是域對象。

我最后要談的是屬性模型。 它們在許多Wicket應用程序中得到了廣泛使用,甚至《 Wicket in Action》一書也鼓勵使用它們,但是它們具有一些不需要的功能。 屬性模型的代碼編寫速度快且易于使用,但是它們使您的代碼成為“字符串類型”。 這是我們不希望使用Java這樣的類型安全語言的東西。

PropertyModel<String> nameModel =new PropertyModel<String>(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 Form<Person> {public PersonForm(final String id, final IModel<Person> personModel) {super(id, new CompoundPropertyModel<Person>(personModel));add(new TextField<String>("name"));add(new TextField<Integer>("age"));} }

在這里,我們創建一個表單以顯示該人的姓名和年齡的輸入字段。 這兩個文本字段均未附加任何模型,但是我們仍然能夠將“名稱”部分綁定到該人的姓名,并將“年齡”部分綁定到該人的年齡。 我們在構造函數中創建的復合屬性模型是表單的根模型,并通過組件ID將表單組件自動綁定到對象的屬性。 復合屬性模型和屬性模型都存在相同的問題,但我們甚至還要添加一個。 現在,我們將組件ID直接鎖定為屬性名稱。 這意味著我們具有從HTML模板到域對象屬性名稱的直接依賴關系。 這聽起來不太合理。

如果要使用屬性模型,則取決于您,但是在我看來,由于前面所述的問題,應避免使用它們。 有諸如bindgen-wicket之類的項目嘗試在不損失類型安全性的情況下實現屬性模型的行為。 但是,即使bindgen在重構中也不能很好地起作用。 我們如何以類型實現名稱模型并以安全的方式重構呢?

public class NameModel implements IModel<String> {private IModel<Person> personModel;public NameModel(final IModel<Person> 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.html

總結

以上是生活随笔為你收集整理的Wicket模型的干净方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 可以免费看污视频的网站 | 麻豆疯狂做受xxxx高潮视频 | 在线观看的av网站 | 看日本黄色录像 | 炕上如狼似虎的呻吟声 | 超碰国产一区二区三区 | 少妇高潮久久久久久潘金莲 | 成人免费视频国产免费 | 国产一级理论片 | 欧美女优一区二区 | 秋霞午夜 | 国产又色又爽又黄的 | 免费色站| 杨贵妃颤抖双乳呻吟求欢小说 | 无遮挡裸光屁屁打屁股男男 | 亚洲手机在线 | www.白丝 | 黑人超碰 | 日本一区二区在线 | 亚洲成人一区二区三区 | av影视在线观看 | 亚洲黄色在线观看视频 | 精品久久99 | 欧美日韩免费视频 | 夜间福利视频 | 国产夫妻自拍av | 69sex久久精品国产麻豆 | 少妇偷人精品无码人妻 | 超碰在线看 | 天天干天天舔 | 一区二区国产精品 | 香港三级日本三级韩国三级 | 青青操在线观看 | 灌篮高手全国大赛电影 | 亚洲国产视频一区二区三区 | 日韩大片免费看 | 最新福利在线 | 九九九九国产 | 国产综合无码一区二区色蜜蜜 | 国产成人精品一区二三区 | 久久成年 | 都市激情亚洲 | 97在线免费公开视频 | 999av视频| 奇米在线 | 91麻豆精品国产91久久久久久久久 | 最新中文字幕2019 | 亚洲黄a| 色爽视频 | 传媒视频在线观看 | 婷婷丁香在线 | 91精品国产综合久久福利 | 视频丨9l丨白浆 | 三级黄色网络 | 字幕网在线 | 国产suv精品一区二区 | 久久成人乱码欧美精品一区二区 | 久久噜噜色综合一区二区 | 亚洲国产va| 青青草99| 国产一级免费片 | 国产婷婷精品 | 国产一区二区a | 亚洲aaaaaa| 秋霞国产午夜精品免费视频 | 91精品国产麻豆国产自产在线 | 成人免费在线观看av | 午夜影视av | 国产精品福利导航 | 国产69久久| 欧美一区二区三区影视 | 久久69 | 久久亚洲AV成人无码国产人妖 | 国产白浆在线 | 大学生高潮无套内谢视频 | 91干干干 | 亚洲成人偷拍 | 手机av在线看 | 青娱乐青青草 | 秋霞二区| 中文字幕在线观看第二页 | 国产原创av在线 | 操大逼网站 | 99riav在线| 国产精品影音先锋 | 国产亚洲天堂网 | 成人av影视在线观看 | 一级黄色片在线免费观看 | 亚洲精品色午夜无码专区日韩 | 久久99精品国产91久久来源 | 99国产精品一区二区 | 午夜国产视频 | 欧美日韩视频在线观看一区 | 国产对白刺激视频 | 三级福利片 | 亚洲无限av | 中国老太婆性做爰 | 国产视频精品自拍 | 久久一级视频 |