Pretvorba entiteta u DTO za Spring REST API
Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:
>> PROVJERITE TEČAJ1. 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