CÔNG NGHỆ THÔNG TIN >> SINH VIÊN BKAP

Tạo Rest API trong Spring boot làm việc với database sử dụng JPA

Đăng lúc: 08:57 AM - 08/04/2025 bởi Charles Chung - 160

Trong bài học này, chúng ta sẽ xây dựng một REST API sử dụng Spring Boot và JPA để làm việc với cơ sở dữ liệu. Chúng ta sẽ sử dụng một ví dụ với 2 bảng quan hệ One-to-Many trong cơ sở dữ liệu.

Yêu cầu: Tạo REST API thực hiện các thao tác CRUD với 2 bảng như hình dưới

Bước 1: Tạo project SpringBoot với tên session11example1 và chọn các dependency như hình dưới:

Bước 2: Tạo cấu trúc project như hình dưới

Bước 3: Code cho các lớp trong gói entities

- Code cho lớp Blog (biểu diễn thông tin bài viết - map với bảng blogs)

  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
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package com.bkap.entities;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotBlank;

@Entity
@Table(name="blogs")
public class Blog {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name="blogid")
	private Long blogId;
	
	@NotBlank(message = "Hãy nhập tiêu đề")
	@Column(name="title",length = 200)
	private String title;
	
	@NotBlank(message = "Hãy nhập mô tả")
	@Column(name="brief",length = 1000)
	private String brief;
	
	@Column(name="content",columnDefinition = "nvarchar(max)")
	private String content;
	
	@Column(name="picture",length = 1000)
	private String picture;
	
	@DateTimeFormat(pattern = "dd/MM/yyyy hh:mm a")
	@Column(name="createdate")
	private Date createDate;
	
	@Column(name="status")
	private int status;
	
	@ManyToOne
	@JoinColumn(name = "topicid",nullable = false)
	@JsonIgnoreProperties("blogs")
	private Topic topic=new Topic();
	
	public Topic getTopic() {
		return topic;
	}
	public void setTopic(Topic topic) {
		this.topic=topic;
	}
	public Long getBlogId() {
		return blogId;
	}

	public void setBlogId(Long blogId) {
		this.blogId = blogId;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getBrief() {
		return brief;
	}

	public void setBrief(String brief) {
		this.brief = brief;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public String getPicture() {
		return picture;
	}

	public void setPicture(String picture) {
		this.picture = picture;
	}

	public Date getCreateDate() {
		return createDate;
	}

	public void setCreateDate(Date createDate) {
		this.createDate = createDate;
	}

	
	public int getStatus() {
		return status;
	}

	public void setStatus(int status) {
		this.status = status;
	}
	
	
}

- Code cho lớp Topic  (biểu diễn thông tin chủ đề - map với bảng topics)

 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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package com.bkap.entities;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import org.springframework.format.annotation.DateTimeFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotBlank;

@Entity
@Table(name="topics")
public class Topic {
	@Id
	@GeneratedValue(strategy =GenerationType.IDENTITY)
	@Column(name="topicid")
	private Long topicId;
	@Column(name="topicname",length = 100,unique = true)
	@NotBlank(message = "Hãy nhập tên chủ đề")
	private String topicName;
	@Column(name="brief",length = 1000)
	private String brief;
	@Column(name="createdate")
	@DateTimeFormat(pattern = "dd/MM/yyyy hh:mm a")
	private Date createDate;
	@Column(name="status")
	private boolean status;
	
	@JsonIgnoreProperties("topic")
	@OneToMany(mappedBy = "topic")
	private Set<Blog> blogs=new HashSet<Blog>();
	
	public Set<Blog> getBlogs(){
		return blogs;
	}

	public Long getTopicId() {
		return topicId;
	}

	public void setTopicId(Long topicId) {
		this.topicId = topicId;
	}

	public String getTopicName() {
		return topicName;
	}

	public void setTopicName(String topicName) {
		this.topicName = topicName;
	}

	public String getBrief() {
		return brief;
	}

	public void setBrief(String brief) {
		this.brief = brief;
	}

	public Date getCreateDate() {
		return createDate;
	}

	public void setCreateDate(Date createDate) {
		this.createDate = createDate;
	}

	public boolean isStatus() {
		return status;
	}

	public void setStatus(boolean status) {
		this.status = status;
	}
	
	
}

Bước 4: Code cho các lớp trong gói models

- Code cho lớp BlogModel (biểu diễn thông bài viết - trả về client)

  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
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
package com.bkap.models;

import java.util.Date;

import com.bkap.entities.Blog;

public class BlogModel {
	private Long blogId;
	private String title;
	private String brief;
	private String content;
	private String picture;
	private Date createDate;
	private int status;	
	private Long topicId;	
	private String topicName;
	public BlogModel() {
		// TODO Auto-generated constructor stub
	}
	public BlogModel(Blog blog) {
		super();
		this.blogId = blog.getBlogId();
		this.title = blog.getTitle();
		this.brief = blog.getBrief();
		this.content = blog.getContent();
		this.picture = blog.getPicture();
		this.createDate = blog.getCreateDate();
		this.status = blog.getStatus();
		this.topicId = blog.getTopic().getTopicId();
		this.topicName = blog.getTopic().getTopicName();
	}

	public Long getTopicId() {
		return topicId;
	}

	public void setTopicId(Long topicId) {
		this.topicId = topicId;
	}

	public String getTopicName() {
		return topicName;
	}

	public void setTopicName(String topicName) {
		this.topicName = topicName;
	}

	public Long getBlogId() {
		return blogId;
	}

	public void setBlogId(Long blogId) {
		this.blogId = blogId;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getBrief() {
		return brief;
	}

	public void setBrief(String brief) {
		this.brief = brief;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public String getPicture() {
		return picture;
	}

	public void setPicture(String picture) {
		this.picture = picture;
	}

	public Date getCreateDate() {
		return createDate;
	}

	public void setCreateDate(Date createDate) {
		this.createDate = createDate;
	}

	
	public int getStatus() {
		return status;
	}

	public void setStatus(int status) {
		this.status = status;
	}
}

- Code cho lớp TopicModel (biểu diễn thông chủ đề- trả về client)

 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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.bkap.models;

import java.util.Date;

import com.bkap.entities.Topic;

public class TopicModel {
	private Long topicId;
	private String topicName;
	private String brief;
	private Date createDate;
	private boolean status;
	public TopicModel() {
		// TODO Auto-generated constructor stub
	}

	public TopicModel(Topic topic) {
		this.topicId = topic.getTopicId();
		this.topicName = topic.getTopicName();
		this.brief = topic.getBrief();
		this.createDate = topic.getCreateDate();
		this.status = topic.isStatus();
	}

	public Long getTopicId() {
		return topicId;
	}

	public void setTopicId(Long topicId) {
		this.topicId = topicId;
	}

	public String getTopicName() {
		return topicName;
	}

	public void setTopicName(String topicName) {
		this.topicName = topicName;
	}

	public String getBrief() {
		return brief;
	}

	public void setBrief(String brief) {
		this.brief = brief;
	}

	public Date getCreateDate() {
		return createDate;
	}

	public void setCreateDate(Date createDate) {
		this.createDate = createDate;
	}

	public boolean isStatus() {
		return status;
	}

	public void setStatus(boolean status) {
		this.status = status;
	}
}

Bước 5: Code cho các interface trong gói repositories

- Code cho interface TopicRepository (biểu diễn các nghiệp vụ làm việc với bảng topics)

1
2
3
4
5
6
7
8
9
package com.bkap.repositories;

import org.springframework.data.jpa.repository.JpaRepository;

import com.bkap.entities.Topic;

public interface TopicRepository extends JpaRepository<Topic,Long> {
	
}

- Code cho interface BlogRepository (biểu diễn các nghiệp vụ làm việc với bảng blogs)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package com.bkap.repositories;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import com.bkap.entities.Blog;

public interface BlogRepository extends JpaRepository<Blog, Long> {
	
	@Query("SELECT b FROM Blog b WHERE b.topic.topicId=:id")
	public List<Blog> findByTopicId(@Param("id") Long topicId);
	
	@Query("SELECT count(b)>0 FROM Blog b WHERE b.topic.topicId=:id")
	Boolean existsTopic(@Param("id")Long topicId);
	
}

Bước 6: Code cho các interface trong gói services

- Code cho lớp TopicService

 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
package com.bkap.services;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bkap.entities.Topic;
import com.bkap.models.TopicModel;
import com.bkap.repositories.TopicRepository;

@Service
public class TopicService {
	@Autowired
	private TopicRepository repository;
	
	public List<TopicModel> getAll(){
		return repository.findAll().stream().map(TopicModel::new).collect(Collectors.toList());
	}
	
	public Topic insert(Topic topic) {
		return repository.save(topic);
	}
	public Topic update(Topic topic) {
		Optional<Topic> tp=repository.findById(topic.getTopicId());
		if(tp.isPresent())
			return repository.save(topic);
		else
			return null;
	}
	public TopicModel getById(Long topicId) {
		Optional<Topic> topic=repository.findById(topicId);
		if(topic.isPresent())
			return new TopicModel(topic.get());
		else
			return null;
	}
	
	public void delete(Long topicId) {
		repository.deleteById(topicId);
	}
}

- Code cho lớp BlogService

 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
45
46
47
48
49
50
51
package com.bkap.services;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bkap.entities.Blog;
import com.bkap.models.BlogModel;

import com.bkap.repositories.BlogRepository;

@Service
public class BlogService {
	@Autowired
	BlogRepository repository;
	
	public List<BlogModel> getAll(){
		return repository.findAll().stream().map(BlogModel::new).collect(Collectors.toList());
	}
	
	public List<BlogModel> getBlogs(Long topicId) {
		return repository.findByTopicId(topicId).stream().map(BlogModel::new).collect(Collectors.toList());
	}
	
	public Boolean existTopic(Long topicId) {
		return repository.existsTopic(topicId);
	}
	
	public Blog insert(Blog blog) {
		return repository.save(blog);
	}
	public void delete(Long blogId) {
		repository.deleteById(blogId);
	}
	public Blog update(Blog blog) {
		Optional<Blog> temp=repository.findById(blog.getBlogId());
		if(!temp.isPresent())
			return null;
		return repository.save(blog);
	}
	public Blog getById(Long blogId) {
		Optional<Blog> blog=repository.findById(blogId);
		if(blog.isPresent())
			return  blog.get();
		else
			return null;
	}
}

Bước 7: Code cho các lớp controller trong gói controllers

- Code cho lớp TopicController

 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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package com.bkap.controllers;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
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.RestController;

import com.bkap.entities.Topic;

import com.bkap.models.TopicModel;
import com.bkap.services.BlogService;
import com.bkap.services.TopicService;

import jakarta.validation.Valid;

@RestController
public class TopicController {
	@Autowired
	TopicService topicService;
	@Autowired
	BlogService blogService;

	@GetMapping("/topics")
	public ResponseEntity<List<TopicModel>> getAll() {
		return new ResponseEntity<>(topicService.getAll(), HttpStatus.OK);
	}

	@PostMapping("/topics")
	public ResponseEntity<Object> post(@RequestBody @Valid Topic topic, BindingResult result) {
		if (result.hasErrors())
			return new ResponseEntity<>(result.getAllErrors().get(0).getDefaultMessage(), HttpStatus.BAD_REQUEST);
		else {
			topic.setCreateDate(new Date());
			return new ResponseEntity<>(topicService.insert(topic), HttpStatus.OK);
		}
	}

	@GetMapping("/topics/{id}")
	public ResponseEntity<Object> get(@PathVariable Long id) {
		TopicModel topic = topicService.getById(id);
		if (topic == null)
			return new ResponseEntity<>("Không tồn tại topic", HttpStatus.BAD_REQUEST);
		else
			return new ResponseEntity<>(topic, HttpStatus.OK);

	}

	@PutMapping("/topics/{id}")
	public ResponseEntity<Object> put(@PathVariable Long id, @RequestBody @Valid Topic topic, BindingResult result) {
		if (topic.getTopicId() != id)
			return new ResponseEntity<>("Mã không khớp", HttpStatus.BAD_REQUEST);
		if (result.hasErrors())
			return new ResponseEntity<>(result.getAllErrors().get(0).getDefaultMessage(), HttpStatus.BAD_REQUEST);
		else {
			topic.setCreateDate(new Date());
			Topic tp = topicService.update(topic);
			if (tp == null)
				return new ResponseEntity<>("Không tồn tại mã cần sửa", HttpStatus.BAD_REQUEST);
			else
				return new ResponseEntity<>(tp, HttpStatus.OK);
		}
	}

	@DeleteMapping("/topics/{id}")
	public ResponseEntity<String> delete(@PathVariable Long id) {
		if(blogService.existTopic(id))
			return new ResponseEntity<>("Topic đang có bài viết, không xóa được", HttpStatus.BAD_REQUEST);
		
		topicService.delete(id);
		return new ResponseEntity<>("Xóa thành công", HttpStatus.OK);
	}

	

	
}

- Code cho lớp BlogController

  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
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package com.bkap.controllers;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
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.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.bkap.entities.Blog; 
import com.bkap.models.BlogModel;
import com.bkap.services.BlogService;

import jakarta.validation.Valid;

@RestController
public class BlogController {
	
	 // Cấu hình thư mục để lưu ảnh
    @Value("${upload.directory:src/main/resources/static/images}")
    private String uploadDir;
    
	@Autowired
	BlogService blogService;
	
	@GetMapping("/blogs")
	public ResponseEntity<List<BlogModel>> getBlogs() {
		return new ResponseEntity<>(blogService.getAll(), HttpStatus.OK);
	}
	
	@GetMapping("/blogs/{id}")
	public ResponseEntity<Object> getBlog(@PathVariable Long id) {
		Blog blog=blogService.getById(id);
		if(blog==null)
			return new ResponseEntity<>("Không tìm thấy Id",HttpStatus.NOT_FOUND);
		return new ResponseEntity<>(new BlogModel(blog), HttpStatus.OK);
	}
	
	@GetMapping("/topics/{id}/blogs")
	public ResponseEntity<List<BlogModel>> getBlogByTopic(@PathVariable Long id) {
		return new ResponseEntity<>(blogService.getBlogs(id), HttpStatus.OK);
	}
	
	
	@DeleteMapping("/blogs/{id}")
	public ResponseEntity<String> delete(@PathVariable Long id) {
		blogService.delete(id);
		return new ResponseEntity<>("Xóa thành công", HttpStatus.OK);
	}
	
	@PostMapping("/blogs")
	public ResponseEntity<Object> post( @Valid @ModelAttribute Blog blog, BindingResult result,@RequestPart MultipartFile file) {
		if (result.hasErrors())
			return new ResponseEntity<>(result.getAllErrors().get(0).getDefaultMessage(), HttpStatus.BAD_REQUEST);
		else {
			//upload ảnh
			try {
				// upload ảnh
				if (!file.isEmpty()) {
					Path path=Paths.get(uploadDir,file.getOriginalFilename());
					File imageFolder=new File(uploadDir);
					if(!imageFolder.exists())
						imageFolder.mkdir();
					System.out.println(path);
					Files.copy(file.getInputStream(),path);
					blog.setPicture("/images/"+file.getOriginalFilename());
				}
			} catch (IllegalStateException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			blog.setCreateDate(new Date());
			return new ResponseEntity<>(blogService.insert(blog), HttpStatus.OK);
		}
	}
	@PutMapping("/blogs/{id}")
	public ResponseEntity<Object> put( @Valid @ModelAttribute Blog blog, BindingResult result,@RequestPart MultipartFile file, @PathVariable Long id, String pictureOld) {
		if (blog.getBlogId() != id)
			return new ResponseEntity<>("Mã không khớp", HttpStatus.BAD_REQUEST);
		
		if (result.hasErrors())
			return new ResponseEntity<>(result.getAllErrors().get(0).getDefaultMessage(), HttpStatus.BAD_REQUEST);
		else {
			//upload ảnh
			blog.setPicture(pictureOld);
			try {
				// upload ảnh
				if (!file.isEmpty()) {
					Path path=Paths.get(uploadDir,file.getOriginalFilename());
					File imageFolder=new File(uploadDir);
					if(!imageFolder.exists())
						imageFolder.mkdir();
					System.out.println(path);
					Files.copy(file.getInputStream(),path);
					blog.setPicture("/images/"+file.getOriginalFilename());
				}
			} catch (IllegalStateException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			blog.setCreateDate(new Date());
			var bl=blogService.update(blog);
			if(bl==null)
				return new ResponseEntity<>("Không tồn tại mã cần sửa", HttpStatus.BAD_REQUEST);
			else
				return new ResponseEntity<>(bl, HttpStatus.OK);
		}
	}
	@GetMapping("/images/{filename}")
    public ResponseEntity<byte[]> getImage(@PathVariable String filename) throws IOException {
        // Đọc ảnh từ thư mục static/images
        Path path = Paths.get(uploadDir, filename);
        byte[] image = Files.readAllBytes(path);
        // Trả về ảnh
        // Định dạng MIME của ảnh (tùy thuộc vào loại ảnh, ví dụ JPEG, PNG, ...)
        String contentType = Files.probeContentType(path);
        // Trả về ảnh dưới dạng byte[] với header Content-Type thích hợp
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_TYPE, contentType)
                .body(image);
    }
	
}

Bước 8: Chạy ứng dụng và sử dụng Postman để kiểm tra kết quả

Source tải tại đây

Video quay trong buổi dạy C2308G

thay lời cảm ơn!

QUẢNG CÁO - TIẾP THỊ