我使用spring数据jpa并进行休息以公开宁静的api,实际上是spring-boot-starter-data-jpa
和spring-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);
}
}
}
我从网络上管理了这些数据,所以我遵循以下步骤:
host:port/permissions
host:port/roles
host:port/roles/role_id/permissions
的权限host:port/users
host:port/users/user_id/roles
的角色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对嵌套数据进行反序列化,这是可行的。
有没有更好的解决方案?我觉得可以在杰克逊或斯普林斯做,但我不知道。有人帮助我吗?