Thao tác với file .properties Spring framework

Sharing now

5/5 - (1 bình chọn)

Cách đọc ghi file .properties Spring framework

Ở bài này mình sẽ làm ví dụ về các cách đọc và ghi thông tin vào file .properties với Spring Boot.

1. File application.properties dùng để lưu cái gì?

File properties trong Java được sử dụng để lưu trữ dữ liệu cấu hình dự án hoặc các thông số cài đặt cho dự án như thông số port, mail, jdbc connection…
Thông tin trong file Properties là các cặp key/value cấu hình cho dự án của bạn. Trong mỗi cặp key/value đều là các giá trị kiểu String.
Ví dụ file application.properties:

# Connection url for the database
spring.datasource.url=jdbc:mysql://localhost:3306/myemployee?useSSL=false
# MySQL username and password
spring.datasource.username=root
spring.datasource.password=root

2. Đọc properties file

Các cách đọc thông tin từ file properties với Spring Framework.

Sử dụng annotation @Value

Cách đơn giản nhất là sử dụng annotation @Value để lấy giá trị trong file application.properites vào thuộc tính của các Spring Bean.

// file application.properties
message=ShareEverythings.com
//java class
package qlam.com.springboothello.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import qlam.com.springboothello.bean.GlobalConfig;
@Controller
public class Controller {
  @Value("${message}")
  private String message;
}

Sử dụng annotation @PropertySource để đọc những file .properites khác application.properties

Ví dụ đọc từ file global.properties thay vì application.properties

// file global.properties
website=shareeverythings.com
facebook=facebook.com/xmaster699
name=qlam
//java
package qlam.com.springboothello.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@PropertySource("classpath:global.properties")
public class GlobalConfig {
  @Value("${name}")
  private String name;
  @Value("${website}")
  private String website;
  @Value("${facebook}")
  private String facebook;
}

Sử dụng annotation @ConfigurationProperties

Annotation @ConfigurationProperties sẽ tự động mapping thuộc tính của bean với các giá trị trong file .properties. Lưu ý: tên tương ứng phải giống nhau.

package qlam.com.springboothello.bean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties
@PropertySource("classpath:global.properties")
public class GlobalConfig {
  private String name;
  private String website;
  private String facebook;
}

Sử dụng Environment

Bạn chỉ cần dùng biến Environment là có thể lấy các message trong file .properties.
Mặc định Environment lấy message từ trong file application.properties, nếu bạn muốn nó đọc từ các file khác thì dùng kèm với @PropertySource như mục trước.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
@Service
public class Service {
  @Autowired
  Environment env;
  public void hello() {
    System.out.println(env.getProperty("message"));
  }
}

Validate dữ liệu từ file properties

@ConfigurationProperties Hỗ trợ validate dữ liệu với javax.validation
Để validate dữ liệu ta sử dụng annotation @Validated ở đầu class và các annotation validate ở mỗi field ví dụ dùng @NotEmpty:

// File GlobalConfig.java
package qlam.com.springboothello.bean;
import javax.validation.constraints.NotEmpty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
@Component
@ConfigurationProperties
@PropertySource("classpath:global.properties")
@Validated
public class GlobalConfig {
  @NotEmpty
  private String name;
  private String website;
  private String facebook;
}

Nếu dữ liệu không hợp lệ thì ứng dụng sẽ thông báo lỗi:

***************************
APPLICATION FAILED TO START
***************************
Description:
Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under '' to qlam.com.springboothello.bean.GlobalConfig failed:
    Property: .name
    Value:
    Origin: "name" from property source "class path resource [global.properties]"
    Reason: must not be empty
Action:
Update your application's configuration

Đọc properties file từ classpath

Giả sử file “application.properties” nằm trong thư mục gốc của classpath (Khi build dự án sẽ có thư mục target/classes/application.properties )

