【问题标题】:Ignore fields from being passed on in Json Object忽略在 Json 对象中传递的字段
【发布时间】:2019-08-04 13:33:39
【问题描述】:

我有一个名为User 的 POJO,它也用于在 MongoDb 中插入文档。

@Data
@Document(collection = Constants.COLLECTION_USERS)
public class User {

    public ObjectId _id;

    public String userID;

    public String email;

    public String name;

    public String sex;

    public String dob;

    public String photo;
    //have more variables

}

我有一个简单的应用程序,用户通过提供User 类中列出的数据子集进行注册。我的控制器中注册方法的签名如下。

public GenericResponse registerUser(@RequestBody User userRegistrationRequest)

可以注意到我在注册请求中使用了相同的 POJO。直到现在一切都很好。我可以很好地保留数据用户对象。

此注册 API 仅用于保存一小组用户数据。 MongoDb 文档中还有其他信息,可以从其他一些 API 访问/保留这些信息。

假设用户已经注册了基本信息,并且还通过注册以外的 API 保存了其他信息。

我将如何制作一个 API,它可以使用相同的 User Pojo 再次从 User 文档中获取一些选择性数据?如果我调用存储库以提供特定用户 ID 的数据,它将为我提供映射到 User 类的整个文档。我不希望我的 API 提供存储在文档中的所有信息。

一种方法是使用我想要的详细信息制作另一个 POJO,并使用 Converter 选择性地映射信息。但是,我想避免这种方法,因为我想使用同一个类。

第二种方法:修改 Mongo 查询以选择性地返回数据,如 docs 中给出的。但是在这里我必须在结果集中指定我想要的所有字段。这又是一个长度查询。

有没有更好的方法从对象中过滤掉数据?

【问题讨论】:

  • 设计的核心原则之一是单一职责原则。您正在积极尝试尽可能多地违反它,希望使用相同的类来表示:1. 数据库中的持久用户信息,2. 注册时作为 JSON 输入发送的数据,3. 检索和返回的数据作为另一个 API 端点的输出。有不同的类来表示不同的东西是一件的事情。您不应该尝试对所有内容都使用相同的类。
  • 但是其他类不会只包含给定 User 类中属性的子集。我将所有这些类视为冗余代码。 PS:我是菜鸟
  • @JBNizet 那么,你是说我应该使用不同的类并使用转换器来映射数据?
  • 通过避免编写琐碎的代码,您会产生更大的可读性和维护问题。以下是其中的一些:可以通过简单地猜测它们的名称并将其提交到 JSON 中来填充不应该存在的类的字段。您或您的同事可能会通过添加/删除字段来破坏一个 API,而没有意识到在完全不相关的用例中使用了相同的类。阅读课程并不能知道客户实际期望什么或发送给客户什么。等等等等。是的,为不同的目的使用不同的类,并使用转换器或临时查询。
  • @JBNizet 感谢您解释设计原则。我会听从你的建议。

标签: java mongodb spring-boot spring-data


【解决方案1】:

我将如何创建一个 API,它可以使用相同的用户 Pojo 再次从用户文档中获取一些选择性数据?

晚上我想带我女孩去餐厅,我将如何开车去越野? 我不会 - 如果我的所有东西都用同一辆车,我会在餐厅旁边看起来很愚蠢,在套房里出来,或者我会陷入沼泽。

Java 最大的优势是object creation time - 你不应该害怕它。只需创建另一个模型用于注册,另一个作为 DTO 用于保存数据,另一个用于前端演示等

切勿混合对象的责任。您将完成类似

@Entity
class ThePileOfShit {
    @Id
    private Long id;

    @my.audit.framework.Id
    private String anotherId;

    @JsonIgnore
    // just a front-end flag ignore
    private boolean flag;

    @Column
    // not a field but getter because of any-weird-issue-you-want-to-put-here
    public String getWeirdStuff() { ... }

    // Useless converters
    public ModelA getAsModelA() { ... }

    public ModelB getAsModelB() { ... }

    // etc
    // etc
}

四种框架,五种技术——没有人知道发生了什么。

如果您害怕转换内容,请使用 ModelMapper 或其他工具,但请尽可能简化您的 POJO

【讨论】:

    【解决方案2】:

    您只能在 API 中要返回的字段上使用 Gson's @Expose 注解。

    要序列化数据,请使用:

    Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
    String json = gson.toJson(userData);
    

    【讨论】:

      猜你喜欢
      • 2020-01-16
      • 1970-01-01
      • 2011-07-24
      • 1970-01-01
      • 2020-11-20
      • 2016-06-06
      • 2019-07-12
      • 1970-01-01
      相关资源
      最近更新 更多