Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java SpringDTO-DAO(资源-实体)映射到哪个应用层:控制器还是服务?_Java_Spring_Spring Mvc_Architecture_Spring Hateoas - Fatal编程技术网

Java SpringDTO-DAO(资源-实体)映射到哪个应用层:控制器还是服务?

Java SpringDTO-DAO(资源-实体)映射到哪个应用层:控制器还是服务?,java,spring,spring-mvc,architecture,spring-hateoas,Java,Spring,Spring Mvc,Architecture,Spring Hateoas,我正在编写一个Spring(4.1.7)web应用程序,它公开一个RESTful服务,并希望使用DTO“资源”对象在控制器和客户端浏览器之间进行通信,而不是公开我的持久性实体 目前,该应用程序具有以下层: 视图(JSP/JSON) 控制员 DAO(@Service) DAO(@Repository) 我的问题是,我应该在哪里将DAO实体映射到DTO资源?我看了一些使用springhateoas的示例,它们显示了Resource扩展ResourceSupport的对象在控制器中映射。这是最好的

我正在编写一个Spring(4.1.7)web应用程序,它公开一个RESTful服务,并希望使用DTO“资源”对象在控制器和客户端浏览器之间进行通信,而不是公开我的持久性实体

目前,该应用程序具有以下层:

  • 视图(JSP/JSON)
  • 控制员
  • DAO(
    @Service
  • DAO(
    @Repository
我的问题是,我应该在哪里将DAO实体映射到DTO资源?我看了一些使用
springhateoas
的示例,它们显示了
Resource
扩展
ResourceSupport
的对象在
控制器中映射。这是最好的方法,还是应该从DAO服务返回资源

我希望将
Link
元素添加到返回的资源中(对于自身和相关资源),但如果
服务中处理
Link
元素,而不了解
控制器及其
@RequestMapping
,则无法看到如何解析
Link
元素。另一方面,我不知道用映射将
控制器
弄得乱七八糟是否是一种好的做法。

DTO(数据传输对象)在其名称中很明显,用于将数据传输出应用程序。在您的情况下,放置它们的最佳位置是控制器层。 您应该只向UI公开DTO,当您从UI获取数据时,您应该将其转换为业务实体并调用下面的层。 原因是,通过这种方式,您可以在不破坏UI的情况下自由地更改业务实体,从而实现更好的维护。同样,出于同样的原因,您的业务/DAO层应该不知道UI和DTO。 因此,在应用程序中,将DTO转换为业务实体(反之亦然)的最佳位置是控制器层


附言:也来看看;)

注意在我写这个答案时,我假设您所说的DTO是服务层的请求和响应对象。因此,我以这种方式使用术语DTO,并将术语资源对象用于“DTO”对象。我现在不想编辑整个答案。所以这个暗示

我应该在哪里将DAO实体映射到DTO资源

在服务层中。通常,服务层实现用例,是事务边界

例如

我希望将链接元素添加到返回的资源中(对于自身和相关资源),但如果在服务中处理链接元素,而不了解控制器及其@RequestMapping,则无法看到如何解析链接元素

你说得对。这些信息仅在控制器中可用。您可以添加资源模型,就像普通的ui模型一样

例如

然后在控制器中,您可以使用它并添加链接

@RequestMapping("/placeOrder")
public @ResponseBody OrderPlacedRessource placeOrderAction(HttpServletRequest request){
   OrderService service = ...;
   ShoppingCartTO cart = ...;

   OrderPlacedTO orderPlacedTO = service.placeOrder(cart);
   OrderPlacedRessource orderPlacedRes = new OrderPlacedModel();

   orderPlacedRes.setOrderNumber(orderPlacedTO.getOrderNumber());

   // since orderPlacedRes is a RessourceSupport we can add links
   // Use the HttpServletRequest to build your links
   Link link = new Link("http://localhost:8080/something");
   orderPlacedRes.addLink(link);

   return orderPlacedRes;
}
PS:如果使用
org.springframework.hateoas.mvc.ControllerLinkBuilder
,构建链接会更容易。例如

orderPlacedRes.add(linkTo(methodOn(YourController.class).orderOverview(userId)).withSelfRel());

有关详细信息,请参阅。

您可以使用不同的方法来调用映射。 请参阅本教程,例如:或问题:。这还取决于控制器中有多少逻辑。 我更喜欢在util类中映射EntityDTO。你可以相对自由地选择,从哪里称呼他们。看来,“最好的设计是最简单的设计”——爱因斯坦。关于DTO必要性的类似文章:
我的意见是在控制器层进行映射,因为该层负责输入/输出。服务层应该是独立的,以便可以将其用于开发另一个接口


如果您创建映射器类并仅在控制器层中创建它们,那么控制器中不会出现太多混乱。

您是否建议我实际实现3个并行模型:DAO(例如
OrderDao
)、DTO(例如
OrderPlacedTo
)和Resource(例如
OrderPlacedResource
)?这确实解决了我对服务具有控制器感知能力的担忧(反之亦然),但随着数据模型的增长,这可能会失控。
@RequestMapping("/placeOrder")
public @ResponseBody OrderPlacedRessource placeOrderAction(HttpServletRequest request){
   OrderService service = ...;
   ShoppingCartTO cart = ...;

   OrderPlacedTO orderPlacedTO = service.placeOrder(cart);
   OrderPlacedRessource orderPlacedRes = new OrderPlacedModel();

   orderPlacedRes.setOrderNumber(orderPlacedTO.getOrderNumber());

   // since orderPlacedRes is a RessourceSupport we can add links
   // Use the HttpServletRequest to build your links
   Link link = new Link("http://localhost:8080/something");
   orderPlacedRes.addLink(link);

   return orderPlacedRes;
}
orderPlacedRes.add(linkTo(methodOn(YourController.class).orderOverview(userId)).withSelfRel());