easyjweb的WebForm

com.easyjf.web.WebForm:負責封裝用於用戶端顯示的數據,是在視圖及程序之間傳輸、處理數據的媒介
WebForm起到了一個VO和TO的作用,將表單數據或者請求中的參數都包裝其中,並且返回頁面上需要合成的數據也在其中。

WebForm的生命週期
首先,當一個請求到達時,框架首先解析出請求的IWebAction,並從Action中得到對應的WebForm的名字。然後直接調用FrameworkEngine.creatWebForm(request, formName)來得到需要的WebForm.當WebForm中填滿了表單數據後,框架會解析出cmd值和傳入的參數,也放入WebForm中。到此,框架對WebForm的處理已經結束,將WebForm就會傳入到IWebAction中。在IWebAction中處理完並返回了Page後,框架會得到WebForm中的那個合成頁面值的Map,並添加到Velocity的上下文對象中進行頁面模版的合成,最後form被丟棄,WebForm完成一次生命週期。瞭解生命週期的主要目的是在於對在WebForm中存在的數據的生命週期的理解。每一次都會有一個新的WebForm產生,但是值得注意的是,WebForm在將數據保存到Velocity上下文時,不光要保存使用addResult方法和addPo方法放入的值,還要向Velocity上下文中保存textElement中的數據,意味着重複的數據可以不用在Action中重複的添加,這在應用中需要特別注意。該項特性和帶環境的頁面導向、不帶環境的頁面導向配合使用,會大大的簡化一些情況下的操作。

@FormPO註解:
inject:
指定可通過toPo自動注入的屬性,默認爲全部可自動注入,如果設置了該值,則表示除指定可注入的屬性以外,其它所有屬性都爲不能自動注入;需要注入的屬性使用逗號(,)作爲分逗符。比如:   
@FormPO(inject="name,bornDate")
public class Person
即在Person類(或者Command對象)中,當使用toPO方法拷貝值的時候,只有name和bornDate屬性被拷貝,其餘如果有符合的屬性,都不準被拷貝。這在很大的層度上提高了應用的安全性。

disInject:
指定不可通過toPO自動注入的屬性,當試圖通過toPO更新該屬性時,將會被忽略,並在日誌中提示相關信息。在EasyJWeb中,一個模型(域)對象的屬性默認情況下全部都是可注入的,我們可以通過disInject來指定不可注入的屬性。多個不可注入的屬性使用逗號(,)作爲分隔。 如上面inject示例,也可以寫成下面的形式:
@FormPO(disInject="id,loginTimes")
public class Person

控制addPo屬性的可見性:
前文在介紹WebForm的時候,提到了addPo方法,在這個方法中,其實也有控制標籤:
disRead:
指定爲disRead的屬性在addPo方法中不會被添加到Velocity上下文中。
下面,給一個這些標籤的使用的一個範例:
@Entity
@FormPO(name = "person",inject="name,sex,mail,intro",disInject="age",disRead="serialVersionUID,id")
public class Person implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private Long id;
    @Column(length = 32)
    private String name;
    @Column(length = 6)
    private String sex;
    @Column(length = 40)
    private String mail;
    private int age;
    @Column(length = 200)
    public String intro;
}
在這個例子中,如果調用WebForm.toPo(Person.class),那麼Person中的name、sex、mail將會拷貝,而age不會被拷貝,並且調用WebForm.addPo()方法時,Person的serialVersionUID和id將不會被添加到Velocity上下文中。關於更多@FormPO標籤的用法,請參見API doc。


toPo(map, obj)方法 :map爲form.getTextElement(), obj爲要轉換的對象
1、若obj爲Map類型則直接複製,返回
2、分析obj的@Overrides註解信息,該註解用於屬性名的替換,如

@Overrides({@OverrideProperty(name="name",newName="xm"),@OverrideProperty(name="bornDate",newName="csrq")})
public class Person {
 private String name;
 private Date bornDate;
}


3、通過com.easyjf.beans.BeanWrapper包裝器獲得類的屬性並依次檢查其可注入性:首先保證屬性的可寫性(可寫屬性或有可寫方法:wrapper.isWritableProperty(name), property.getWriteMethod())

4、獲得屬性的驗證對象:通過Validator,Field及FormPO標籤中的validators標籤中的標籤來判斷驗證對象配置(返回列表結構爲List<Map<Annonation,
List<Validator>>>。針對字段的Field、Validator標籤、針對方法的Field、Validator標籤以及針對FormPO的標籤等分別放在存放在返回列表中),多個則取列表順序最後一個,並生成驗證對象ValidatorObject返回。

5、檢測@FormPO註解的inject和disInject,判斷屬性是否可注入,可以則再檢測屬性的@Field註解的writeable值是否爲true。
允許注入則依次檢測設置方法或屬性的@POLoad,@InnerProperty,@MultiPOLoad,@OverrideProperty註解,獲得注入屬性別名,然後根據註解注入:
①@POLoad    :從持久(或業務)層加載特定id值,類型爲clz的對象。
該標籤用來加載關聯 ,我們在表單中只能存放關聯對象的id,而在賦值的時候需要通過這個id從持久層中加載這個對象,然後設置到指定的屬性中,

public class BBSDoc {
	@Id
	private Long id;
	@POLoad(name="dirId")
	private BBSDir dir;
}

 


②@InnerProperty:內嵌屬性加載,根據屬性名實例化內嵌對象,利用包裝器分析內嵌對象的屬性:若屬性可寫,檢查如address.city以及city這樣的字段,在包裝器中賦值。 設置內部屬屬性,嵌套屬性該標籤主要用於輔助WebForm.toPo方法來給複雜的屬性對象賦值,主要用於內嵌屬性。 地址信息的Address

public class Address {
	private String province;
	private String city;
}

public class Employee {
	private String name;
	@InnerProperty
	private Address address1;
	@InnerProperty(overrides={@OverrideProperty(name="province",newName="province2"),@OverrideProperty(name="city",newName="city2")});
	private Address address2;
}


③@MultiPOLoad:自動加載關聯的List對象,適用於OneToMany關聯。form中傳入id數組或ids字串(,隔開),對每一個id利用POLoadDao從持久層加載特定id值,類型爲clz的對象。返回對象的list(@MultiPOLoad的targetClz需要手動設置)

public class Father {
    @MultiPOLoad(targetClz="Son")
    List<Son> sons;
}
// form傳入1,2,3或者[1,2,3]表示son的id,則自動注入


④普通對象加載:如果需要驗證,則執行。利用com.easyjf.beans.BeanUtils.convertType(Object value, Class<?> type)將form中傳入value轉化成type類型的對象。

6、執行驗證,若驗證出錯,則不改變PO對象的值,即不加入到屬性名與對象值映射map中,最後返回該map

7、如果validateRollback爲false且驗證不出錯,則利用包裝器將屬性名與對象之注入到obj中


addPo(obj, form.getTextElement)
1、若obj是map類型,則直接複製
2、利用包裝器獲得屬性,檢查其可讀性(FormPO是否有disread以及Field的readable),將名與值添加到form中


附件是一個topo示例

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章