【问题标题】:Can we protect a Domain Model from JSON request not creating a DTO object?我们可以保护领域模型免受 JSON 请求而不是创建 DTO 对象吗?
【发布时间】:2017-08-08 06:17:16
【问题描述】:

对于 Web/JSON 请求,我们不希望将整个域模型暴露给客户端。在这种情况下,其中一种模式是使用 DTO 对象,然后从域模型映射到 DTO 并返回。

DTO 的示例是用于 JSON 请求的 LoginUserDTO:

public class LoginUserDTO {
    private String email;
    private String password;
}

此外,我们还有一个用户 POJO 注释为具有更多属性的实体。通过使用 LoginUserDTO,我们可以保护要更新的用户实体的其他字段

但是,拥有多个 DTO 会导致代码重复,是否可以避免这种重复?我正在使用 Spring/Hibernate 和 Spring Data

【问题讨论】:

    标签: java json spring hibernate spring-data


    【解决方案1】:

    这肯定是更多的代码,但最终还是值得的。如果你的服务应该“拥有”它的数据,它应该从最终用户那里抽象出来。这意味着给客户一个 API。 API 具有 DTO 和函数。数据层有自己的模型。

    试想一下,如果您想开始将数据存储为时间序列。您不希望所有客户都必须知道这一点。或者您想在表中添加或删除字段。或者你想写一个花哨的连接,这样你就不必经常查询了。如果您没有两组对象,所有这些事情都意味着要更改面向用户的 API。

    因此,除了拥有 DTO 和模型之外,您还需要一个转换器!幸运的是,Spring 已准备好使用模式/类。

    import com.example.dto.LoginUserDto;
    import com.example.model.LoginUser;
    import org.springframework.core.convert.converter.Converter;
    
    public class LoginUserDtoToLoginUserConverter
        implements Converter <LoginUserDto, LoginUser> {
    
      @Override
      public LoginUser convert(LoginUserDto source) {
        if (source == null) {
          return null;
        }
        LoginUser target = new LoginUser();
        target.setEmail(source.getEmail());
        target.setPassword(source.getPassword());
        return target;
      }
    }
    

    乐趣还没有结束!在将对象返回给客户端时,您仍然必须将模型对象 back 转换为 DTO。耶!

    import com.example.dto.LoginUserDto;
    import com.example.model.LoginUser;
    import org.springframework.core.convert.converter.Converter;
    
    public class LoginUserToLoginUserDtoConverter
        implements Converter <LoginUser, LoginUserDto> {
    
      @Override
      public LoginUserDto convert(LoginUser source) {
        if (source == null) {
          return null;
        }
        LoginUserDto target = new LoginUserDto();
        target.setEmail(source.getEmail());
        target.setPassword(source.getPassword());
        return target;
      }
    }
    

    美丽是不是。这么多浪费。但是不,真的没有其他方法可以解决这个问题。你要么存储你的“wire”对象,要么转换它们。

    祝你好运。

    【讨论】:

      【解决方案2】:

      这不是一个聪明的解决方案,但有些人可能会发现对特定情况有用。

      您可以编写 JSON 类并从 POJO 类扩展它们。比如;

      public class LoginUserAsJSON {
          private String email;
          private String password;
      }
      
      public class LoginUserAsPOJO extends LoginUserAsJSON {
          private int userId;
          private Date loginTime;
          ...
      }
      

      【讨论】:

      • 这取决于设计选择,两者在技术上是平等的,但正如我在上面的例子中提到的,从 POJO 类扩展 JSON 类是合理的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-02
      • 2019-09-02
      • 1970-01-01
      • 1970-01-01
      • 2010-11-19
      • 1970-01-01
      • 2023-03-15
      相关资源
      最近更新 更多