EntityToDTOConversionforaSpringRESTAPI

编程

2. Model Mapper

Let"s start by introducing the main library that we"re going to use to perform this entity-DTO conversion – ModelMapper.

We will need this dependency in the pom.xml:

1

2

3

4

5

<

dependency

>

    

<

groupId

>org.modelmapper</

groupId

>

    

<

artifactId

>modelmapper</

artifactId

>

    

<

version

>2.3.5</

version

>

</

dependency

>

To check if there"s any newer version of this library, go here.

We"ll then define the ModelMapper bean in our Spring configuration:

1

2

3

4

@Bean

public

ModelMapper modelMapper() {

    

return

new

ModelMapper();

}

3. The DTO

Next, let"s introduce the DTO side of this two-sided problem – Post DTO:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

public

class

PostDto {

    

private

static

final

SimpleDateFormat dateFormat

      

=

new

SimpleDateFormat(

"yyyy-MM-dd HH:mm"

);

 

    

private

Long id;

 

    

private

String title;

 

    

private

String url;

 

    

private

String date;

 

    

private

UserDto user;

 

    

public

Date getSubmissionDateConverted(String timezone)

throws

ParseException {

        

dateFormat.setTimeZone(TimeZone.getTimeZone(timezone));

        

return

dateFormat.parse(

this

.date);

    

}

 

    

public

void

setSubmissionDate(Date date, String timezone) {

        

dateFormat.setTimeZone(TimeZone.getTimeZone(timezone));

        

this

.date = dateFormat.format(date);

    

}

 

    

// standard getters and setters

}

Note that the two custom date related methods handle the date conversion back and forth between the client and the server:

  • getSubmissionDateConverted() method converts date String into a Date in server"s timezone to use it in the persisting Post entity
  • setSubmissionDate() method is to set DTO"s date to Post‘s Date in current user timezone.

4. The Service Layer

Let"s now look at a service level operation – which will obviously work with the Entity (not the DTO):

1

2

3

4

5

6

7

8

9

10

public

List<Post> getPostsList(

  

int

page,

int

size, String sortDir, String sort) {

  

    

PageRequest pageReq

     

= PageRequest.of(page, size, Sort.Direction.fromString(sortDir), sort);

  

    

Page<Post> posts = postRepository

      

.findByUser(userService.getCurrentUser(), pageReq);

    

return

posts.getContent();

}

We"re going to have a look at the layer above service next – the controller layer. This is where the conversion will actually happen as well.

5. The Controller Layer

Let"s now have a look at a standard controller implementation, exposing the simple REST API for the Post resource.

We"re going to show here a few simple CRUD operations: create, update, get one and get all. And given the operations are pretty straightforward, we are especially interested in the Entity-DTO conversion aspects:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

@Controller

class

PostRestController {

 

    

@Autowired

    

private

IPostService postService;

 

    

@Autowired

    

private

IUserService userService;

 

    

@Autowired

    

private

ModelMapper modelMapper;

 

    

@GetMapping

    

@ResponseBody

    

public

List<PostDto> getPosts(...) {

        

//...

        

List<Post> 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

    

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(post);

    

}

}

And here is our conversion from Post entity to PostDto:

1

2

3

4

5

6

private

PostDto convertToDto(Post post) {

    

PostDto postDto = modelMapper.map(post, PostDto.

class

);

    

postDto.setSubmissionDate(post.getSubmissionDate(),

        

userService.getCurrentUser().getPreference().getTimezone());

    

return

postDto;

}

And here is the conversion from DTO to an entity:

1

2

3

4

5

6

7

8

9

10

11

12

private

Post convertToEntity(PostDto postDto)

throws

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());

    

}

    

return

post;

}

So, as you can see, with the help of the model mapper, the conversion logic is quick and simple – we"re using the map API of the mapper and getting the data converted without writing a single line of conversion logic.

6. Unit Testing

Finally, let"s do a very simple test to make sure the conversions between the entity and the DTO work well:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

public

class

PostDtoUnitTest {

 

    

private

ModelMapper modelMapper =

new

ModelMapper();

 

    

@Test

    

public

void

whenConvertPostEntityToPostDto_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

    

public

void

whenConvertPostDtoToPostEntity_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. Conclusion

This was an article on simplifying the conversion from Entity to DTO and from DTO to Entity in a Spring REST API, by using the model mapper library instead of writing these conversions by hand.

The full source code for the examples is available in the GitHub project.

以上是 EntityToDTOConversionforaSpringRESTAPI 的全部内容, 来源链接: utcz.com/z/513016.html

回到顶部