假设我有一个非常简单的User
类:
@JsonIgnoreProperties({"password", "created", "lastModified"})
public class User {
public String id;
public String name;
public String password
public Long created;
public Long lastModified;
}
当我们将User
实体序列化为JSON字符串时,我们会过滤掉password
,created
和lastModified
。然后,前端用户将更新用户的名称,并将用户返回到我们的Restful服务。
我的伪控制器方法处理PUT
请求:
@Path("/user/{id}")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void saveUpdate(@PathParam("id")String id, User user) {
userService.save(user);
}
在上面的方法中,我希望Jackson将反序列化前端发送到POJO user
实例的JSON字符串,然后调用我们的服务来保存实例。
到目前为止,一切看起来都很酷。但是,当我们将user
POJO传递给userService
以保存它时,引起了关注。请记住,当我们将user
简化为JSON时,我们忽略了三个属性:password
,created
,lastModified
,我们必须从数据库中获取这些缺失属性的值然后合并从前端发送的数据。
对于编码人员来说,执行合并操作是一项非常简单但又乏味的任务。我想知道是否有任何好的做法可以轻松优雅地处理这个案例
答案 0 :(得分:1)
我认为User对象是将要保存到DB中的实体对象,因此最佳做法不是将实体对象暴露给FE,而是使用仅包含FE需要知道的字段的DTO对象(考虑隐藏id以及改为使用UUID,因为id值是可预测的)。稍后您可以使用ModelMapper将此类DTO对象映射到Entity,这样您就可以轻松地在userDTO和用户实体对象之间进行合并,然后只需保留实体而不必担心缺少字段的状态
此外,现在许多Web服务禁用其应用程序的PUT请求并使用POST。我不太熟悉原因,但当我们将申请转交给安全检查时,这是一个安全问题
答案 1 :(得分:1)
我认为关注的更多是关于您的服务而不是REST API。我的意思是,如果用户的3个属性"密码","创建"和#34; lastModified"不应该对表示层可见,那么服务应该能够在没有它们的情况下处理保存。
在持久层中,您绝对可以在不填充所有属性的情况下更新User
。或者更好的设计,让我们分开UserLogin(" id","密码","创建"," lastModified")和用户(" id"," name")指向同一个DB表。然后,用户的更新根本不需要其他不必要的属性。