Spring DTO-DAO(资源 - 实体)映射在哪个应用层:Controller或Service?

时间:2015-07-27 02:30:35

标签: java spring spring-mvc architecture spring-hateoas

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

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

  • 查看(JSP / JSON)
  • 控制器(S)
  • DAO(@Service
  • DAO(@Repository

我的问题是,我应该将DAO实体映射到DTO资源?我查看了一些使用Spring HATEOAS的示例,并显示了Resource ResourceSupport Controller对象的Link被映射到Link。这是最好的方法吗,还是我应该从DAO服务中返回资源?

我希望将Service个元素添加到返回的资源(针对自我和相关资源),但如果在Controller中进行处理,则无法查看@RequestMapping元素的解析方式它了解Controllerpublic int childCount; public void countChildren() { GameObject buildBoard = GameObject.FindGameObjectWithTag("Board"); GameObject[] allChildren = buildBoard.transform.Cast<Transform>().Select(t=>t.gameObject).ToArray(); childCount = 0; for(int i = 0; i < allChildren.Length; i++) { childCount++; } Debug.Log(childCount); } 。另一方面,我不知道将@Local与映射混为一谈是否是一种好习惯。

4 个答案:

答案 0 :(得分:4)

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

PS:看看http://puu.sh/jefv0/181ba9d94c.png也是如此;)

答案 1 :(得分:2)

我的意见是在Controller层中进行映射,因为该层负责输入/输出。服务层应该是独立的,以便可以使用相同的开发另一个接口。

如果您在Controller层中创建Mapper类并且只是它们,那么Controller中不会出现太多混乱。

答案 2 :(得分:0)

  

我应该将DAO实体映射到DTO资源?

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

E.g。

@Transactional
public OrderPlacedTO placeOrder(ShoppingCartTO cart)[
   OrderDao orderDao = ...
   // implement your use case here
   ...
}
  

我希望将链接元素添加到返回的资源(用于自身和相关资源),但是如果在服务中处理它而不知道控制器及其所有权,则无法看到如何解析链接元素。 ; s @RequestMapping

你是对的。这些信息仅在控制器中可用。您可以添加资源模型,如普通的ui模型。

E.g。

public class OrderPlacedRessource extends ResourceSupport {

    private Long oderNumber;

    public void setOrderNumber(Long orderNumber){ this.orderNumber = orderNumber; }
    public Long getOrderNumber() { return this.orderNumber }
}

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

@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,建设链接会更容易。 E.g

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

有关详细信息,请参阅Building a Hypermedia-Driven RESTful Web Service

答案 3 :(得分:0)

您可以遇到可以调用映射的不同方法。 请参阅本教程,例如:http://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application或问题:http://forum.spring.io/forum/other-spring-related/architecture/56753-controller-vs-service-vs-private-method-on-command-object。它还取决于您的控制器中有多少逻辑。 我更喜欢在util类中映射Entity&lt; - &gt; DTO。而且您可以相对自由地选择,您可以从中调用它们。看起来,&#34;最好的设计是最简单的设计,可以使用#34; - 爱因斯坦关于DTO必要性的类似文章: Should services always return DTOs, or can they also return domain models?