[英]Disable enhancement for Play Framework model classes
有沒有辦法禁用播放框架模型類的增強功能? 我之所以這樣問,是因為我想將模型對象序列化為JSON,但是一旦json序列化程序接觸到任何未初始化的模型,該模型就會被初始化,從而導致額外的數據庫命中,並且所產生的json會因不必要的膨脹而膨脹模型對象。 我嘗試從application.conf中排除models.*
,並使用ServerConfigStartup
與此調用serverConfig.addClass(Model.class)
或該調用serverConfig.addPackage("models")
但它們都不適合我。
Ebean要求增強模型類。 如果未增強,則無法在ebean中使用模型類。
因此,您可以選擇不使用ebean或不將模型對象序列化為JSON。 后者被認為是最佳實踐,將REST API數據對象與數據庫模型綁定不是一個好主意,因為您現在遇到的問題-兩種模型在概念上通常是不同的-數據庫模型具有對其他模型的引用模型,而JSON模型則沒有。 因此,使用不同的類來表示不同的模型。
還有另一個選擇,使用@JsonIgnore之類的Jackson注釋來忽略這些屬性。 但是,實際上,這是一個滑坡,隨着您的代碼庫的發展,當您開始在類上使用更多這些批注並維護模型時,幾乎就不可能推斷出JSON的樣子了,從而確保您不會破壞您的公共REST API,將成為一場噩夢。
我找到了解決JSON序列化過程中不需要的模型加載的方法。 首先,我必須使用以下方法修改Jackson序列化模型對象的方式:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.PUBLIC_ONLY);
這迫使傑克遜直接使用該字段,但是您的模型字段必須是公開的。 這還不夠,因為在序列化過程中仍會加載未初始化的模型集。 為了解決這個問題,我必須在序列化過程之前通過使用反射使這些集合為空,如下所示:
for (Field field : model.getClass().getFields())
{
Object fieldObject = field.get(model);
if (fieldObject instanceof BeanSet)
{
BeanSet beanSet = (BeanSet) fieldObject;
//checks if the set is loaded or not
if (beanSet.isReference())
{
field.set(model, null);
}
}
}
現在,您的模型可以安全地傳遞給Jackson序列化程序,而無需在序列化過程中加載未初始化的模型對象。
String jsonString = objectMapper.writeValueAsString(model);
JsonNode jsonNode = Json.parse(jsonString);
使用@JsonIgnore
也可以使用,但是從長遠來看,這並不可靠,就像James提到的那樣,因為您可能需要稍后將忽略的模型對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.