简体   繁体   English

Java 关于反序列化继承 class 的一些问题

[英]Java some issue about deserialize inherit class

When I tried to send a object from postman to restcontroller, it couldnnot deserialize as expected.当我尝试将 object 从 postman 发送到 restcontroller 时,它无法按预期反序列化。 My code:我的代码:

BaseClass:基类:

@Data
@MappedSuperclass
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public class BaseClass  implements Serializable{

    private static final long serialVersionUID = -93167525523223059L;
    
    private String id;

}

User:用户:

@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public class User extends BaseClass{

    private static final long serialVersionUID = -93167525523563033L;
    
    private String name;
    
    private String email;
   
    // ...other fields
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public class Group extends BaseClass{

    private static final long serialVersionUID = -93167115523563033L;
    
    private String name;
    
    private Set<User> users;

    // ...other fields
}

RestController休息控制器

    @PutMapping("/{id}")
    public void updateGroup(@PathVariable String id, @RequestBody Group group) {
        // some code @debug// 
        return null;
    }

When I made a request using Postman, my request body was:当我使用 Postman 发出请求时,我的请求正文是:

{
    "id": "group1",
    "users": [
    {
        "id": "user1"
    },
    {
        "id": "user2"
    },
    {
        "id": "user3"
    }]
}

I debuged in @debug and find that the @RequestBody group had only a user{id=user1}我在@debug 中调试,发现@RequestBody 组只有一个user{id=user1}

I did some research and knew one solution.我做了一些研究,知道了一种解决方案。 If I changed the request body to如果我将请求正文更改为

{
    "id": "group1",
    "users": [
    {
        "id": "user1",
        "name": "name1"
    },
    {
        "id": "user2",
        "name": "name2"
    },
    {
        "id": "user3",
        "name": "name3"
    }]
}

It worked.有效。 And I found that, it seems, when deserializing, the key to identify user is the (name, email), in the User, not the id, in the BaseClass.而且我发现,在反序列化时,识别用户的关键似乎是(名称,电子邮件),在用户中,而不是在 BaseClass 中的 id。 So my question is, is it what I think right?所以我的问题是,这是我认为对的吗? If so, how to change my code to get three users when I only deliver the id.如果是这样,当我只提供 id 时如何更改我的代码以获取三个用户。 In my current project, User has a lot properties, so I just want to send some few fields, not all.在我当前的项目中,用户有很多属性,所以我只想发送一些字段,而不是全部。 So I don't want to send the name, email and other fields.所以不想发名字,email等字段。

By default, the json deserialization process considers all the attributes of a class to be present in the given json string.默认情况下,json 反序列化过程认为 class 的所有属性都存在于给定的 json 字符串中。 If there is a need for only specific attributes and if rest of them are to be made optional, then javax.annotation.Nullable annotation can be used for non-mandatory attributes something like this:如果只需要特定属性并且如果 rest 是可选的,那么javax.annotation.Nullable注释可以用于非强制性属性,如下所示:

public class User extends BaseClass {
    private String name;

    @Nullable
    private String email;
    /*..*/
}

Further more, in order to have a fine control on the object hierarchy you can also make use of Jackson Library and define your object hierarchy as below:此外,为了更好地控制 object 层次结构,您还可以使用Jackson 库并定义 object 层次结构,如下所示:

Base class:底座 class:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "id")
@JsonSubTypes(value = {
    @JsonSubTypes.Type(name = "group", value = Group.class),
    @JsonSubTypes.Type(name = "user", value = User.class)})
public class BaseClass {
    private String id;
}

Sub classes:子类:

@JsonTypeName(value = "user")
public class User extends BaseClass {
    /*..*/
}

@JsonTypeName(value = "group")
public class Group extends BaseClass {
    /*..*/
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM