我们可以保护域模型免受JSON请求而不创建DTO对象吗?

时间:2017-03-16 21:08:52

标签: java json spring hibernate spring-data

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

DTO的示例是在JSON请求中使用的LoginUserDTO:

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

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

然而,让多个DTO创建代码重复,是否可以避免这种重复?我在Spring Data中使用Spring / Hibernate

2 个答案:

答案 0 :(得分: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;
  }
}

虽然乐趣尚未结束!将对象返回到客户端时,您仍然需要将模型对象返回转换为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;
  }
}

美丽不是吗。这么多浪费。但不,没有别的办法可以解决这个问题。您要么存储“线”对象,要么转换它们。

祝你好运。

答案 1 :(得分:1)

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

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

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

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