繁体   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