有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java禁用对Play框架模型类的增强

有没有办法禁用play framework模型类的增强功能? 我之所以问这个问题,是因为我想将模型对象序列化为JSON,但一旦JSON序列化程序接触到任何未初始化的模型, 该模型将被初始化,导致额外的数据库命中,生成的json将被不必要的模型对象填充。我试图从应用程序中排除models.*。conf并使用ServerConfigStartup与这个调用serverConfig.addClass(Model.class)或那个调用serverConfig.addPackage("models")一起使用,但这两种方法都不适用于我


共 (2) 个答案

  1. # 1 楼答案

    Ebean要求增强模型类。如果模型类没有得到增强,就不能与ebean一起使用

    所以,你的选择是,不要使用ebean,或者不要将模型对象序列化为JSON。后者被认为是最佳实践,将REST API数据对象绑定到数据库模型不是一个好主意,因为您现在遇到的问题——这两个模型通常在概念上不同——数据库模型引用了其他模型,而JSON模型则不然。所以使用不同的类来表示不同的模型

    还有另一种选择,使用@JsonIgnore等Jackson注释忽略这些属性。但实际上,这是一个滑坡,随着代码库的发展,当您开始在类上使用更多这些注释时,几乎不可能对JSON的外观进行推理,维护模型,确保不破坏公共REST API,这将成为一场噩梦

  2. # 2 楼答案

    我找到了一种在json序列化过程中不需要加载模型的方法。 首先,我必须使用以下方法修改Jackson序列化模型对象的方式:

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
    objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.PUBLIC_ONLY);
    

    这迫使Jackson直接使用该字段,但您的模型字段必须是公共的。这仍然不够,因为在序列化过程中仍将加载未初始化的模型集。 为了解决这个问题,我必须在序列化过程之前使用反射将集合设为空,如下所示:

    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提到的,它并不可靠,因为您可能需要稍后忽略的模型对象