让我们假设下面的例子。pojo类:
@XmlRootElement
public class User {
private String id;
private String email;
private String password;
private String firstName;
private String lastName;
// getters and setters
}
资源类:
@Path("user")
public class UserResource {
private UserRepository userRepository = new UserRepositoryStub();
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})
public User createUser(User user) {
return userRepository.create(user);
}
@GET
@Path("{objectId}")
@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})
public Response getManagedObject(@PathParam("objectId") String objectId) {
if (objectId == null) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
User user = userRepository.findUser(objectId);
if (user == null) {
return Response.status(Response.Status.NOT_FOUND).build();
}
// Possible, but seems that not nice solution
// user.setPassword(null);
return Response.ok().entity(user).build();
}
}
在这个简单的示例中,我希望get request{url}/user/12345不返回password字段。我评论了一个我不喜欢的解决方案。
一般来说,在处理api时,我希望为每个请求配置pojo字段的可见性。有没有一个优雅的方法来实现这一点?
3条答案
按热度按时间q7solyqu1#
一般的做法是中间有一个服务层。然后您就有了一个dto对象,它是外部世界的io对象,转换为您的资源/实体/存储库/任何对象。您需要在这两种类型的对象之间提供转换/mapper/whatever,并且在进入dto到资源方向时不设置密码。rest接口中的ID通常也是这样。您不希望任何人通过在输入对象中提供id来更新资源和其他对象。尽管这意味着额外的代码,但这通常是微不足道的。可以简化使用配置使用推土机框架或类似的东西。
从设计的Angular 来看,资源/持久层应该只包含原子操作。如果您需要为单个资源执行其中的几个操作,会发生什么情况?你必须把它放在资源类的一个方法中。这样,您将把rest/io逻辑与服务层中应该有的逻辑混合在一起。更容易出错,也更难为其编写独立的单元测试
xpcnnkqh2#
假设您希望post方法(取消封送)包含密码,而不是get方法(封送),并且您使用的是jaxb,那么您可以编写一个xmladapter。
它的主要用途是在可Map类和不可Map类之间进行转换,但在这里它可以做到这一点。
然后为password属性指定适配器:
wfauudbj3#
创建一个transferobject,即to或dto,其中包含希望用户在json响应中显示的字段。您可以在字段上使用@jsonignore,json解析器不会解析该字段,因此不会包含在响应中。