Konvertierung von Entität in DTO für eine Spring-REST-API

REST Top

Ich habe gerade den neuen Learn Spring- Kurs angekündigt , der sich auf die Grundlagen von Spring 5 und Spring Boot 2 konzentriert:

>> Überprüfen Sie den Kurs

1. Übersicht

In diesem Lernprogramm werden die Konvertierungen behandelt, die zwischen den internen Entitäten einer Spring-Anwendung und den externen DTOs (Datenübertragungsobjekten) durchgeführt werden müssen, die zurück auf dem Client veröffentlicht werden.

2. Model Mapper

Beginnen wir mit der Einführung der Hauptbibliothek, die wir für diese Entity-DTO-Konvertierung verwenden werden - ModelMapper .

Wir werden diese Abhängigkeit in der pom.xml benötigen :

 org.modelmapper modelmapper 2.3.5 

Um zu überprüfen, ob es eine neuere Version dieser Bibliothek gibt, klicken Sie hier.

Anschließend definieren wir die ModelMapper- Bean in unserer Spring-Konfiguration:

@Bean public ModelMapper modelMapper() { return new ModelMapper(); }

3. Das DTO

Als nächstes stellen wir die DTO-Seite dieses zweiseitigen Problems vor - Post- DTO:

public class PostDto { private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); private Long id; private String title; private String url; private String date; private UserDto user; public Date getSubmissionDateConverted(String timezone) throws ParseException { dateFormat.setTimeZone(TimeZone.getTimeZone(timezone)); return dateFormat.parse(this.date); } public void setSubmissionDate(Date date, String timezone) { dateFormat.setTimeZone(TimeZone.getTimeZone(timezone)); this.date = dateFormat.format(date); } // standard getters and setters } 

Beachten Sie, dass die beiden benutzerdefinierten datumsbezogenen Methoden die Datumskonvertierung zwischen dem Client und dem Server durchführen:

  • getSubmissionDateConverted () -Methode konvertiert Datum String in ein Datum in Zeitzone des Servers zu verwenden , um es in der anhaltenden Beitrag Einheit
  • setSubmissionDate () Methode ist DTO Datum zu setzen Beitrag ‚s Datum in aktuellen Benutzer Zeitzone.

4. Die Service-Schicht

Schauen wir uns nun eine Service Level-Operation an, die offensichtlich mit der Entität (nicht mit dem DTO) funktioniert:

public List getPostsList( int page, int size, String sortDir, String sort) { PageRequest pageReq = PageRequest.of(page, size, Sort.Direction.fromString(sortDir), sort); Page posts = postRepository .findByUser(userService.getCurrentUser(), pageReq); return posts.getContent(); }

Wir werden uns als nächstes die Ebene über dem Dienst ansehen - die Controller-Ebene. Hier findet auch die Konvertierung statt.

5. Die Controller-Schicht

Schauen wir uns nun eine Standard-Controller-Implementierung an, die die einfache REST-API für die Post- Ressource verfügbar macht.

Wir werden hier einige einfache CRUD-Operationen zeigen: Erstellen, Aktualisieren, Abrufen einer und Abrufen aller. Und da die Abläufe ziemlich einfach sind, interessieren uns insbesondere die Aspekte der Entity-DTO-Konvertierung :

@Controller class PostRestController { @Autowired private IPostService postService; @Autowired private IUserService userService; @Autowired private ModelMapper modelMapper; @GetMapping @ResponseBody public List getPosts(...) { //... List posts = postService.getPostsList(page, size, sortDir, sort); return posts.stream() .map(this::convertToDto) .collect(Collectors.toList()); } @PostMapping @ResponseStatus(HttpStatus.CREATED) @ResponseBody public PostDto createPost(@RequestBody PostDto postDto) { Post post = convertToEntity(postDto); Post postCreated = postService.createPost(post)); return convertToDto(postCreated); } @GetMapping(value = "/{id}") @ResponseBody public PostDto getPost(@PathVariable("id") Long id) { return convertToDto(postService.getPostById(id)); } @PutMapping(value = "/{id}") @ResponseStatus(HttpStatus.OK) public void updatePost(@RequestBody PostDto postDto) { Post post = convertToEntity(postDto); postService.updatePost(post); } }

Und hier ist unsere Konvertierung von der Post- Entität zu PostDto :

private PostDto convertToDto(Post post) { PostDto postDto = modelMapper.map(post, PostDto.class); postDto.setSubmissionDate(post.getSubmissionDate(), userService.getCurrentUser().getPreference().getTimezone()); return postDto; }

Und hier ist die Konvertierung von DTO zu einer Entität :

private Post convertToEntity(PostDto postDto) throws ParseException { Post post = modelMapper.map(postDto, Post.class); post.setSubmissionDate(postDto.getSubmissionDateConverted( userService.getCurrentUser().getPreference().getTimezone())); if (postDto.getId() != null) { Post oldPost = postService.getPostById(postDto.getId()); post.setRedditID(oldPost.getRedditID()); post.setSent(oldPost.isSent()); } return post; }

Wie Sie sehen, ist die Konvertierungslogik mit Hilfe des Modell-Mappers schnell und einfach. Wir verwenden die Map- API des Mappers und lassen die Daten konvertieren, ohne eine einzige Zeile Konvertierungslogik zu schreiben.

6. Unit Testing

Lassen Sie uns abschließend einen sehr einfachen Test durchführen, um sicherzustellen, dass die Konvertierungen zwischen der Entität und dem DTO gut funktionieren:

public class PostDtoUnitTest { private ModelMapper modelMapper = new ModelMapper(); @Test public void whenConvertPostEntityToPostDto_thenCorrect() { Post post = new Post(); post.setId(1L); post.setTitle(randomAlphabetic(6)); post.setUrl("www.test.com"); PostDto postDto = modelMapper.map(post, PostDto.class); assertEquals(post.getId(), postDto.getId()); assertEquals(post.getTitle(), postDto.getTitle()); assertEquals(post.getUrl(), postDto.getUrl()); } @Test public void whenConvertPostDtoToPostEntity_thenCorrect() { PostDto postDto = new PostDto(); postDto.setId(1L); postDto.setTitle(randomAlphabetic(6)); postDto.setUrl("www.test.com"); Post post = modelMapper.map(postDto, Post.class); assertEquals(postDto.getId(), post.getId()); assertEquals(postDto.getTitle(), post.getTitle()); assertEquals(postDto.getUrl(), post.getUrl()); } }

7. Fazit

Dies war ein Artikel zur Vereinfachung der Konvertierung von Entität zu DTO und von DTO zu Entität in einer Spring REST-API , indem die Modell-Mapper-Bibliothek verwendet wurde, anstatt diese Konvertierungen manuell zu schreiben.

Der vollständige Quellcode für die Beispiele ist im GitHub-Projekt verfügbar.

REST unten

Ich habe gerade den neuen Learn Spring- Kurs angekündigt , der sich auf die Grundlagen von Spring 5 und Spring Boot 2 konzentriert:

>> Überprüfen Sie den Kurs