remote.server=192.168.1.100
remote.server.port=8080
remote.user=qlam
remote.password=qlam
package qlam.example;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class LoadPropertiesFromClasspath {
	public static void main(String[] args) {
		Properties prop = new Properties();
		InputStream input = null;
		try {
			String filename = "application.properties";
			input = LoadPropertiesFromClasspath.class.getClassLoader().getResourceAsStream(filename);
			if (input == null) {
				System.out.println("Sorry, unable to find " + filename);
				return;
			}
			// load a properties file from class path, inside static method
			prop.load(input);
			// get the property value and print it out
			prop.entrySet().forEach(e -> System.out.println(e.getKey() + " : " + e.getValue()));
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			if (input != null) {
				try {
					input.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

Kết quả chạy:

remote.server : 192.168.1.100
remote.server.port : 8080
remote.user : qlam
remote.password : qlam

Đọc các file properties phức tạp

// file menu.properties
#App
app.menus[0].title=Home
app.menus[0].name=Home
app.menus[0].path=/home
app.menus[1].title=Login
app.menus[1].name=Login
app.menus[1].path=/login

Hoặc với file yaml. Xem bài thao tác với file .yml

// file menu.yml
app:
  menus:
  - title: Home
    name: Home
    path: /home
  - title: Login
    name: Login
    path: /login

Lưu ý: annotation @ConfigurationProperties hỗ trợ cả file.properties và file.yml.

package qlam.com.springboothello.bean;
import java.util.ArrayList;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties("app") // prefix app, find app.* values
@PropertySource("classpath:menu.properties")
public class MenuConfig {
  private List<Menu> menus = new ArrayList<>();
  public List<Menu> getMenus() {
    return menus;
  }
  public void setMenus(List<Menu> menus) {
    this.menus = menus;
  }
  public static class Menu {
    private String name;
    private String path;
    private String title;
    @Override
    public String toString() {
      return "Menu{" + "name='" + name + '\'' + ", path='" + path + '\'' + ", title='" + title + '\'' + '}';
    }
}

Demo tổng hợp

File Properties:

//File application.properties
message=ShareEverythings.com
// File menu.properties
#App
app.menus[0].title=Home
app.menus[0].name=Home
app.menus[0].path=/home
app.menus[1].title=Login
app.menus[1].name=Login
app.menus[1].path=/login
//File global.properties
website=shareeverythings.com
facebook=facebook.com/xmaster699
name=qlam
File Controller:
//File BaseController.java
package qlam.com.springboothello.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import qlam.com.springboothello.bean.GlobalConfig;
import qlam.com.springboothello.bean.MenuConfig;
@Controller
public class BaseController {
  @Autowired
  private GlobalConfig globalConfig;
  @Autowired
  private MenuConfig menuConfig;
  @Value("${message}")
  private String message;
  @RequestMapping("/")
  public String index(Model model) {
    model.addAttribute("name", globalConfig.getName());
    model.addAttribute("website", globalConfig.getWebsite());
    model.addAttribute("facebook", globalConfig.getFacebook());
    model.addAttribute("message", message);
    model.addAttribute("menus", menuConfig.getMenus());
    return "index";
  }
}
File view:
// File index.html
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring Boot - Share Everything </title>
</head>
<body>
  <h1>Spring Boot Properites file</h1>
  <table>
    <tr>
      <td>Name:</td>
      <td><p th:text="${name}">Default Name</p></td>
    </tr>
    <tr>
      <td>Website:</td>
      <td><p th:text="${website}">Default Website</p></td>
    </tr>
    <tr>
      <td>Facebook:</td>
      <td><p th:text="${facebook}">Default Facebook</p></td>
    </tr>
    <tr>
      <td>Message:</td>
      <td><p th:text="${message}">Default Message</p></td>
    </tr>
    Menu:
    <ul th:if="${menus != null && !menus.empty}">
      <li th:each="menu: ${menus}" th:text="${menu}"></li>
    </ul>
  </table>
</body>
</html>

Kết quả:
properties file

3. Ghi dữ liệu động vào properties file

Thiết lập giá trị của thuộc tính và lưu nó vào properties file có tên là application.properties

package qlam.properties.example;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;
public class WriteProperties {
	public static void main(String[] args) {
		Properties prop = new Properties();
		OutputStream output = null;
		try {
			output = new FileOutputStream("application.properties");
			// set the properties value
			prop.setProperty("remote.server", "192.168.1.100");
			prop.setProperty("remote.server.port", "8080");
			prop.setProperty("remote.user", "qlam");
			prop.setProperty("remote.password", "qlam");
			// save properties to project root folder
			prop.store(output, null);
		} catch (IOException io) {
			io.printStackTrace();
		} finally {
			if (output != null) {
				try {
					output.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

Sau khi run, file application.properties sẽ được sinh ra với nội dung như sau:

remote.server=192.168.1.100
remote.server.port=8080
remote.user=qlam
remote.password=qlam

Xong mình đã hướng dẫn cách đọc và ghi thông tin vào file .properties với Spring Boot. Bạn nào thắc mắc gì thì hãy bình luận bên dưới nhé !


Sharing now

Viết một bình luận