java Spring DTO-DAO(资源-实体)映射在哪个应用层:控制器还是服务?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31644131/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring DTO-DAO (Resource - entity) mapping goes in which application layer: Controller or Service?
提问by Tiksi
I'm writing a Spring (4.1.7) web application that exposes a RESTful service and wish to use DTO "resource" objects for communication between Controller and client browser rather than expose my persistence entities.
我正在编写一个公开 RESTful 服务的 Spring (4.1.7) Web 应用程序,并希望使用 DTO“资源”对象在控制器和客户端浏览器之间进行通信,而不是公开我的持久性实体。
Currently the application has the following layers:
目前该应用程序有以下几层:
- View (JSP/JSON)
- Controller(s)
- DAO (
@Service
) - DAO (
@Repository
)
- 查看 (JSP/JSON)
- 控制器
- 道 (
@Service
) - 道 (
@Repository
)
My question is, where should I be mapping my DAO entities to DTO resources? I had a look at some examples using Spring HATEOAS
and they show Resource
objects extending ResourceSupport
being mapped in the Controller
. Is this the best way to do it, or should I be returning resources from the DAO Service?
我的问题是,我应该在哪里将我的 DAO 实体映射到 DTO 资源?我有看一些例子使用Spring HATEOAS
它们显示Resource
对象延伸ResourceSupport
的映射Controller
。这是最好的方法,还是应该从 DAO 服务返回资源?
I wish to add Link
elements to the returned resource (for self and related resources), but can't see how Link
elements would be resolved if processed in the Service
without it having knowledge of the Controller
and it's @RequestMapping
. On the other hand, I don't know if it's good practice to clutter the Controller
with the mapping either.
我希望将Link
元素添加到返回的资源(用于自身和相关资源),但无法看到Link
如果在Service
不了解Controller
和它的情况下处理元素将如何解决@RequestMapping
。另一方面,我不知道Controller
将映射与映射混淆是否是一个好习惯。
回答by Morteza Adi
DTO ( Data Transfer Object) as obvious in its name, is used for transfering data out of your application. In your case the best place to put them is in your controller layer. You should only expose DTO's to UI and when you get a data from UI you should convert it to the business entity and call the below tier. The reason is, in this way you are free to change the business entitiy without breaking UI and leads to better maintenance. Also your business/DAO tier should be unaware of UI and DTO's for the same reason. So the best place to convert DTO to Business Entities and vice versa in your app is Controller tier.
顾名思义,DTO(数据传输对象)用于将数据传输出您的应用程序。在您的情况下,放置它们的最佳位置是您的控制器层。您应该只向 UI 公开 DTO,当您从 UI 获取数据时,您应该将其转换为业务实体并调用下面的层。原因是,通过这种方式,您可以在不破坏 UI 的情况下自由更改业务实体,并带来更好的维护。出于同样的原因,您的业务/DAO 层也应该不知道 UI 和 DTO。因此,在您的应用程序中将 DTO 转换为业务实体(反之亦然)的最佳位置是控制器层。
PS:Take a look at Dozertoo ;)
PS:也看看推土机;)
回答by Bhushan Bhangale
My opinion is to do the mapping in Controller layer as this layer is responsible for input/output. The service layer should be independent so that the same can be used to develop another interface.
我的观点是在Controller层进行映射,因为该层负责输入/输出。服务层应该是独立的,以便相同的可以用于开发另一个接口。
Not much clutter will happen in Controller if you create Mapper classes and just them in your Controller layer.
如果您创建 Mapper 类并且仅在您的控制器层中创建它们,则控制器中不会发生太多混乱。
回答by René Link
where should I be mapping my DAO entities to DTO resources?
我应该在哪里将我的 DAO 实体映射到 DTO 资源?
In the service layer. Normally the service layer implements use cases and is the transaction boundary.
在服务层。通常服务层实现用例并且是事务边界。
E.g.
例如
@Transactional
public OrderPlacedTO placeOrder(ShoppingCartTO cart)[
OrderDao orderDao = ...
// implement your use case here
...
}
I wish to add Link elements to the returned resource (for self and related resources), but can't see how Link elements would be resolved if processed in the Service without it having knowledge of the Controller and it's @RequestMapping
我希望将 Link 元素添加到返回的资源(用于自身和相关资源),但无法看到如果在服务中处理 Link 元素,而它不知道 Controller 并且它是 @RequestMapping
You are right. These information is only available in the controller. You can add a resource model, like a normal ui model.
你说的对。这些信息仅在控制器中可用。您可以添加资源模型,就像普通的 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 }
}
and in your controller you can then use it and add links
然后在您的控制器中您可以使用它并添加链接
@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: Building links is easier if you use a org.springframework.hateoas.mvc.ControllerLinkBuilder
. E.g
PS:如果您使用org.springframework.hateoas.mvc.ControllerLinkBuilder
. 例如
orderPlacedRes.add(linkTo(methodOn(YourController.class).orderOverview(userId)).withSelfRel());
See Building a Hypermedia-Driven RESTful Web Servicefor details.
有关详细信息,请参阅构建超媒体驱动的 RESTful Web 服务。
回答by Grigory Kislin
You can meet different approach from where a mapping can be called. See this tutorial for example: http://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-applicationor question: http://forum.spring.io/forum/other-spring-related/architecture/56753-controller-vs-service-vs-private-method-on-command-object. It is also depend on how many logic in yours controllers. I prefer do mapping Entity<->DTO in util classes. And you are relatively free to choose, where from you call them. It seems, that "The best design is the simplest design that works" - Einstein. Similar article about necessity of DTO: Should services always return DTOs, or can they also return domain models?
您可以从可以调用映射的地方遇到不同的方法。例如,请参阅本教程: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<->DTO。而且您可以相对自由地选择,从哪里调用它们。似乎,“最好的设计是最简单的设计”——爱因斯坦。关于 DTO 必要性的类似文章: 服务应该总是返回 DTO,还是也可以返回域模型?