Konverzia entity na DTO pre jarné REST API
Práve som oznámil nové Naučte sa jar kurz zameraný na základy jari 5 a Spring Boot 2:
>> SKONTROLUJTE KURZ1. Prehľad
V tomto tutoriáli sa budeme zaoberať konverziami, ktoré sa musia uskutočniť medzi internými entitami jarnej aplikácie a externými DTO (Objekty na prenos údajov), ktoré sa zverejnia späť klientovi.
2. Model Mapper
Začnime predstavením hlavnej knižnice, ktorú použijeme na vykonanie tejto konverzie entity - DTO - ModelMapper.
Túto závislosť budeme potrebovať v pom.xml:
org.modelmapper modelmapper 2.3.5
Ak chcete skontrolovať, či existuje nejaká novšia verzia tejto knižnice, prejdite sem.
Potom definujeme ModelMapper fazuľa v našej jarnej konfigurácii:
@Bean public ModelMapper modelMapper () {vrátiť nový ModelMapper (); }
3. DTO
Ďalej si predstavíme DTO stranu tohto obojstranného problému - Príspevok DTO:
verejná trieda PostDto {súkromné statické konečné SimpleDateFormat dateFormat = nový SimpleDateFormat ("rrrr-MM-dd HH: mm"); súkromné Long id; súkromný názov reťazca; súkromná reťazcová adresa URL; súkromný dátum reťazca; súkromný používateľ UserDto; public Date getSubmissionDateConverted (String timezone) hodí ParseException {dateFormat.setTimeZone (TimeZone.getTimeZone (timezone)); dátum vráteniaFormat.parse (this.date); } public void setSubmissionDate (Date date, String timezone) {dateFormat.setTimeZone (TimeZone.getTimeZone (timezone)); this.date = dateFormat.format (dátum); } // štandardní zakladatelia a zakladatelia}
Všimnite si, že dve vlastné metódy súvisiace s dátumom spracúvajú prevod údajov medzi klientom a serverom:
- getSubmissionDateConverted () metóda prevádza dátum String do a Dátum v časovom pásme servera, aby sa použilo v pretrvávajúcom formáte Príspevok subjekt
- setSubmissionDate () metódou je nastaviť dátum DTO na Príspevok‘S Dátum v časovom pásme aktuálneho používateľa.
4. Servisná vrstva
Pozrime sa teraz na operáciu na úrovni služby - ktorá bude samozrejme fungovať s entitou (nie s DTO):
public List getPostsList (int page, int size, String sortDir, String sort) {PageRequest pageReq = PageRequest.of (page, size, Sort.Direction.fromString (sortDir), sort); Príspevky na stránke = postRepository .findByUser (userService.getCurrentUser (), pageReq); vrátiť posts.getContent (); }
Ďalej sa pozrieme na vrstvu nad službou - vrstvu ovládača. Tu tiež skutočne dôjde ku konverzii.
5. Vrstva radiča
Poďme sa teraz pozrieť na implementáciu štandardného radiča a odhaliť jednoduché REST API pre Príspevok zdroj.
Ukážeme si tu niekoľko jednoduchých operácií CRUD: vytvorenie, aktualizácia, získanie jednej a získanie všetkých. A vzhľadom na to, že operácie sú celkom jednoduché, obzvlášť nás zaujímajú aspekty konverzie Entity-DTO:
@Controller class PostRestController {@Autowired private IPostService postService; @Autowired private IUserService userService; @Autowired private ModelMapper modelMapper; @GetMapping @ResponseBody verejný zoznam getPosts (...) {// ... List posts = postService.getPostsList (page, size, sortDir, sort); vrátiť posts.stream () .map (this :: convertToDto) .collect (Collectors.toList ()); } @PostMapping @ResponseStatus (HttpStatus.CREATED) @ResponseBody verejné PostDto createPost (@RequestBody PostDto postDto) {Post post = convertToEntity (postDto); Príspevok postCreated = postService.createPost (príspevok)); návrat 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 (príspevok); }}
A tu je naša premena z Príspevok subjekt do PostDto:
private PostDto convertToDto (Post post) {PostDto postDto = modelMapper.map (post, PostDto.class); postDto.setSubmissionDate (post.getSubmissionDate (), userService.getCurrentUser (). getPreference (). getTimezone ()); návrat postDto; }
A tu je premena z DTO na subjekt:
private Post convertToEntity (PostDto postDto) hodí 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 ()); } spiatočný príspevok; }
Ako teda vidíte, pomocou modelového mapovača logika konverzie je rýchla a jednoduchá - používame mapa API mapovača a získanie údajov prevedených bez napísania jediného riadku logiky prevodu.
6. Testovanie jednotky
Na záver urobíme veľmi jednoduchý test, aby sme sa ubezpečili, že konverzie medzi entitou a DTO fungujú dobre:
verejná trieda PostDtoUnitTest {súkromný ModelMapper modelMapper = nový ModelMapper (); @Test public void whenConvertPostEntityToPostDto_thenCorrect () {Príspevok príspevok = nový príspevok (); 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 = nový 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. Záver
Toto bol článok o zjednodušenie prechodu z Entity na DTO a z DTO na Entitu v Spring REST APInamiesto manuálneho zápisu týchto konverzií pomocou knižnice modelových mapovačov.
Celý zdrojový kód príkladov je k dispozícii v projekte GitHub.
REST spodok