Pretvorba entiteta u DTO za Spring REST API

OSTALO Vrh

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ

1. Pregled

U ovom uputstvu obradit ćemo konverzije koje se trebaju dogoditi između unutarnjih entiteta Spring aplikacije i vanjskih DTO-a (Objekti za prijenos podataka) koji se objavljuju natrag klijentu.

2. Mapper modela

Počnimo s uvođenjem glavne knjižnice koju ćemo koristiti za izvođenje ove pretvorbe entiteta i DTO - ModelMapper.

Trebat će nam ova ovisnost u pom.xml:

 org.modelmapper modelmapper 2.3.5 

Idite ovdje da biste provjerili postoji li novija verzija ove knjižnice.

Tada ćemo definirati ModelMapper grah u našoj proljetnoj konfiguraciji:

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

3. DTO

Dalje, predstavimo DTO stranu ovog dvostranog problema - Objavi DTO:

javna klasa PostDto {privatni statički konačni SimpleDateFormat dateFormat = novi SimpleDateFormat ("yyyy-MM-dd HH: mm"); privatni Long id; privatni naslov niza; private String url; privatni datum niza; private UserDto korisnik; javni Datum getSubmissionDateConverted (Niz vremenske zone) baca ParseException {dateFormat.setTimeZone (TimeZone.getTimeZone (vremenska zona)); datum povrataFormat.parse (this.date); } javna praznina setSubmissionDate (datum, datum, niz vremenske zone) {dateFormat.setTimeZone (TimeZone.getTimeZone (vremenska zona)); this.date = dateFormat.format (datum); } // standardni getteri i postavljači} 

Imajte na umu da dvije prilagođene metode povezane s datumom obrađuju pretvorbu datuma između klijenta i poslužitelja:

  • getSubmissionDateConverted () metoda pretvara datum Niz u a Datum u vremenskoj zoni poslužitelja da ga koristi u trajnom Objavi entitet
  • setSubmissionDate () metoda je postaviti datum DTO na Objavi‘S Datum u trenutnoj korisničkoj vremenskoj zoni.

4. Razina usluge

Pogledajmo sada operaciju na razini usluge - koja će očito raditi s entitetom (ne s DTO-om):

javni popis getPostsList (int stranica, int veličina, String sortDir, String sort) {PageRequest pageReq = PageRequest.of (stranica, veličina, Sort.Direction.fromString (sortDir), sort); Objave na stranici = postRepository .findByUser (userService.getCurrentUser (), pageReq); vratiti postove.getContent (); }

Sljedeći ćemo pogled na sloj iznad usluge - sloj kontrolera. Tu će se zapravo dogoditi i pretvorba.

5. Sloj kontrolera

Pogledajmo sada implementaciju standardnog kontrolera, izlažući jednostavni REST API za Objavi resurs.

Ovdje ćemo pokazati nekoliko jednostavnih CRUD operacija: stvorite, ažurirajte, nabavite jednu i nabavite sve. A s obzirom na to da su operacije prilično jednostavne, posebno smo zainteresirani za aspekte konverzije Entity-DTO:

Klasa @Controller PostRestController {@Autowired private IPostService postService; @Automobilski privatni IUserService userService; @Autowired privatni ModelMapper modelMapper; @GetMapping @ResponseBody javni popis getPosts (...) {// ... Popis postova = postService.getPostsList (stranica, veličina, sortDir, sortiranje); vratiti postove.stream () .map (this :: convertToDto) .collect (Collectors.toList ()); } @PostMapping @ResponseStatus (HttpStatus.CREATED) @ResponseBody javni PostDto createPost (@RequestBody PostDto postDto) {Post post = convertToEntity (postDto); Objavi postCreated = postService.createPost (post)); return convertToDto (postCreate); } @GetMapping (value = "/ {id}") @ResponseBody public PostDto getPost (@PathVariable ("id") Long id) {return convertToDto (postService.getPostById (id)); } @PutMapping (value = "/ {id}") @ResponseStatus (HttpStatus.OK) javna praznina updatePost (@RequestBody PostDto postDto) {Post post = convertToEntity (postDto); postService.updatePost (post); }}

I ovdje je naše obraćenje iz Objavi entitet da PostDto:

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

I evo obraćenja od DTO-a do entiteta:

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

Kao što vidite, uz pomoć mapera modela, logika pretvorbe je brza i jednostavna - koristimo karta API mappera i pretvaranje podataka bez upisivanja ijednog retka logike pretvorbe.

6. Jedinstveno testiranje

Na kraju, napravimo vrlo jednostavan test kako bismo bili sigurni da konverzije između entiteta i DTO rade dobro:

javna klasa PostDtoUnitTest {private ModelMapper modelMapper = new ModelMapper (); @Test public void whenConvertPostEntityToPostDto_thenCorrect () {Post post = novi 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"); Objavi post = modelMapper.map (postDto, Post.class); assertEquals (postDto.getId (), post.getId ()); assertEquals (postDto.getTitle (), post.getTitle ()); assertEquals (postDto.getUrl (), post.getUrl ()); }}

7. Zaključak

Ovo je članak o pojednostavljivanje pretvorbe iz entiteta u DTO i iz DTO u entitet u Spring REST API-ju, pomoću biblioteke mapper modela, umjesto da ove pretvorbe pišem ručno.

Potpuni izvorni kod za primjere dostupan je u projektu GitHub.

OSTALO dno

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