Enhed til DTO-konvertering til en Spring REST API

REST Top

Jeg har lige annonceret det nye Lær foråret kursus med fokus på det grundlæggende i Spring 5 og Spring Boot 2:

>> KONTROLLER KURSEN

1. Oversigt

I denne vejledning håndterer vi de konverteringer, der skal ske mellem de interne enheder i en Spring-ansøgning og de eksterne DTO'er (Data Transfer Objects), der offentliggøres tilbage til klienten.

2. Modelkort

Lad os starte med at introducere det vigtigste bibliotek, som vi skal bruge til at udføre denne enhed-DTO-konvertering - ModelMapper.

Vi har brug for denne afhængighed i pom.xml:

 org.modelmapper modelmapper 2.3.5 

Gå her for at kontrollere, om der er nogen nyere version af dette bibliotek.

Vi definerer derefter ModelMapper bønne i vores forårskonfiguration:

@Bean offentlig ModelMapper modelMapper () {returner ny ModelMapper (); }

3. DTO

Lad os derefter introducere DTO-siden af ​​dette tosidede problem - Stolpe DTO:

offentlig klasse PostDto {privat statisk endelig SimpleDateFormat dateFormat = ny SimpleDateFormat ("åååå-MM-dd HH: mm"); privat Lang id; privat streng titel; privat String url; privat streng dato; privat UserDto-bruger; offentlig dato getSubmissionDateConverted (streng tidszone) kaster ParseException {dateFormat.setTimeZone (TimeZone.getTimeZone (tidszone)); return dateFormat.parse (denne dato); } public void setSubmissionDate (Date date, String timezone) {dateFormat.setTimeZone (TimeZone.getTimeZone (timezone)); this.date = dateFormat.format (dato); } // standard getters og setters} 

Bemærk, at de to brugerdefinerede datorelaterede metoder håndterer datokonvertering frem og tilbage mellem klienten og serveren:

  • getSubmissionDateConverted () metode konverterer dato Snor ind i en Dato i serverens tidszone for at bruge den i den vedvarende Stolpe enhed
  • setSubmissionDate () metoden er at indstille DTO's dato til Stolpe'S Dato i den aktuelle brugers tidszone.

4. Servicelaget

Lad os nu se på en serviceniveauoperation - som naturligvis fungerer med Enheden (ikke DTO):

offentlig liste getPostsList (int side, int størrelse, streng sortDir, streng sortering) {PageRequest pageReq = PageRequest.of (side, størrelse, Sort.Direction.fromString (sortDir), sort); Sideposter = postRepository .findByUser (userService.getCurrentUser (), pageReq); returposts.getContent (); }

Vi skal se på laget over tjenesten næste - controller-laget. Det er her, konverteringen faktisk også vil ske.

5. Controller-laget

Lad os nu se på en standard controllerimplementering, der udsætter den enkle REST API for Stolpe ressource.

Vi viser her et par enkle CRUD-operationer: Opret, opdater, få en og få alle. Og da operationerne er ret enkle, vi er især interesserede i konverteringsaspekterne Entity-DTO:

@Controller klasse PostRestController {@Autowired privat IPostService postService; @Autowired privat IUserService userService; @Autowired privat ModelMapper modelMapper; @GetMapping @ResponseBody offentlig Liste getPosts (...) {// ... Listeindlæg = postService.getPostsList (side, størrelse, sortDir, sortering); return posts.stream () .map (dette :: convertToDto) .collect (Collectors.toList ()); } @PostMapping @ResponseStatus (HttpStatus.CREATED) @ResponseBody public PostDto createPost (@RequestBody PostDto postDto) {Post post = convertToEntity (postDto); Post postCreated = postService.createPost (post)); returner convertToDto (postCreated); } @GetMapping (værdi = "/ {id}") @ResponseBody offentlig PostDto getPost (@PathVariable ("id") Lang id) {return convertToDto (postService.getPostById (id)); } @PutMapping (værdi = "/ {id}") @ResponseStatus (HttpStatus.OK) offentlig ugyldig opdateringspost (@RequestBody PostDto postDto) {Post post = convertToEntity (postDto); postService.updatePost (post); }}

Og her er vores konvertering fra Stolpe enhed til PostDto:

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

Og her er omvendelsen fra DTO til en enhed:

privat indlæg convertToEntity (PostDto postDto) kaster ParseException {Post post = modelMapper.map (postDto, Post.class); post.setSubmissionDate (postDto.getSubmissionDateConverted (userService.getCurrentUser (). getPreference (). getTimezone ())); hvis (postDto.getId ()! = null) {Post oldPost = postService.getPostById (postDto.getId ()); post.setRedditID (oldPost.getRedditID ()); post.setSent (oldPost.isSent ()); } returpost }

Så som du kan se, ved hjælp af model kortlæggeren, konverteringslogikken er hurtig og enkel - vi bruger kort API for kortlæggeren og få dataene konverteret uden at skrive en enkelt konverteringslogik.

6. Enhedstest

Endelig lad os lave en meget enkel test for at sikre, at konverteringerne mellem enheden og DTO fungerer godt:

offentlig klasse PostDtoUnitTest {privat ModelMapper modelMapper = ny ModelMapper (); @Test offentlig ugyldig nårConvertPostEntityToPostDto_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 offentlig ugyldig nårConvertPostDtoToPostEntity_thenCorrect () {PostDto postDto = ny 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. Konklusion

Dette var en artikel om forenkling af konverteringen fra enhed til DTO og fra DTO til enhed i en Spring REST APIved at bruge modelmapper-biblioteket i stedet for at skrive disse konverteringer manuelt.

Den fulde kildekode til eksemplerne er tilgængelig i GitHub-projektet.

REST bunden

Jeg har lige annonceret det nye Lær foråret kursus med fokus på det grundlæggende i Spring 5 og Spring Boot 2:

>> KONTROLLER KURSEN