post-image

YAML sang List của Objects trong Spring Boot

Tổng quan

Trong bài viết ngắn này chúng ta sẽ cùng nhau tìm hiểu cách ánh xạ một danh sách được định nghĩa trong tệp cấu hình YAML sang List object trong Spring Boot.

Tóm lược nhanh về Lists trong YAML

Spring Boot hiện nay đã hỗ trợ định dạng YAML để viết file cấu hình dự án ngoài định dạng properties. Để định nghĩa một danh sách các phần tử trong file YAML chúng ta có thể làm như sau:

yamlconfig:
  list:
    - item1
    - item2
    - item3
    - item4Code language: PHP (php)

Các phần tử trong một List được bắt đầu bằng ký tự “-“, ngoài ra YAML còn hỗ trợ chúng ta định nghĩa các cấu trúc phức tạp khác như Map, Scaler type.

THAM KHẢO WEBSITE SPRING BOOT

Để đạt được cấu hình tương tự như trên trong định dạng properties thì chúng ta phải làm như sau:

yamlconfig.list[0]=item1
yamlconfig.list[1]=item2
yamlconfig.list[2]=item3
yamlconfig.list[3]=item4Code language: PHP (php)

Binding YAML List sang 1 List đơn giản trong Object

Spring boot hỗ trợ @ConfigurationProperties annotation dùng để ánh xạ một list từ YAML vào object model rất dễ dàng. Giả sử chúng ta có file YAML có cấu hình sau:

application:
  profiles:
    - dev
    - test
    - prod
    - 1
    - 2

Sau đó, chúng ta có thể ánh xạ bằng cách định nghĩa ApplicationProps sử dụng @ConfigurationProperties để ánh xạ dữ liệu từ YAML sang

@Component
@Getter
@Setter
@ConfigurationProperties(prefix = "application")
public class ApplicationProps {
    private List<String> profiles;
}Code language: PHP (php)

Ở trên mình đã sử dụng @Component để đánh dấu ApplicationProps là một bean trong hệ thống, chúng ta có thể inject chúng ở bất cứ đâu mà chúng ta muốn sử dụng.

Giờ chúng ta có thể kiểm tra bằng một unit-test nhỏ như sau:

@SpringBootTest
class YamlListConvertApplicationTests {
  @Autowired ApplicationProps props;
  @Test
  void testLoad() {
    for(String item: props.getProfiles()) {
      System.out.println("Profile: " + item);
    }
  }
}Code language: JavaScript (javascript)

Output:

Profile: dev
Profile: test
Profile: prod
Profile: 1
Profile: 2Code language: HTTP (http)

Binding YAML Lists sang Complex Lists

Trong trường hợp chúng ta định nghĩa một cấu trúc phức tạp trong file YAML mà không đơn thuần là một List String nữa thì chúng ta sẽ phải cần làm thêm một số công việc bắt buộc.

Giả sử file YAML của mình được định nghĩa thêm như sau:

application:
  // ...
  props: 
    -
      name: YamlList
      url: http://yamllist.dev
      description: Mapping list in Yaml to list of objects in Spring Boot
    -
      ip: 10.10.10.10
      port: 8091
    -
      email: [email protected]
      contact: http://yamllist.dev/contact
  users:
    -
      username: admin
      password: admin@10@
      roles:
        - READ
        - WRITE
        - VIEW
        - DELETE
    -
      username: guest
      password: guest@01
      roles:
        - VIEWCode language: PHP (php)

Trong đó chúng ta có thể thấy props chứa nested object và users chứa một List các objet đại diện cho một User.

Tổng hợp 200+ tài liệu, sách, bài thực hành, video hướng dẫn lập trình… từ cơ bản đến nâng cao

Đối với props không có quy luật cố định chúng ta có thể sử dụng Map để ánh xạ, còn với users thì chúng ta có thể định nghĩa một User class chứa các thuộc tính tương ứng trong YAML.

public class ApplicationProps {
    
    // ...
	
    private List<Map<String, Object>> props;
    private List<User> users;
    
    // getters and setters

    public static class User {

        private String username;
        private String password;
        private List<String> roles;

        // getters and setters

    }
}Code language: PHP (php)

Testing:

@ExtendWith(SpringExtension.class)
@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class)
@EnableConfigurationProperties(value = ApplicationProps.class)
class YamlComplexListsUnitTest {
 
    @Autowired
    private ApplicationProps applicationProps;
 
    @Test
    public void whenYamlNestedLists_thenLoadComplexLists() {
        assertThat(applicationProps.getUsers().get(0).getPassword()).isEqualTo("admin@10@");
        assertThat(applicationProps.getProps().get(0).get("name")).isEqualTo("YamlList");
        assertThat(applicationProps.getProps().get(1).get("port").getClass()).isEqualTo(Integer.class);
    }
	
}Code language: CSS (css)

Output

Profile: dev
Profile: test
Profile: prod
Profile: 1
Profile: 2
Name: YamlList
Port: 8091
Username: adminCode language: HTTP (http)

Tóm lược

Qua bài viết này chúng ta đã biết cách binding một List object từ YAML. Ngoài ra chúng ta cũng đã biết cách binding một list object có cấu trúc phức tạp. 

Leave a Reply

Your email address will not be published. Required fields are marked *