Java 运动衫隐藏一些POJO的好方法';REST请求响应中的s字段

Java 运动衫隐藏一些POJO的好方法';REST请求响应中的s字段,java,rest,jersey,Java,Rest,Jersey,让我们假设以下示例。 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 c

让我们假设以下示例。 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请求{url}/user/12345不返回password字段。我已经评论了一个我不喜欢的解决方案


通常,在处理API时,我希望为每个请求配置POJO字段的可见性。有没有一种优雅的方式来实现这一点

创建一个TransferObject,即TO或DTO,其中包含希望用户在JSON响应中显示的字段。您可以在字段上使用@JsonIgnore,JSON解析器不会解析该字段,因此不会包含在响应中。

创建一个TransferObject,即TO或DTO,它保存您希望用户在JSON响应中显示的字段。您可以在字段中使用@JsonIgnore,JSON解析器不会解析该字段,因此不会包含在响应中。

假设您希望POST方法(未封送)包含密码- 但不是GET方法(封送)——如果您使用JAXB,您可以编写一个

它的主要用途是在可映射类和不可映射类之间进行转换,但在这里它可以做到这一点

public class PasswordAdapter extends XmlAdapter<String, String> {

    @Override
    public String unmarshal(String v) throws Exception {
        return v;
    }

    @Override
    public String marshal(String v) throws Exception {
        return "***";
    }
}

假设您希望POST方法(取消封送)包含密码- 但不是GET方法(封送)——如果您使用JAXB,您可以编写一个

它的主要用途是在可映射类和不可映射类之间进行转换,但在这里它可以做到这一点

public class PasswordAdapter extends XmlAdapter<String, String> {

    @Override
    public String unmarshal(String v) throws Exception {
        return v;
    }

    @Override
    public String marshal(String v) throws Exception {
        return "***";
    }
}

一般做法是在两者之间有一个服务层。然后,您有一个dto对象,它是外部世界的io对象,转换为您的资源/实体/存储库/任何对象。您需要在这两种类型的对象之间提供转换/映射器/任何东西,并且在dto中转到资源方向时不设置密码。rest接口中的ID通常也是这样。您不希望任何人通过在输入对象中提供id来更新资源和其他对象。尽管这意味着额外的代码,但这通常是很平常的事情。可以使用Dozer框架或类似的配置来简化


从设计的角度来看,资源/持久性层应该只包含原子操作。如果您需要为单个资源执行其中的几个操作,会发生什么情况?您必须将它放在资源类中的单个方法中。这样,您将把rest/io逻辑与服务层中应该包含的逻辑混合在一起。更容易犯错误,也更难为

编写独立的单元测试一般做法是在两者之间有一个服务层。然后,您有一个dto对象,它是外部世界的io对象,转换为您的资源/实体/存储库/任何对象。您需要在这两种类型的对象之间提供转换/映射器/任何东西,并且在dto中转到资源方向时不设置密码。rest接口中的ID通常也是这样。您不希望任何人通过在输入对象中提供id来更新资源和其他对象。尽管这意味着额外的代码,但这通常是很平常的事情。可以使用Dozer框架或类似的配置来简化


从设计的角度来看,资源/持久性层应该只包含原子操作。如果您需要为单个资源执行其中的几个操作,会发生什么情况?您必须将它放在资源类中的单个方法中。这样,您将把rest/io逻辑与服务层中应该包含的逻辑混合在一起。更容易犯错误,也更难编写独立的单元测试,谢谢。我大体上理解这个概念。这可能是一般的做法。也许您知道github或其他地方的一些类似的开放实现。阅读代码将非常有用。这似乎是我所说的设计示例,谢谢。我大体上理解这个概念。这可能是一般的做法。也许您知道github或其他地方的一些类似的开放实现。阅读代码将非常有用。这似乎是我所说的设计示例