- Getting Started with Spring Boot
- Spring Restful Web Services Example
- Create Spring Boot Project With Spring Initializer
- Create Spring Boot Project in Spring Tool Suite [STS] // Popular
- Installing Spring Boot with Maven and Gradle
- Standard Project Structure for Spring Boot Projects // Popular
- Spring Boot 2 Hello World Application // Popular
- Overview of Spring Boot Starter Parent
- Important Spring Boot Starters with Examples
- Spring Boot Embedded Servers - Tomcat, Jetty, and Undertow
- Spring Boot How to Change Port and Context Path // Popular
- Spring Boot 2 Deploy WAR file to External Tomcat // Popular
- SpringBootServletInitializer Class in Spring Boot // Popular
- Different Ways of Running Spring Boot Application
- Migrating from Spring to Spring Boot
- Spring Boot Annotations // Popular
- SpringApplication Class in Spring Boot with Examples // Popular
- Spring Boot CLI Commands
- Spring RestTemplate - Spring REST Client GET, POST, PUT and DELETE Example
- Spring Boot 2 Hibernate 5 MySQL CRUD REST API Tutorial
- Spring Boot, MySQL, JPA, Hibernate Restful CRUD API Tutorial // LATEST
- Search REST API using Spring Boot, Spring Data JPA, and MySQL Database
- Spring Boot 2 JPA MySQL CRUD Example
- Spring Boot 2 Hello World Application
- Spring Boot 2 CRUD REST APIs Validation Example
- Spring Data JPA Auditing with Spring Boot 2 and MySQL Example
- Spring Boot 2 Exception Handling for REST APIs
- Spring Boot 2 Logging SLF4j Logback and LOG4j2 Example
- Spring Boot 2 + Jersey REST + JPA + Hibernate 5 CRUD REST APIs Example
- Spring Boot 2 - Scheduling Tasks
- Spring Boot 2 RESTful API Documentation with Swagger 2 Tutorial
- Spring Boot 2 - File Upload and Download Rest API Tutorial // LATEST
- Spring Boot - Loading Initial Data
- Spring Boot @PathVariable
- Spring Boot @ResponseBody
- Spring @RequestBody - Binding Method Parameters to Request Body
- Spring Boot @ResponseStatus Annotation
- Spring ResponseEntity - Using ResponseEntity in Spring Application
- Spring Boot Thymeleaf CRUD Example Tutorial // Popular
- Spring Boot CRUD Web Application with Thymeleaf, Spring MVC, Spring Data JPA, Hibernate, MySQL
- Spring Boot Thymeleaf CRUD Database Real-Time Project - PART 1
- Spring Boot Thymeleaf CRUD Database Real-Time Project - PART 2
- Spring Boot Thymeleaf CRUD Database Real-Time Project - PART 3
- Spring Boot Thymeleaf CRUD Database Real-Time Project - PART 4
- Spring Boot Thymeleaf CRUD Database Real-Time Project - PART 5
- Spring Boot Thymeleaf CRUD Database Real-Time Project - PART 6
- Spring Boot Thymeleaf CRUD Database Real-Time Project - PART 7
- Spring Boot JSP Example Tutorial
- Spring Boot Thymeleaf Example Tutorial
- Spring MVC + Spring Boot2 + JSP + JPA + Hibernate 5 + MySQL Example
- Spring Boot 2 MVC Web Application Thymeleaf JPA MySQL Example // Popular
- Spring Boot 2 - Spring MVC + Thymeleaf Input Form Validation
- Spring Boot JPA Multiple Data Sources Example // Popular
- Angular 12 + Spring Boot CRUD Example
- Angular CRUD Example with Spring Boot
- Spring Boot + Angular 10 CRUD Example Tutorial
- Spring Boot + Angular 9 CRUD Example Tutorial
- Spring Boot + Angular 8 CRUD Example Tutorial
- Spring Boot + Angular 6 CRUD Example
- Spring Boot 2 + Angular 7 CRUD Example Tutorial
- Angular 8 + Spring Boot Example Tutorial
- Spring Boot + Angular 8 + WebSocket Example Tutorial
- Spring Boot + Angular + MongoDB CRUD Example
- Spring Boot + Angular + PostgreSQL CRUD Example
- Spring Boot + React JS CRUD Example Tutorial
- React JS + Spring Boot REST API Example Tutorial
- React + Spring Boot + PostgreSQL CRUD Example
- React + Spring Boot + MongoDB CRUD Example
- React JS (React Hooks) + Spring Boot Tutorial
- Spring Boot 2 + Role-Based Spring Security + JPA + Thymeleaf + MySQL Tutorial // Popular
- Authenticating a User with LDAP using Spring Boot and Spring Security
- User Registration Module + Spring Boot 2 + Spring Security + Hibernate 5 + Thymeleaf + MySQL // Popular
- User Account Registration and Login using Spring Boot, Spring Security, Spring Data JPA, Hibernate, H2, JSP, and Bootstrap
- Spring Boot + Spring AOP Logging Example Tutorial // Popular
- Spring AOP + AspectJ @Before, @After, @AfterReturning, @AfterThrowing, and @Around
- SpringBoot JpaRepository Example Tutorial
- Spring Boot CrudRepository Example Tutorial
- Spring Data JPA Repository Testing using Spring Boot @DataJpaTest
- Spring Boot JPA Multiple Data Sources Example // Popular
- Spring Boot 2 JPA MySQL CRUD Example
- Spring Data JPA Auditing with Spring Boot 2 and MySQL Example
- Spring Data JPA One-to-One Unidirectional Mapping
- Spring Data JPA One to Many Unidirectional Mapping
- Spring Data JPA One to Many Bidirectional Mapping
- Spring Data JPA Many to Many Unidirectional Mapping
- Spring Data JPA Many to Many Bidirectional Mapping
- Spring Data JPA One-to-One Bidirectional Mapping
- Spring Boot 2 Java-Based Configuration Example
- Spring Boot 2 XML Configuration Example
- Migrating from Spring to Spring Boot
- Spring Data JPA Repository Testing using Spring Boot @DataJpaTest
- Spring Boot Unit Testing CRUD REST API with JUnit and Mockito
- Spring Boot Integration Testing MySQL CRUD REST API Tutorial
- Spring Boot Unit Testing Service Layer using JUnit and Mockito
- Spring Boot Testing - Data Access Layer Integration Testing using Testcontainers
- CRUD JUnit Tests for Spring Data JPA - Testing Repository Layer
- Spring Boot Testing - REST API Integration Testing using Testcontainers
- Spring Boot @Bean Annotation Example
- Spring @Qualifier Annotation Example
- Spring @Autowired Annotation with Example
- Spring @Bean Annotation with Example
- Spring @Configuration Annotation with Example
- Spring @PropertySource Annotation with Example
- Spring @Import Annotation with Example
- Spring @ImportResource Annotation Example
- Spring - @Lazy Annotation Example
- Spring - @Primary Annotation Example
- Spring @PostConstruct and @PreDestroy Example
- Spring @Repository Annotation
- Spring @Service Annotation
- The Spring @Controller and @RestController Annotations
- Spring Boot @Component, @Controller, @Repository and @Service
- Spring @Scope annotation with Prototype Scope Example
- Spring @Scope annotation with Singleton Scope Example
- Spring Boot @PathVariable
- Spring Boot @ResponseBody
- Spring @RequestBody - Binding Method Parameters to Request Body
- Spring Boot @ResponseStatus Annotation
- Spring Boot - Creating Asynchronous Methods using @Async Annotation
- SpringBootTest Spring Boot Example
- SpringBootTest vs @WebMvcTest
- DataJpaTest Spring Boot Example
- Spring @GetMapping, @PostMapping, @PutMapping, @DeleteMapping and @PatchMapping
- Spring Boot @EnableAutoConfiguration Annotation with Example
- Spring Boot @SpringBootApplication Annotation with Example
- Spring Boot + PostgreSQL + JPA/Hibernate CRUD Restful API Tutorial // Popular
- Spring Boot + Microsoft SQL Server + JPA/Hibernate CRUD Restful API Tutorial // Popular
- Configure Spring boot application with H2, HSQL, and Derby embedded databases // LATEST
- Spring Boot MariaDB CRUD Example Tutorial
- Spring Boot + JPA / Hibernate + Oracle CRUD Example
- Mini Todo Management Project using Spring Boot + Spring MVC + Spring Security + JSP + Hibernate + MySQL // Popular
- User Registration Module using Spring Boot + Spring MVC + Spring Security + Hibernate 5 + Thymeleaf + MySQL // Popular
- Spring Boot CRUD Web Application with Thymeleaf, Spring MVC, Spring Data JPA, Hibernate, MySQL
- Spring Boot Thymeleaf CRUD Database Real-Time Project - PART 1
- Spring Boot Thymeleaf CRUD Database Real-Time Project - PART 2
- Spring Boot Thymeleaf CRUD Database Real-Time Project - PART 3
- Spring Boot Thymeleaf CRUD Database Real-Time Project - PART 4
- Spring Boot Thymeleaf CRUD Database Real-Time Project - PART 5
- Spring Boot Thymeleaf CRUD Database Real-Time Project - PART 6
- Spring Boot Thymeleaf CRUD Database Real-Time Project - PART 7
- Spring Boot + React JS CRUD Example Tutorial
- 10+ Free Open Source Projects Using Spring Boot (Very Useful)
- Spring Boot + JPA/Hibernate One-to-One Mapping Example
- Spring Boot JPA/Hibernate One to Many Example Tutorial
- Spring Boot Hibernate Many to Many Example
- Spring Data JPA One-to-One Unidirectional Mapping
- Spring Data JPA One-to-One Bidirectional Mapping
- Spring Data JPA One to Many Unidirectional Mapping
- Spring Data JPA One to Many Bidirectional Mapping
- Spring Data JPA Many to Many Unidirectional Mapping
- Spring Data JPA Many to Many Bidirectional Mapping
- Free Spring Boot ReactJS Open Source Projects | GitHub
- 10+ Free Open Source Projects Using Spring Boot
- 20+ Free Open Source Projects Using Spring Framework
- Free Open Source Angular Projects or Templates [GitHub]
- Free Spring Boot Microservices Open Source Projects | GitHub | Download
- Free Spring Boot Angular Open Source Projects | GitHub
- Mức độ log: ERROR, WARN, INFO, DEBUG và TRACE.
- Các cấu hình mặc định được cung cấp để hỗ trợ cho Java Util Logging, Log4J2, SLF4J và Logback.
Mức độ | Màu | Nội dung |
---|---|---|
FATAL | Đỏ | Chỉ định các sự kiện lỗi rất nghiêm trọng có thể khiến ứng dụng bị hủy bỏ hoặc dừng lại. |
ERROR | Đỏ | Chỉ định các sự kiện lỗi có thể xảy ra mà vẫn cho phép ứng dụng tiếp tục chạy. |
WARN | Vàng | Chỉ định các tình hướng có thể gây hại cho ứng dụng đang chạy. |
INFO | Xanh | Chỉ định các thông báo cung cấp thông tin làm nổi bật tiến trình của ứng dụng ở cấp độ chi tiết. |
DEBUG | Xanh | Chỉ định các sự kiện thông tin chi tiết hữu ích để gỡ lỗi ứng dụng. |
TRACE | Xanh | Chỉ định các sự kiện thông tin chi tiết hơn cấp độ DEBUG. |
-
@Value("${jwt.secret-key}")
: lưu ý, @Value là annotation của Spring và không hoạt động với các thuộc tinhStatic
-
@SqlResultSetMappings
: được sử dụng để định nghĩa các kết quả của câu truy vấn SQL dưới dạng tập hợp các@SqlResultSetMapping
annotation. được sử dụng để ánh xạ các cột quan hệ dữ liệu của câu truy vấn SQL thành đối tượng Java. Bằng cách chỉ định tên của@SqlResultSetMapping
annotation, bạn có thể lựa chọn các cột từ kết quả truy vấn và ánh xạ chúng vào các thuộc tính của đối tượng Java. -
@NamedNativeQuery
là một annotation được sử dụng trong JPA (Java Persistence API) để định nghĩa một truy vấn SQL nguyên thủy (native query). -
@Transactional
: Annotation@Transactional
được đặt trước một phương thức hoặc một lớp và chỉ định rằng phương thức hoặc tất cả các phương thức trong lớp được gọi trong một giao dịch (transaction). Giao dịch dùng để đảm bảo tính nhất quán của dữ liệu và bảo đảm rằng các thay đổi được thực hiện thành công hoặc rollback nếu có lỗi xảy ra. Annotation này giúp giảm thiểu việc viết mã để quản lý giao dịch thủ công và đảm bảo rằng các thay đổi dữ liệu được xử lý một cách an toàn và nhất quán. -
@Modifying
: Annotation@Modifying
được sử dụng để chỉ định rằng phương thức đang thực hiện một hành động sửa đổi dữ liệu trong cơ sở dữ liệu, không phải là một truy vấn truy xuất dữ liệu. Annotation này cần được sử dụng kèm với annotation@Transactional
. -
@Query
: Annotation@Query
được sử dụng để định nghĩa truy vấn SQL hoặc JPQL (Java Persistence Query Language) mà phương thức sẽ thực hiện. VớinativeQuery = true
, câu lệnh truy vấn được sử dụng là một câu lệnh SQL gốc (Native SQL) thay vì truy vấn JPQL. Các tham số của truy vấn được chỉ định bằng cách sử dụng các tham số có tên (?1, ?2, ...) và các tham số này sẽ được truyền vào từ các tham số của phương thức.
SYNTAX DESCRIPTION
SYNTAX | DESCRIPTION |
---|---|
@Api | Đánh dấu 1 class là nơi chứa các API |
@ApiModel | Đánh dấu 1 class là Swagger Model |
@ApiModelProperty | Bổ sung các thông tin cho |
@ApiOperation | Mô tả cho một API và response của nó |
@ApiParam | Mô tả các parameter |
@ApiResponse | Mô tả status code của response |
@ApiResponses | Mô tả danh sách các status code của response |
GeneratedValue: và Trường sinh này áp dụng cho các trường kiểu số nguyên (integer)
hoặc số dấu thập phân (decimal)
GenerationType.AUTO
: là một kiểu sinh giá trị tự động. hệ thống sẽ cố gắng tự động xác định cách sinh giá trị tốt nhất dựa trên cơ sở dữ liệu bạn đang sử dụng.
@GeneratedValue(strategy = GenerationType.AUTO)
GenerationType.IDENTITY
: Được sử dụng với các cơ sở dữ liệu hỗ trợ tự động tăng (auto-increment) như MySQL hoặc PostgreSQL. Khi bạn chọn kiểu này, cơ sở dữ liệu sẽ tự động tăng giá trị của trường này khi một bản ghi mới được thêm vào cơ sở dữ liệu.
@GeneratedValue(strategy = GenerationType.IDENTITY)
=> id int8 NOT NULL GENERATED BY DEFAULT AS IDENTITY
GenerationType.SEQUENCE
: Sử dụng với cơ sở dữ liệu hỗ trợ chuỗi số (sequence) như Oracle. Bạn cần phải cung cấp tên của chuỗi số mà bạn muốn sử dụng.
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "your_sequence_name")
GenerationType.TABLE
: Sử dụng với cơ sở dữ liệu không hỗ trợ tự động tăng hoặc chuỗi số. Hibernate (một triển khai JPA phổ biến) sẽ sử dụng một bảng tạm thời để theo dõi và sinh giá trị duy nhất cho trường.
@GeneratedValue(strategy = GenerationType.TABLE, generator = "your_table_generator_name")
- Hibernate tạo lược đồ tự động :
spring.jpa.hibernate.ddl-auto=true
- Nếu chúng ta vẫn muốn có cả Hibernate tạo lược đồ tự động kết hợp với tạo lược đồ dựa trên tập lệnh và tập hợp dữ liệu, chúng ta sẽ phải sử dụng:
spring.jpa.defer-datasource-initialization=true
- Khởi tạo cơ sở dữ liệu bằng tập lệnh, chúng ta sẽ phải sử dụng:
spring.sql.init.mode=always
Spring cung cấp một thuộc tính JPA cụ thể mà Hibernate sử dụng để tạo DDL: spring.jpa.hibernate.ddl-auto.
- create (tạo) : Trước tiên Hibernate bỏ các bảng hiện có và sau đó tạo các bảng mới.
- update (cập nhật): Mô hình đối tượng được tạo dựa trên ánh xạ (Annotations hoặc XML) được so sánh với lược đồ hiện có, sau đó Hibernate cập nhật lược đồ theo sự khác biệt. Nó không bao giờ xóa các bảng hoặc cột hiện có ngay cả khi chúng không còn được ứng dụng yêu cầu.
- create - drop (tạo - xóa): Tương tự như tạo, với việc bổ sung Hibernate sẽ xóa cơ sở dữ liệu sau khi tất cả các hoạt động hoàn thành; thường được sử dụng cho unit testing.
- validate (xác thực): Hibernate chỉ xác nhận xem các bảng và cột có tồn tại hay không. Nếu không, nó sẽ ném ra một ngoại lệ.
- none: Giá trị này sẽ ngay lập tức tắt tạo DDL.
always
: luôn khởi tạo cơ sở dữ liệuembedded
: luôn khởi khởi tạo nếu một cơ sở dữ liệu nhúng đang được sử dụng. Đây là mặc định nếu giá trị thuộc tính không được chỉ định.never
: không bao giờ khởi tạo cơ sở dữ liệu
@SQL: Spring cũng cung cấp Annotatios @Sql - một cách khai báo để khởi tạo và điền vào lược đồ thử nghiệm của chúng ta.
@Sql({"/employees_schema.sql", "/import_employees.sql"})
public class SpringBootInitialLoadIntegrationTest {
@Autowired
private EmployeeRepository employeeRepository;
@Test
public void testLoadDataForTestClass() {
assertEquals(3, employeeRepository.findAll().size());
}
}
SQL: Chú thích này có thể được sử dụng để gắn SQL query vào một lớp hoặc một phương thức trong dự án Spring Boot của bạn.
@SQL("SELECT * FROM users WHERE username = :username")
public User findUserByUsername(String username) {
// Thực hiện truy vấn SQL ở đây
}
SQLConfig: Chú thích này có thể được sử dụng để cấu hình các thiết lập liên quan đến SQL query, ví dụ như cơ sở dữ liệu mặc định để sử dụng.
@SQLConfig(key = "production")
public class ProductionDatabaseConfig {
// Cấu hình cho cơ sở dữ liệu sản xuất
}
- @Entity : được sử dụng để chú thích một class là một Entity.
- Thuộc tính name của @Entity là không bắt buộc.
- Entity khớp với một bảng lấy theo tên theo thứ tự ưu tiên:
- name trong @Table.
- name trong @Entity.
- name của class.
- Một table trong database có thể có nhiều ràng buộc unique (duy nhất). Chúng ta có thể sử dụng @Table để mô tả các ràng buộc này
- @Table cho phép chú thích tên bảng thông qua thuộc tính name (thuộc tính này không bắt buộc).
- Nếu không chỉ rõ tên bảng trong phần tử name, Hibernate sẽ dựa vào phần tử name của @Entity sau đó mới tới tên của class.
- @Column được sử dụng để chỉ định thông tin chi tiết của cột mà một field của entity sẽ được ánh xạ với một column trong database.
- Thuộc tính name được sử dụng để chị định tên cột nào trong database map với tên field được chú thích.
- Thuộc tính length cho phép kích thước của cột. @Column không chỉ rõ phần tử length, mặc định nó là 255.
- Thuộc tính nullable cho phép cột được đánh dấu KHÔNG NULL khi schema được tạo ra. Giá trị nullable mặc định là true.
- Thuộc tính unique cho phép cột được đánh dấu chỉ chứa các giá trị duy nhất.
- Trong entity class có chứa một field mà
field này không tồn tồn tại trong database
. Khi đó chúng ta sẽ gặp lỗi “java.sql.SQLSyntaxErrorException: Unknown column ‘additionalPropery’ in ‘field list'”. - Để tránh lỗi này, chúng ta có thể sử dụng @Transient để thông báo rằng thuộc tính/ phương thức này không liên quan gì tới một cột nào dưới database. Khi đó, Hibernate sẽ bỏ qua field này.
- @Temporal sử dụng để chú thích cho cột dữ liệu ngày tháng và thời gian (date time).
- Có 3 giá trị cho TemporalType:
- TemporalType.DATE : chú thích cột sẽ lưu trữ ngày tháng năm (bỏ đi thời gian).
- TemporalType.TIME : chú thích cột sẽ lưu trữ thời gian (Giờ phút giây).
- TemporalType.TIMESTAMP : chú thích cột sẽ lưu trữ ngày tháng và cả thời gian.
- @Id được sử dụng để mô tả đây là Id (Identity) của Entity, nó tương đương với cột đó là khóa chính (Primary Key) của table trong database.
- @GeneratedValue được sử dụng để Hibernate tự động tạo ra giá trị và gán vào cho một cột trong trường hợp insert mới một Entity vào database.
@Lob
thường chú thích cùng với@Column
để nói rằng cột đó có kiểuBLOB
hoặcCLOB
. Trong một số Database có phân biệt TINY, MEDIUM, LARGE BLOB/CLOB, còn một số database thì không.
@Lob
@Column(name = "avatar", nullable = true, length = Integer.MAX_VALUE)
private byte[] avatar;
- @ManyToOne mô tả một quan hệ N-1 (Nhiều – Một), nó thường được sử dụng cùng với @JoinColumn.
FetchType.LAZY
: LAZY nói với Hibernate rằng, hãy tải dữ liệu một cách lười biếng, nghĩa là chỉ tải khi được gọi (khi cần thiết).FetchType.EAGER
: EAGER nói với Hibernate rằng, hãy truy vấn toàn bộ các cột của bảng liên quan.
@OneToMany
mô tả quan hệ 1-N (Một – Nhiều). Nó là đảo ngược của @ManyToOne, và vì vậy nó dựa vào @ManyToOne để định nghĩa ra @OneToMany.
@OneToOne
mô tả quan hệ 1-1 (Một – Một).
- @ManyToMany mô tả quan hệ N-N (Nhiều – Nhiều).
@Entity
@Table
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "roles")
private Set<User> users;
}
@Entity(name = "User")
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// ...
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "user_roles",
joinColumns = { @JoinColumn(name = "user_id", nullable = false, updatable = false) },
inverseJoinColumns = { @JoinColumn(name = "role_id", nullable = false, updatable = false) })
private Set<Role> roles;
}
- @OrderBy được sử dụng để sắp xếp một danh sách, vì vậy nó có thể được sử dụng cùng với @OneToMany, @ManyToMany.
@Entity
@Table
public class Category {
// ...
@OneToMany(fetch = FetchType.LAZY, mappedBy = "category")
@OrderBy("title")
private Set<Post> posts;
}
EnumType.ORDINAL
: Khi sử dụng kiểu này, JPA sẽ lưu giá trị của enum dưới dạng số nguyên, tức là vị trí của hằng số enum trong khai báoEnumType.STRING
: Khi sử dụng kiểu này, JPA sẽ lưu giá trị của enum dưới dạng chuỗi, tức là tên của hằng số enum12. Điều này giúp giữ nguyên độ rõ ràng của mã nguồn và đảm bảo tính nhất quán khi thay đổi cấu trúc của enum
public enum Status {
OPEN,
CLOSED
}
@Entity
public class Article {
@Id
private int id;
private String title;
@Enumerated(EnumType.STRING)
private Status status;
}
OAuth2 có 4 loại định danh chính:
- Authorization Code
- Resource Owner Password Credentials
- Implicit
- Client Credentials
Để xác thực thì cần:
Client Client ID
: chuỗi ký tự được sử dụng để định danh ứng dụng.Client Secret
: là một chuỗi ký tự dùng cho việc xác thực Client khi ứng dụng yêu cầu truy cập thông tin tài khoản người dùng. Chuỗi này được giữ bí mật giữa Client và Authorization Server.
Có thể hiểu Client ID là username, Client Secret là password của Client đối với Authorization cũng được. 😄
+--------+ +---------------+
| |--(A)- Authorization Request ->| Resource |
| | | Owner |
| |<-(B)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(C)-- Authorization Grant -->| Authorization |
| Client | | Server |
| |<-(D)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(E)----- Access Token ------>| Resource |
| | | Server |
| |<-(F)--- Protected Resource ---| |
+--------+ +---------------+
+--------+ +---------------+
| |--(A)------- Authorization Grant --------->| |
| | | |
| |<-(B)----------- Access Token -------------| |
| | & Refresh Token | |
| | | |
| | +----------+ | |
| |--(C)---- Access Token ---->| | | |
| | | | | |
| |<-(D)- Protected Resource --| Resource | | Authorization |
| Client | | Server | | Server |
| |--(E)---- Access Token ---->| | | |
| | | | | |
| |<-(F)- Invalid Token Error -| | | |
| | +----------+ | |
| | | |
| |--(G)----------- Refresh Token ----------->| |
| | | |
| |<-(H)----------- Access Token -------------| |
+--------+ & Optional Refresh Token +---------------+
- @JsonSerialize: được sử dụng để chỉ định cách một trường hoặc thuộc tính của một đối tượng Java sẽ được chuyển đổi thành JSON khi sử dụng thư viện Jackson
- @JsonInclude: được sử dụng để chỉ định rằng các trường có giá trị null sẽ không được bao gồm trong đầu ra JSON. và ngược lại nếu khác null sẽ được hiển thị ở đầu JSON.
- @JsonSerialize(using = LocalDateTimeSerializer.class): Chú thích này định nghĩa rằng trường hoặc thuộc tính nơi nó được áp dụng sẽ được chuyển đổi từ kiểu dữ liệu LocalDateTime của Java thành chuỗi JSON bằng cách sử dụng một lớp serializer tùy chỉnh là LocalDateTimeSerializer.class. Lớp serializer này sẽ quyết định cách biểu diễn một đối tượng LocalDateTime thành chuỗi JSON.
- @JsonDeserialize(using = LocalDateTimeDeserializer.class): Chú thích này định nghĩa rằng khi chuyển đổi từ chuỗi JSON thành đối tượng Java, trường hoặc thuộc tính nơi nó được áp dụng sẽ được chuyển đổi từ chuỗi JSON thành kiểu dữ liệu LocalDateTime của Java bằng cách sử dụng một lớp deserializer tùy chỉnh là LocalDateTimeDeserializer.class. Lớp deserializer này sẽ quyết định cách chuyển đổi chuỗi JSON thành một đối tượng LocalDateTime.
@Configuration
public class ModelMapperConfig {
@Bean
public ModelMapper modelMapper() {
// Tạo object và cấu hình
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration()
.setMatchingStrategy(MatchingStrategies.STRICT);
return modelMapper;
}
}
sau đó là dùng `model mapper' để map giữa entity với dto và ngược lại:
@Service
public class UserService {
// Có thể inject bằng cách khác, mình viết như thế này cho gọn
@Autowired
private final ModelMapper mapper;
public UserDto getUser(String username) {
// Lấy User entity ra từ DB
User user = userRepository.findByUsername(username);
// Map thành DTO
UserDto userDto = mapper.map(user, UserDto.class);
return userDto;
}
}
có 3 loại mapping, mỗi loại có một hằng số biểu diễn (để set config):
- Chiến lược map chuẩn:
MatchingStrategies.STANDARD
- Chiến lược map lỏng lẻo:
MatchingStrategies.LOOSE
- Chiến lược map chặt chẽ:
MatchingStrategies.STRICT
Vài thuộc tính cấu hình căn bản như sau:
- setSkipNullEnabled() có cho phép bỏ qua thuộc tính null hay không
- setDeepCopyEnabled() mặc định dùng shallow copy, dùng deep copy thì sẽ chậm hơn.
- setMatchingStrategy() đặt loại mapping (như phần trên)
- setFieldAccessLevel() chỉ định field truy cập ở mức độ nào (private, public,...)
- setMethodAccessLevel() chỉ định mức độ truy cập method, getter và setter (như trên)
- setSourceNameTokenizer() chỉ định quy ước đặt tên cho thuộc tính ở source (object nguồn dùng để map)
- setDestinationNameTokenizer() chỉ định quy ước đặt tên cho thuộc tính ở đích (object map ra).