NỘI DUNG BÀI HỌC
✅ Khái niệm JSON
✅ Jsonpath
✅ Json Extractor
✅ Ví dụ minh họa
✅ Best practices
1. JSON là gì?
JSON (JavaScript Object Notation) là một dạng lưu trữ và trao đổi dữ liệu rất gọn nhẹ.
-
Người dùng có thể dễ dàng đọc và viết JSON.
-
Máy tính cũng dễ dàng xử lý và tạo ra JSON.
JSON được xây dựng dựa trên hai dạng chính:
-
Cặp khóa/giá trị: Trong nhiều ngôn ngữ lập trình, thể hiện như object, dictionary, hash table hoặc key-value list.
-
Danh sách có thứ tự: Thể hiện như array, list, vector, sequence.
✳️Cấu trúc JSON: Object
-
Object là một tập hợp các cặp khóa – giá trị (name/value pairs), không theo thứ tự cố định.
-
Bắt đầu bằng
{
và kết thúc bằng}
. -
Mỗi tên đi kèm một giá trị, nối với nhau bằng dấu
:
. -
Các cặp phân tách bằng dấu
,
.
👉 Nói ngắn gọn: Object giống như một bảng thông tin gồm nhiều thuộc tính (tên) và giá trị tương ứng.
Ví dụ:
{ "name": "Tom", "age": 30, "city": "Ho Chi Minh"}
Ở đây:
- name là tên thuộc tính, "Tom" là giá trị.
- age là tên thuộc tính, 30 là giá trị.
- city là tên thuộc tính, "Ho Chi Minh" là giá trị.
2. JSONPath

JSONPath là một ngôn ngữ truy vấn dùng để trích xuất dữ liệu từ tài liệu JSON.
-
Tương tự XPath trong XML, nhưng áp dụng cho JSON.
-
Trong JMeter, JSON Extractor sử dụng JSONPath để lấy dữ liệu từ response.
🔆Cú pháp cơ bản
Cú pháp | Ý nghĩa | Ví dụ |
---|---|---|
$ |
Root (gốc JSON) | $.order.id |
. |
Truy cập thuộc tính con | $.user.name |
[*] |
Chọn tất cả phần tử mảng | $.users[*].id |
[n] |
Phần tử thứ n (0-based) | $.users[0].name |
[-1] |
Phần tử cuối | $.users[-1].name |
.. |
Tìm ở mọi cấp | $..price |
?() |
Biểu thức lọc | $.products[?(@.price>1000)] |
@ |
Đối tượng hiện tại | $.products[?(@.name=="iPhone 15")] |
3. JSON Extractor
JSON Extractor dùng để trích xuất dữ liệu từ response JSON (REST API).
Vị trí thêm: (Sampler) → Add → Post Processors → JSON Extractor
✳️Các trường cấu hình quan trọng
-
Name of created variable(s): Tên biến kết quả (ví dụ:
authToken
, hoặc nhiều biến cách nhau;
). -
JSON Path expressions: Biểu thức JSONPath, 1–1 với tên biến.
-
Match No.:
-
1, 2, 3…
→ lấy giá trị thứ n (index từ 1). -
-1
→ lấy tất cả kết quả →${var_1}
,${var_2}
, …,${var_matchNr}
. -
0
→ lấy ngẫu nhiên một kết quả.
-
-
Default Values: Giá trị mặc định nếu không tìm thấy.
-
Compute concatenation var (tuỳ phiên bản): Ghép tất cả kết quả bằng dấu
,
hoặc ký tự khác.
👉 Biến sinh ra khi Match Numbers = -1: ${var_1}, ${var_2}, … và ${var_matchNr} (tổng số match).
4. Ví dụ minh họa
a. Lấy giá trị đơn
Response:
{
"status": "success",
"user": { "id": 12345, "name": "Nguyen Van A", "token": "abc123xyz" }
}
- Var: authToken
- JSONPath: $.user.token
- Match No.: 1 → ${authToken} = abc123xyz
b. Lấy phần tử trong mảng
Response:
{ "users": [ {"id":101}, {"id":102}, {"id":103} ] }
- Var: uid
- JSONPath: $.users[*].id
- Match No.: -1
→ ${uid_1}=101, ${uid_2}=102, ${uid_3}=103, ${uid_matchNr}=3
c. Wildcard / Deep-scan
Response:
{"a": {"id": 1}, "b": {"id": 2}, "c": {"x": {"id": 3}}}
- JSONPath: $..id (deep-scan mọi cấp)
→ 1, 2, 3 (với -1)
d. Lọc theo điều kiện
Response:
{ "products": [
{"id":1, "name":"iPhone 15", "price":2500},
{"id":2, "name":"Samsung S24", "price":1800},
{"id":3, "name":"Xiaomi 14", "price":900}
]}
- Lấy id theo name:JSONPath: $.products[?(@.name=='Samsung S24')].id → 2
- Lấy name price > 1000:
$.products[?(@.price>1000)].name → ["iPhone 15","Samsung S24"]
Lưu ý: Filter trả một mảng. Dùng -1 để nhận từng phần tử ${var_1}, ${var_2}…
e. Nhiều biến – nhiều biểu thức
Response:
{
"order": {
"id": "ORD12345",
"date": "2025-08-26",
"customer": { "name": "Nguyen Van A", "email": "vana@example.com", "address": { "city": "Hanoi", "zip": "100000" } },
"items": [
{ "sku": "IP15", "name": "iPhone 15", "qty": 1, "price": 2500 },
{ "sku": "S24", "name": "Samsung S24", "qty": 2, "price": 1800 }
],
"status": "PAID"
}
}
- Name of variables: orderId;customerName;city
- JSONPath expressions: $.order.id;$.order.customer.name;$.order.customer.address.city
- Default Values: NA;NA;NA
f. Khóa động (dynamic keys)
Response:
{ "meta": { "v2025-08": {"build": 776, "status":"ok"} } }
- Khi khoá con biến đổi theo phiên bản, dùng deep-scan:
JSONPath: $..build → 776
g. Lấy mảng lồng nhau
Response:
{ "order": { "items": [
{"sku":"A1","batches":[{"lot":"L1"},{"lot":"L2"}]},
{"sku":"B2","batches":[{"lot":"L3"}]}
]}}
- JSONPath: $.order.items[*].batches[*].lot
→ ${lot_1}=L1, ${lot_2}=L2, ${lot_3}=L3
h. Chuỗi JSON trong JSON (2 bước)
Response:
{ "data": "{\"token\":\"ABC123\"}" }
- B1 JSON Extractor lấy chuỗi: $.data → ${raw}
- B2 JSON Extractor (áp trên Sample Variables → JMeter Variables):
- Variable names: token
- JSONPath: $.token
- JMeter Variable Name to use: raw (tuỳ cách bạn tổ chức; hoặc dùng JSR223 để parse)
i. Lọc nâng cao
Lấy id của sản phẩm có price > 900 và name là Samsung S24
- → $.products[?(@.price > 900 && @.name == "Samsung S24")].id
k. Xử lý không tồn tại (graceful)
- Set Default Value rõ ràng (NOT_FOUND), tránh rỗng gây lỗi tham chiếu ở bước sau.
- Kết hợp Response Assertion để fail sớm nếu token không được trả về.
5. Best Practices
- Dùng $..field để tìm ở mọi cấp, nhưng cẩn trọng số lượng match.
- Luôn cấu hình Default Values khi phát triển kịch bản.
- Giữ JSONPath ngắn & ổn định, hạn chế phụ thuộc thứ tự nếu API có thể đổi.