簡體   English   中英

禁用Play框架模型類的增強功能

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM