Enhet til DTO-konvertering for en REST API for våren

REST Topp

Jeg kunngjorde nettopp det nye Lær våren kurs, med fokus på det grunnleggende i vår 5 og vårstøvel 2:

>> KONTROLLER KURSET

1. Oversikt

I denne opplæringen håndterer vi konverteringene som må skje mellom de interne enhetene i en vårapplikasjon og de eksterne DTO-ene (Data Transfer Objects) som blir publisert tilbake til klienten.

2. Model Mapper

La oss starte med å introdusere hovedbiblioteket vi skal bruke til å utføre denne enhet-DTO-konvertering - ModelMapper.

Vi vil trenge denne avhengigheten i pom.xml:

 org.modelmapper modelmapper 2.3.5 

Gå hit for å sjekke om det er noen nyere versjon av dette biblioteket.

Vi definerer deretter ModelMapper bønne i vårkonfigurasjon:

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

3. DTO

Deretter, la oss introdusere DTO-siden av dette tosidige problemet - Post DTO:

offentlig klasse PostDto {privat statisk slutt SimpleDateFormat dateFormat = ny SimpleDateFormat ("åååå-MM-dd HH: mm"); privat Lang id; privat strengetittel; privat String url; privat streng dato; privat UserDto-bruker; offentlig dato getSubmissionDateConverted (streng tidssone) kaster ParseException {dateFormat.setTimeZone (TimeZone.getTimeZone (tidssone)); retur datoFormat.parse (denne datoen); } public void setSubmissionDate (Date date, String timezone) {dateFormat.setTimeZone (TimeZone.getTimeZone (tidssone)); this.date = dateFormat.format (dato); } // standard getters and setters} 

Merk at de to egendefinerte datorrelaterte metodene håndterer datokonvertering frem og tilbake mellom klienten og serveren:

  • getSubmissionDateConverted () metoden konverterer dato String inn i en Dato i serverens tidssone for å bruke den i vedvarende Post enhet
  • setSubmissionDate () metoden er å sette DTOs dato til Post‘S Dato i gjeldende tidssone for brukeren.

4. Servicelaget

La oss nå se på en operasjon på tjenestenivå - som åpenbart vil fungere med enheten (ikke DTO):

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

Vi skal se på laget over tjenesten neste - kontrollerlaget. Det er her konverteringen faktisk vil skje også.

5. Kontrollerlaget

La oss nå ta en titt på en standard implementering av kontrolleren, og avsløre den enkle REST API for Post ressurs.

Vi skal vise her noen få enkle CRUD-operasjoner: opprette, oppdatere, få en og få alt. Og gitt operasjonene er ganske greie, vi er spesielt interessert i konverteringsaspektene for Entity-DTO:

@Controller klasse PostRestController {@Autowired privat IPostService postService; @Autowired privat IUserService userService; @Autowired privat 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 offentlig PostDto getPost (@PathVariable ("id") Lang 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); }}

Og her er vår konvertering fra Post enhet til PostDto:

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

Og her er konvertering fra DTO til en enhet:

private Post 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 hjelp av modellmapperen, konverteringslogikken er rask og enkel - vi bruker kart API for kartleggeren og få dataene konvertert uten å skrive en eneste linje med konverteringslogikk.

6. Enhetstesting

Til slutt, la oss gjøre en veldig enkel test for å sikre at konverteringene mellom enheten og DTO fungerer bra:

offentlig klasse PostDtoUnitTest {private ModelMapper modelMapper = ny ModelMapper (); @Test offentlig ugyldig nårConvertPostEntityToPostDto_thenCorrect () {Innlegg innlegg = nytt innlegg (); 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 = 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. Konklusjon

Dette var en artikkel om forenkle konverteringen fra enhet til DTO og fra DTO til enhet i en REST API for våren, ved å bruke modellmappebiblioteket i stedet for å skrive disse konverteringene for hånd.

Den fulle kildekoden for eksemplene er tilgjengelig i GitHub-prosjektet.

HVILLE bunnen

Jeg kunngjorde nettopp det nye Lær våren kurs, med fokus på det grunnleggende i vår 5 og vårstøvel 2:

>> KONTROLLER KURSET

$config[zx-auto] not found$config[zx-overlay] not found