在本教程中,我们将学习如何在Spring Boot 应用程序中创建 DTO(数据传输对象)类,以及如何使用 ModelMapper 库将实体转换为 DTO,反之亦然。
数据传输对象设计模式是一种常用的设计模式。它基本上用于一次性将具有多个属性的数据从客户端传递到服务器,以避免多次调用远程服务器。
在用Java编写的RESTful API上使用DTO(以及在Spring Boot上)的另一个优点是,它们可以帮助隐藏域对象(JPA实体)的实现细节。如果我们不仔细处理可以通过哪些操作更改哪些属性,则通过终结点公开实体可能会成为安全问题。
让我们从介绍ModelMapper Java库开始,我们将使用它来将实体转换为DTO,反之亦然。
我们将在pom中需要这种依赖.xml:
-
org.modelmapper -
modelmapper -
2.3.5
我们将在pom中需要这种依赖.xml:
-
org.modelmapper -
modelmapper -
2.3.5
- package net.javaguides.springboot.model;
-
- import java.util.HashSet;
-
- import java.util.Set;
-
- import javax.persistence.Column;
- import javax.persistence.Entity;
- import javax.persistence.GeneratedValue;
- import javax.persistence.GenerationType;
- import javax.persistence.Id;
- import javax.persistence.Table;
- import javax.persistence.UniqueConstraint;
-
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.NoArgsConstructor;
-
- @Data
- @NoArgsConstructor
- @AllArgsConstructor
- @Entity
- @Table(name = "posts", uniqueConstraints = {@UniqueConstraint(columnNames = {"title"})})
- public class Post {
-
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
-
- @Column(name = "title")
- private String title;
-
- @Column(name = "description")
- private String description;
-
- @Column(name = "content")
- private String content;
- }
- package net.javaguides.springboot.payload;
-
- import java.util.HashSet;
- import java.util.Set;
-
- import lombok.Data;
-
- @Data
- public class PostDto {
- private long id;
- private String title;
- private String description;
- private String content;
- }
仅包含客户端所需的 DTO 类中的那些详细信息。实体和 DTO 字段看起来相同,但您将向客户端添加所需的字段。
- package com.springboot.blog.repository;
-
- import com.springboot.blog.entity.Post;
- import org.springframework.data.jpa.repository.JpaRepository;
-
- public interface PostRepository extends JpaRepository
{ -
- }
- package net.javaguides.springboot.service;
-
- import java.util.List;
-
- import net.javaguides.springboot.model.Post;
-
- public interface PostService {
- List
getAllPosts(); -
- Post createPost(Post post);
-
- Post updatePost(long id, Post post);
-
- void deletePost(long id);
-
- Post getPostById(long id);
- }
- package net.javaguides.springboot.service.impl;
-
- import java.util.List;
- import java.util.Optional;
-
- import org.springframework.stereotype.Service;
-
- import net.javaguides.springboot.exception.ResourceNotFoundException;
- import net.javaguides.springboot.model.Post;
- import net.javaguides.springboot.repository.PostResository;
- import net.javaguides.springboot.service.PostService;
-
- @Service
- public class PostServiceImpl implements PostService{
-
- private final PostResository postRepository;
-
- public PostServiceImpl(PostResository postRepository) {
- super();
- this.postRepository = postRepository;
- }
-
- @Override
- public List
getAllPosts() { - return postRepository.findAll();
- }
-
- @Override
- public Post createPost(Post post) {
- return postRepository.save(post);
- }
-
- @Override
- public Post updatePost(long id, Post postRequest) {
- Post post = postRepository.findById(id)
- .orElseThrow(() -> new ResourceNotFoundException("Post", "id", id));
-
- post.setTitle(postRequest.getTitle());
- post.setDescription(postRequest.getDescription());
- post.setContent(postRequest.getContent());
- return postRepository.save(post);
- }
-
- @Override
- public void deletePost(long id) {
- Post post = postRepository.findById(id)
- .orElseThrow(() -> new ResourceNotFoundException("Post", "id", id));
-
- postRepository.delete(post);
- }
-
- @Override
- public Post getPostById(long id) {
- Optional
result = postRepository.findById(id); - if(result.isPresent()) {
- return result.get();
- }else {
- throw new ResourceNotFoundException("Post", "id", id);
- }
-
- // Post post = postRepository.findById(id)
- // .orElseThrow(() -> new ResourceNotFoundException("Post", "id", id));
- //return post;
- }
- }
- package net.javaguides.springboot;
-
- import org.modelmapper.ModelMapper;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.context.annotation.Bean;
-
- @SpringBootApplication
- public class SpringbootBlogApiApplication {
-
- @Bean
- public ModelMapper modelMapper() {
- return new ModelMapper();
- }
-
- public static void main(String[] args) {
- SpringApplication.run(SpringbootBlogApiApplication.class, args);
- }
-
- }
- package net.javaguides.springboot.contoller;
-
- import java.util.List;
- import java.util.stream.Collectors;
-
- import org.modelmapper.ModelMapper;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.http.HttpStatus;
- import org.springframework.http.ResponseEntity;
- import org.springframework.web.bind.annotation.DeleteMapping;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.PathVariable;
- import org.springframework.web.bind.annotation.PostMapping;
- import org.springframework.web.bind.annotation.PutMapping;
- import org.springframework.web.bind.annotation.RequestBody;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- import net.javaguides.springboot.model.Post;
- import net.javaguides.springboot.payload.ApiResponse;
- import net.javaguides.springboot.payload.PostDto;
- import net.javaguides.springboot.service.PostService;
-
- @RestController
- @RequestMapping("/api/posts")
- public class PostController {
-
- @Autowired
- private ModelMapper modelMapper;
-
- private PostService postService;
-
- public PostController(PostService postService) {
- super();
- this.postService = postService;
- }
-
- @GetMapping
- public List
getAllPosts() { -
- return postService.getAllPosts().stream().map(post -> modelMapper.map(post, PostDto.class))
- .collect(Collectors.toList());
- }
-
- @GetMapping("/{id}")
- public ResponseEntity
getPostById(@PathVariable(name = "id") Long id) { - Post post = postService.getPostById(id);
-
- // convert entity to DTO
- PostDto postResponse = modelMapper.map(post, PostDto.class);
-
- return ResponseEntity.ok().body(postResponse);
- }
-
- @PostMapping
- public ResponseEntity
createPost(@RequestBody PostDto postDto) { -
- // convert DTO to entity
- Post postRequest = modelMapper.map(postDto, Post.class);
-
- Post post = postService.createPost(postRequest);
-
- // convert entity to DTO
- PostDto postResponse = modelMapper.map(post, PostDto.class);
-
- return new ResponseEntity
(postResponse, HttpStatus.CREATED); - }
-
- // change the request for DTO
- // change the response for DTO
- @PutMapping("/{id}")
- public ResponseEntity
updatePost(@PathVariable long id, @RequestBody PostDto postDto) { -
- // convert DTO to Entity
- Post postRequest = modelMapper.map(postDto, Post.class);
-
- Post post = postService.updatePost(id, postRequest);
-
- // entity to DTO
- PostDto postResponse = modelMapper.map(post, PostDto.class);
-
- return ResponseEntity.ok().body(postResponse);
- }
-
- @DeleteMapping("/{id}")
- public ResponseEntity
deletePost(@PathVariable(name = "id") Long id) { - postService.deletePost(id);
- ApiResponse apiResponse = new ApiResponse(Boolean.TRUE, "Post deleted successfully", HttpStatus.OK);
- return new ResponseEntity
(apiResponse, HttpStatus.OK); - }
- }
@PostMapping
public ResponseEntity createPost(@RequestBody PostDto postDto) {
// convert DTO to entity
Post postRequest = modelMapper.map(postDto, Post.class);
Post post = postService.createPost(postRequest);
// convert entity to DTO
PostDto postResponse = modelMapper.map(post, PostDto.class);
return new ResponseEntity(postResponse, HttpStatus.CREATED);
}
// change the request for DTO
// change the response for DTO
@PutMapping("/{id}")
public ResponseEntity updatePost(@PathVariable long id, @RequestBody PostDto postDto) {
// convert DTO to Entity
Post postRequest = modelMapper.map(postDto, Post.class);
Post post = postService.updatePost(id, postRequest);
// entity to DTO
PostDto postResponse = modelMapper.map(post, PostDto.class);
return ResponseEntity.ok().body(postResponse);
}
@GetMapping("/{id}")
public ResponseEntity getPostById(@PathVariable(name = "id") Long id) {
Post post = postService.getPostById(id);
// convert entity to DTO
PostDto postResponse = modelMapper.map(post, PostDto.class);
return ResponseEntity.ok().body(postResponse);
}
@GetMapping
public List getAllPosts() {
return postService.getAllPosts().stream().map(post -> modelMapper.map(post, PostDto.class))
.collect(Collectors.toList());
}