当前位置: 首页 > 知识库问答 >
问题:

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

狄兴邦
2023-03-14

对于Web/JSON请求,我们不希望向客户端公开整个域模型。本例中的模式之一是使用DTO对象,然后从域模型映射到DTO,然后再映射回来。

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

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

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

然而,拥有多个DTO会造成代码重复,是否有可能避免这种重复?我正在使用Spring/Hibernate处理Spring数据

共有2个答案

云胤
2023-03-14

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

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

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

public class LoginUserAsPOJO extends LoginUserAsJSON {
    private int userId;
    private Date loginTime;
    ...
}
汪博达
2023-03-14

这肯定是更多的代码,但最终还是值得的。如果你的服务应该“拥有”它的数据,它应该让它从最终用户那里抽象出来。这意味着给客户端一个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;
  }
}

很漂亮,不是吗?这么多浪费。但是不,真的没有别的办法了。你要么存储你的“线”对象,要么转换它们。

祝你好运。

 类似资料:
  • 我的应用程序使用谷歌的AngularJS Firebase身份验证。当用户注册到应用程序时,它会在数据库中创建该用户的条目,如下所示: 现在,一旦用户登录,用户将看到付款选项,一旦付款完成,该特定ID的数据库值将根据“付款状态”填充,如上面的JSON所示。一旦付款状态为“是”,则只允许用户查看主页。 我创建了如下所示的安全规则: 现在的问题是:任何可以使用谷歌登录的用户都有权写入该数据库。因此,一

  • 问题内容: 我正在尝试在 c#* 应用程序和分布式 python 服务器之间的TCP层上实现 ZeroMQ 模式。我有一个使用request- reply模式的版本,在上进行测试时似乎相对稳定。但是,在测试中,我调试了一些情况,在收到回复之前,我偶然发送了多个请求,这显然是不可接受的。 * 在实践中,网络可能会丢掉很多数据包,我怀疑我会丢掉很多答复和/或无法发送请求。 1)有没有一种方法可以重置请

  • 问题内容: 这是来自JCiP的示例。 在第34页上: [15]这里的问题不是Holder类本身,而是Holder没有正确发布。但是,可以通过将n字段声明为final来使Holder免受不适当发布的影响,这将使Holder不变。 从这个答案: final的规范(请参阅@andersoj的答案)保证当构造函数返回时,将对final字段进行适当的初始化(从所有线程可见)。 从维基: 例如,在Java中,

  • @覆盖 公共列表getOrder(String orderNo){ StoredProcedureQuery=EntityManager.createstoredProcedureQuery(“xx.xxx.get_order_details”);query.RegisterStoredProcedureParameter(1,String.class,parametermode.in);quer

  • 我有一个域对象的图形,我需要构建一个DTO来将其发送到视图。如何正确设计它?我看到两个选项,我可以把DTO构建代码放在哪里: 1)进入DTO构造函数。但是域对象必须通过getters向DTO呈现所有字段,所以它不是DDD。 2)进入域对象。访问字段不会有问题,但是当添加新视图时,域对象会增长得非常快。 我应该如何正确地构建DTO?

  • 问题内容: 这是我的javascript: 这是我的控制器: spring-servlet.xml 收到此错误: 标头: 响应标题 请求标题 有趣的注意事项: 我收到406错误,但休眠查询同时起作用。 每当我在保管箱中更改选择时,这就是tomcat日志所说的: 可能是什么问题?之前在SO中有两个类似的问题,我在那里尝试了所有被接受的提示,但是我猜它们没有起作用… 有什么建议?随意问的问题… 问题答