2015-07-27 6 views
5

Ich schreibe eine Spring (4.1.7) -Webanwendung, die einen REST-fähigen Dienst verfügbar macht und DTO- "Ressourcen" -Objekte für die Kommunikation zwischen Controller und Client-Browser verwenden möchte, anstatt meine Persistenz-Entitäten freizulegen.Spring DTO-DAO (Ressourcen - Entity) Mapping geht in welche Anwendungsschicht: Controller oder Service?

Derzeit ist die Anwendung hat die folgenden Schichten:

  • Ansicht (JSP/JSON)
  • Controller (s)
  • DAO (@Service)
  • DAO (@Repository)

Meine Frage ist, wo sollte ich meine DAO-Entitäten zu DTO-Ressourcen zuordnen? Ich habe mir einige Beispiele angesehen, die Spring HATEOAS verwenden, und sie zeigen Resource Objekte, die ResourceSupport erweitern, die in dem Controller zugeordnet werden. Ist dies der beste Weg, oder sollte ich Ressourcen vom DAO-Dienst zurückgeben?

Ich wünsche Link Elemente der zurück Ressource (für sich selbst und den dazugehörigen Ressourcen) hinzuzufügen, kann aber nicht sehen, wie Link Elemente in der Service wenn verarbeitet aufgelöst werden würde, ohne es zu Wissen über die Controller mit und es ist @RequestMapping. Auf der anderen Seite weiß ich nicht, ob es eine gute Übung ist, die Controller mit dem Mapping zu verwischen.

Antwort

3

DTO (Data Transfer Object), wie es in seinem Namen heißt, wird zum Übertragen von Daten aus Ihrer Anwendung verwendet. In Ihrem Fall ist der beste Ort, um sie zu setzen, in Ihrer Controller-Schicht. Sie sollten DTOs nur der Benutzeroberfläche zugänglich machen. Wenn Sie Daten von der Benutzeroberfläche erhalten, sollten Sie sie in die Geschäftsentität konvertieren und die folgende Ebene aufrufen. Der Grund dafür ist, dass Sie auf diese Weise die Business-Entity ändern können, ohne die Benutzeroberfläche zu unterbrechen und zu einer besseren Wartung zu führen. Auch Ihr Unternehmen/Ihre Dao-Ebene sollte aus demselben Grund keine UI und DTOs kennen. Der beste Ort für die Konvertierung von DTO zu Geschäftseinheiten und umgekehrt in Ihrer App ist die Controller-Ebene.

PS: Werfen Sie einen Blick auf Dozer auch;)

0

wo soll ich zu DTO Ressourcen meine DAO Einheiten werden abbildet?

In der Serviceebene. Normalerweise implementiert die Serviceschicht Anwendungsfälle und ist die Transaktionsgrenze.

z.

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

Ich möchte Link-Elemente auf die zurück Ressource hinzufügen (für sich selbst und damit verbundenen Ressourcen), kann aber nicht sehen, wie Verbindungselemente gelöst werden würde, wenn in den Dienst verarbeitet, ohne dass sie Kenntnis des Controllers mit und es ist @RequestMapping

Sie haben Recht. Diese Information ist nur in der Steuerung verfügbar. Sie können ein Ressourcenmodell wie ein normales ui-Modell hinzufügen.

z.

public class OrderPlacedRessource extends ResourceSupport { 

    private Long oderNumber; 

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

und in Ihrem Controller Sie können es dann Links verwenden und fügen Sie

@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: Aufbau von Verbindungen ist einfacher, wenn Sie einen org.springframework.hateoas.mvc.ControllerLinkBuilder verwenden. ZB

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

Weitere Informationen finden Sie unter Building a Hypermedia-Driven RESTful Web Service.

+0

Schlägst du vor, dass ich tatsächlich drei parallele Modelle implementieren sollte: DAO (z. B. 'OrderDao'), DTO (z. B.' OrderPlacedTo') und Resource (z. B. 'OrderPlacedResource')? Dies betrifft meine Bedenken, dass der Dienst Controller-fähig ist (und umgekehrt), aber wenn das Datenmodell wächst, könnte dies außer Kontrolle geraten. – Tiksi

0

Sie können verschiedene Ansätze treffen, von denen ein Mapping aufgerufen werden kann. Siehe dieses Tutorial zum Beispiel: http://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application oder Frage: http://forum.spring.io/forum/other-spring-related/architecture/56753-controller-vs-service-vs-private-method-on-command-object. Es hängt auch davon ab, wie viele Logik in Ihren Controllern ist. Ich bevorzuge Zuordnung Entity < -> DTO in util-Klassen. Und Sie können relativ frei wählen, wo Sie sie nennen. Es scheint, dass "das beste Design das einfachste Design ist, das funktioniert" - Einstein. Ähnliche Artikel über die Notwendigkeit von DTO: Should services always return DTOs, or can they also return domain models?

0

Meine Meinung ist, das Mapping im Controller-Layer zu tun, da diese Schicht für die Eingabe/Ausgabe verantwortlich ist. Die Service-Schicht sollte unabhängig sein, damit dieselbe zur Entwicklung einer anderen Schnittstelle verwendet werden kann.

Es wird nicht viel Unordnung im Controller passieren, wenn Sie Mapper-Klassen und nur diese in Ihrer Controller-Ebene erstellen.