服务层和控制器:谁负责什么?
在课堂上,我们现在正在学习如何构建 Spring 应用程序,即使没有直接涉及 Spring,我们也学习了如何为 DAO 和服务层对象创建接口。
如果我错了,请纠正我: DAO 层非常抽象:它只包含 CRUD 操作,并进一步用于读取数据。(即:获取所有对象、获取特定对象等)
服务层:包含创建事物、删除事物的服务,这就是业务所在逻辑应该是。
现在所有这些在服务层都有意义了;除了“更新”对象。您是否只是放置一个仅将对象保存在数据库中的“更新”函数?或者您还需要在那里定义逻辑吗?这就是我困惑的地方,我的理解是 Spring 中的对象只是 POJO 的。那么谁来验证数据呢?
假设我有一个对象“孩子” 它有:姓名
、姓氏
、性别
、照片
、出生日期
字段。 我该如何命名这些服务?或者你会让控制器负责验证,这对我来说似乎不合适。另一方面,将每个需要调用的 setter 委托给服务层似乎也不合适。
所以基本上:帮助我定义如何通过服务层保存对象。
In class we're now learning how to build up a Spring application, even though spring isn't directly involved, we learned how to make the interfaces for DAO and service layer objects.
Please correct me if I'm wrong:
DAO layer is pretty abstract: it just contains the CRUD operations and is further used to read data.(ie: get all objects, get specific objects, etc)
Service layer: contains services to create things, and delete things, this is where business logic should be.
Now all of this makes sense in the service layer; except "updating" objects. Do you just put a "update" function that just saves the object in your database? Or do you need to define the logic there as well? This is where my confusion is as, my understanding is objects in Spring are just POJO's. Now then who validates the data?
Let's say I have an Object "child"
it has:Name
, SurName
, Gender
, Photo
, Birthdate
fields.
how would I name the services? Or would you just let the controller take care of validation, which doesn't seem right to me. On the other hand it wouldn't seem right either to delegate every setter that needs to be called to the service layer.
So just basically: help me with how to define saving your objects via the service layer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
一般来说,Spring 服务是事务性的。事物进入特定的服务方法,因为它们应该在同一事务中组合在一起。如果你想从数据库中检索一个对象,调整它,并保存新版本,检索和保存应该在同一个服务方法中。因此,您的服务方法是根据您需要应用程序为用户做什么来确定的。
我尝试限制控制器执行与验证 http 参数、决定使用什么参数调用什么服务方法、在 httpsession 或请求中放入什么、要重定向或转发到什么视图或类似的 Web 相关内容相关的工作。
就验证而言:验证控制器中的输入参数是一件好事,可以确保没有人可以用虚假输入破坏您的应用程序。控制器中的验证往往是为了确保输入在语法上正确(包括检测注入攻击),而服务级别验证则是为了确保数据库中的状态符合您的预期。
因此控制器包含网络框架基础设施代码,服务包含应用程序逻辑代码。
Generally a Spring service is transactional. Things go into a particular service method because they ought to be grouped together in the same transaction. If you want to retrieve an object from the database, twiddle it, and save the new version, the retrieval and save ought to be in the same service method. So your service methods are determined according to what you need the application to do for the user.
I try to restrict controllers to doing work related to validating http parameters, deciding what service method to call with what parameters, what to put in the httpsession or request, what view to redirect or forward to, or similar web-related stuff.
As far as validation goes: Validating input parameters in the controller is a good thing to make sure nobody can break your application with bogus inputs. Validation in the controller tends to be about making sure the inputs are syntactically ok (including detecting injection attacks) while service-level validation is about making sure the state of things in the database is what you expect it to be.
So controllers contain web-framework infrastructure code, services contain application logic code.
如果您希望控制器能够持久保存对
Child
对象的更改,那么传统上您将在服务中使用一个名为ChildService.update(Child newchild)
的方法,它将处理调用正确的 DAO 来保存该 Child 的新版本。控制器可以自由地向服务请求子项,更改周围的字段(可以想象基于某些用户输入) - 合理的设计将使控制器对子项 POJO 进行一些工作,然后要求服务保留更改。模型 POJO 应该对控制器、服务或 DAO 一无所知,而只是按照您的建议保存数据 - 当然您不希望每次调用
setName()
或setGender() 自动导致数据库更新。
相反,控制器和/或服务应该获取一个
Child
对象,对其工作单元中的对象执行所需的任何工作,然后请求服务(然后是 DAO)保存更改。验证可以在多个层中进行 - 控制器可能希望验证来自 Web 用户的任何输入,而服务可能希望在保留该对象之前验证它是否具有有效的
Child
对象。如果您想以其他功能重用此服务,例如公开 REST 接口、不同的前端等,那么在两个层中进行一定程度的验证尤其有意义。If you wish to have controllers be able to persist changes to a
Child
object, then traditionally you would have a method in the service named something likeChildService.update(Child newchild)
, which will handle calling the correct DAOs to persist the new version of this Child.Controllers are free to ask the service for a Child, change the fields around (conceivably based on some user input) - a sane design would have the Controller doing some work with the Child POJO and then asking the Service to persist the change. The model POJO should know nothing about a controller, service, or DAO but just simply hold data as you suggest - certainly you would not want every call to
setName()
orsetGender()
to automatically result in a database update.Instead, the controller and/or service should acquire a
Child
object, do whatever work it needs to the object in it's unit of work, and then ask a Service (and then the DAO) to persist the changes.Validation can take place in several layers - the Controller might want to validate any input from the web user, and the Service may want to validate that it has a valid
Child
object before it persists it. It especially makes sense to have some level of validation in both layers in case you want to re-use this Service in other capacities - such as exposing a REST interface, a different front-end, etc.