如何使用Spring Data JPA Repository(jackson)反序列化已嵌套数据的json?

时间:2018-07-16 07:28:02

标签: json jackson nested spring-data-jpa spring-data-rest

我使用spring数据jpa并进行休息以公开宁静的api,实际上是spring-boot-starter-data-jpaspring-boot-starter-data-rest

我的实体定义为:

用户

@Entity
@Table(name="users")
@JsonDeserialize(using = User.Deserialize.class)
public class User implements Serializable {
    private static final long serialVersionUID = 7802610584713776262L;

    @Id
    @Column(name = "username")
    private String userName;

    @ManyToMany(
            cascade = {CascadeType.REFRESH},
            fetch = FetchType.EAGER
    )
    @JoinTable(
            name = "user_roles",
            joinColumns = @JoinColumn(name = "username"),
            inverseJoinColumns = @JoinColumn(name = "role")
    )
    @Fetch(FetchMode.JOIN)
    private Set<Role> roles = new HashSet<>();

    @ManyToMany(
            cascade = {CascadeType.REFRESH},
            fetch = FetchType.EAGER
    )
    @JoinTable(
            name = "user_permissions",
            joinColumns = @JoinColumn(name = "username"),
            inverseJoinColumns = @JoinColumn(name = "permission")
    )
    @Fetch(FetchMode.JOIN)
    private Set<Permission> permissions = new HashSet<>();

    // ... getters and setters ...
    public static class Deserialize extends JsonDeserializer<User> {

        @Override
        public User deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
            String txt = jsonParser.readValueAsTree().toString();
            return JSON.parseObject(txt, User.class);
        }
    }
}

角色

@Entity
@Table(name="roles")
@JsonDeserialize(using = Role.Deserialize.class)
public class Role implements Serializable {
    private static final long serialVersionUID = -53314161963168175L;
    @Id
    @Column(name="role_name")
    private String roleName;
    private String info;

    @ManyToMany(
            targetEntity=Permission.class,
            cascade={CascadeType.REFRESH},
            fetch=FetchType.EAGER
    )
    @JoinTable(
            name="roles_permissions",
            joinColumns=@JoinColumn(name="role_name"),
            inverseJoinColumns=@JoinColumn(name="permission")
    )
    @Fetch(FetchMode.SELECT)
    private Set<Permission> permissions = new HashSet<>();

    public static class Deserialize extends JsonDeserializer<Role> {

        @Override
        public Role deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
            String txt = jsonParser.readValueAsTree().toString();
            return JSON.parseObject(txt, Role.class);
        }
    }
}

权限

@Entity
@Table(name="permissions")
@JsonDeserialize(using = Permission.Deserialize.class)
public class Permission implements Serializable {
    private static final long serialVersionUID = -3716946708377038760L;
    @Id
    private String permission;
    private String info;

    @ManyToOne(
            cascade={CascadeType.REFRESH},
            fetch=FetchType.EAGER
    )
    @JoinColumn(name="parent")
    @Fetch(FetchMode.JOIN)
    private Permission parent;

    public static class Deserialize extends JsonDeserializer<Permission> {

        @Override
        public Permission deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
            String txt = jsonParser.readValueAsTree().toString();
            return JSON.parseObject(txt, Permission.class);
        }
    }
}

我从网络上管理了这些数据,所以我遵循以下步骤:

  1. 将权限发布到服务器var host:port/permissions
  2. 发布角色var host:port/roles
  3. 发布角色var host:port/roles/role_id/permissions的权限
  4. 发布用户var host:port/users
  5. 发布用户var host:port/users/user_id/roles的角色
  6. 发布用户var host:port/users/user_id/permissions的权限。

但是我想通过发布嵌套数据将步骤2,3合并为一个单一操作,并将4,5,6合并为另一个单一操作。 例如: 假设已经创建了perm1,perm2,perm3。

{roleName: "admin", permissions: ["perm1", "perm2"]}

{userName: "peter", roles: ["admin"], permissions: ["perm3"]}

我找到了我的代码中使用的解决方案:@JsonDeserializer。我为这些实体定义了反序列化器,并使用Fastjson对嵌套数据进行反序列化,这是可行的。

有没有更好的解决方案?我觉得可以在杰克逊或斯普林斯做,但我不知道。有人帮助我吗?

0 个答案:

没有答案