如何在序列化期间隐藏字段(但不是反序列化)

Posted

技术标签:

【中文标题】如何在序列化期间隐藏字段(但不是反序列化)【英文标题】:how to hide field during serialization (but not deserialization) 【发布时间】:2016-04-16 19:32:44 【问题描述】:

在我们的项目(springMVC)Rest API 项目中,我希望只对请求和响应使用 ONE 模型(以避免添加大量代码来将字段从对象复制到对象)

我想使用 Swagger 来处理所有文档,但我遇到了一个小问题。例如假设我有一个模型用户

public class User  
 private Long id;
 private String username;
 private String password;

还有一个简单的控制器

 public void createUser(@RequestBody User user)...
 public User getUser(Long id) ..

现在我想大摇大摆地在反序列化而不是序列化时隐藏属性密码(所以让它显示输入但输出) 而 Id 字段则相反。

我尝试使用 @JsonIgnore 和 @JsonProperty,但在 swagger-ui 上它要么显示所有内容,要么隐藏所有内容。我无法让它工作。

有人可以告诉我存档目标的最佳方式是什么吗?在使用 swagger 时是否可以使用单个模型进行请求和响应?如果无法使用@JsonIgnore,有没有办法以不同的方式存档?

【问题讨论】:

【参考方案1】:

Swagger 不希望您拥有同名的不同输入/输出模型。您应该简单地创建一个接口并将其附加到输入,并为输出扩展该接口或添加具有附加字段的实现。例如,请参阅此处了解建模技巧:

https://swaggerhub.com/api/swagger-tutorials/modeling-samples/1.0.0

您的确切用例就是其中之一。上面链接中发布的解决方案在这里:

definitions:
  User:
    description: this is a user that would be passed into the system
    properties:
      username:
        type: string
  UserResponse:
    allOf:
      - $ref: '#/definitions/User'
      - type: object
        required:
          - id
        properties:
          id:
            type: string
            format: uuid
            readOnly: true

其中User 是输入对象,UserResponse 是输出对象,带有额外的id 字段。

【讨论】:

我确实尝试过接口路线,但我没有设法让 springMVC 的“@RequestBody”与接口一起工作。我的意思是它确实适用于招摇,但我不能调用端点,因为它不知道要使用哪个实现。 (我用 getUsername 和 setUsername 创建了一个 UserRequest 接口,我让 User 实现了它,我把 UserRequest 放在 @RequestBody 和 User 中作为响应) 我遇到的第二个接口问题是“子对象”。考虑我在 User 类中有一个“地址”对象。我没有反序列化字段地址,例如在 Address 对象中 您可以尝试将UserUserResponse 的java 类作为子类吗?我希望 springfox 能够很好地完成这项工作。您可能需要在该 repo 上打开一个问题【参考方案2】:

添加 @JsonIgnore 与字段的 getter 和 @JsonProperty 与 setter 或与字段。由于使用不可变代码或最终字段,有时 setter 不起作用。

示例:

  public class Student 
   private Float name;
   private String rollnum;
   private String section;
   @JsonProperty
   private Boolean passOrFailed;

   @JsonIgnore
   public Boolean getpassOrFailed 
     return active;
   

记住要同时使用 else 否则会导致反序列化中删除元素

【讨论】:

以上是关于如何在序列化期间隐藏字段(但不是反序列化)的主要内容,如果未能解决你的问题,请参考以下文章

在 xml 序列化期间忽略属性,但在反序列化期间不忽略

如何在 JSON 反序列化期间将引用转换为实例

Django REST Framework 序列化程序字段必需=false

如何反序列化没有字段名的 JSON

如何在 .NET 中的反序列化期间指定 XML 序列化属性以支持命名空间前缀?

选择性地@JsonIgnore Immutables 访问器方法,仅在使用 Jackson 进行序列化或反序列化期间