Frühjahr DTO Validierung im Service oder Controller?
Baue ich eine geradlinig-AJAX /JSON web service mit Spring. Der Allgemeine Datenfluß ist:
some DTO from browser
v
Spring @Controller method
v
Spring @Service method
Ich bin auf der Suche nach der einfachste Weg, um zu behandeln, Daten-Validierung.
- Ich weiß, die
@Valid
Anmerkung, das funktioniert ziemlich gut drin@Controller
Methoden. - Warum
@Valid
nicht Arbeit innerhalb@Service
Methoden?
Ich meine: Eine service-Methode verwendet werden kann, von einem anderen Dienst und controller. So würde es nicht machen, viel mehr Sinn zu validieren am @Service
Ebene?
Nehmen wir dieses einfache Beispiel:
MyDTO.java:
public class MyDTO {
@NotNull
public String required
@Min(18)
public int age;
}
MyServiceImpl.java:
public MyDomainObject foo(MyDTO myDTO) {
//persist myDTO
//and return created domain object
}
MyController.java:
@Autowired
MyService myService;
@Autowired //some simple bean mapper like Dozer or Orika
Mapper mapper; //for converting domain objects to DTO
@RequestMapping(...)
public MyDomainObjectDTO doSomething(@RequestBody MyDTO myDTO) {
mapper.map(myService.foo(myDTO), MyDomainObjectDTO.class);
}
Ist es gängige Praxis, dass der service-Methode erhält der DTO?
- Wenn
yes
: Was ist die best practice, um zu überprüfen, dass DTO innerhalb der service-Methode? - Wenn
no
: Sollte vielleicht die Steuerung zu manipulieren, das Domain-Objekt und lassen Sie die service-speichern Sie das Objekt? (dies scheint ziemlich nutzlos für mich)
Meiner Meinung nach der Dienst sollte dafür verantwortlich sein, nur die Konsistenz der Daten.
Wie lösen Sie diese?
- möglich, Duplikat der Überprüfen Voraussetzungen, Controller-oder Service-Ebene
Du musst angemeldet sein, um einen Kommentar abzugeben.
Meine Antwort? Beide.
Muss der service zur überprüfung seiner eigenen Vertrag für die Gültigkeit.
Der controller ist der Teil der Benutzeroberfläche. Sie sollten überprüfen, und binden Sie für eine bessere Benutzer-Erfahrung, aber der service sollte nicht auf Sie verlassen.
Den service nicht wissen, wie es genannt wird. Was ist, wenn Sie wickeln Sie es wie ein REST-service?
Den service kennt, weiß auch über Verstöße gegen die business-Logik in einer Weise, dass kein UI können. Es braucht, um sich zu bestätigen, stellen Sie sicher, dass der use-case erfüllt ist angemessen.
Doppel-Tasche es; tun Sie beide.
@Valid
Anmerkungen? ... Habe ich Ihren Punkt -, service-und controller verwenden kann (zum Beispiel) verschiedene Felder in Ihren Klassen. In meiner app, es ist immer das gleiche. Dadurch habe ich Durchlaufen nur die DTO in den Dienst.Siehe meine andere Antwort: Überprüfen Voraussetzungen, Controller-oder Service-Schicht
Wenn Sie wirklich wollen, zu tun, Validierung, Fehlerbehandlung in Ihrem Dienst Schicht ähnlich Spring MVC, die Sie verwenden können
javax.Validierung
und AspectJ (zu Beratung, die Methoden zu überprüfen), das ist, was ich Tue, weil ich wie machen Reflexion die Arbeit machen und die deklarative Programmierung (Anmerkungen).Spring MVC nicht tun müssen AspectJ/AOP zu tun, die Fehlerbehandlung, da die Methoden aufgerufen werden, die durch Reflexion (url-routing/dispatching).
Schließlich für Sie MVC-code, den Sie sollten wissen, dass
@Valid
ist sozusagen inoffiziell veraltet. Betrachten Sie stattdessen@Validiert
die Hebelwirkung mehr derjavax.validation
Funktionen.@Validated
bei der Service-Schicht, die ist ziemlich genial. Registrieren Sie sich einfach FrühlingMethodValidationPostProcessor
, dann setzen Sie ein@Validated
annotation auf der Service-Schnittstelle selbst und nicht zuletzt setzen einige@Valid
oder@NotNull
Anmerkungen auf die Methodensignaturen definiert die Service-Schnittstelle. Die ServiceImpl bleibt sauber. Dies funktioniert sehr gut! Das einzige "problem" ist, dass diepropertyPath
innerhalb der geworfenConstraintViolationException
bekommen, Präfix mit der ganzen call-Hierarchie, d.h.controllerMethod.serviceMethod.dtoProperty
. Ich muss irgendwie loszuwerden, diese.