Nội dung bài viết
I. Mở bài
Có nhiều TH chúng ta muốn lấy thông tin từ json của response, chúng ta có thể
- Dùng JsonPath để tách lấy 1 hoặc nhiều value
- Mapping json sang POJO để lấy nhiều value cùng lúc.
II. Cách mapping nói chung
JSON | Java |
---|---|
string | String |
number | int, long, double |
boolean | boolean |
object | object or Map<String, T> |
array | List |
null | any object |
Ví dụ:
Bạn sẽ cần các methods của JsonPath rest-assured để convert từ json sang POJO.
- Get 1 object
public <T> T getObject(String path, Class<T> objectType) VD: .getObject("", StoreResponse.class);
- Get List của 1 object nào đó
public <T> List<T> getList(String path, Class<T> genericType) VD: .getList("menu.popup.menuitem", MenuItem.class); .getList("", Config.class);
III. Các trường hợp mapping
1. Json có cả object, array, string, number
{ "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 5.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 } } }
POJO tương ứng:
@Data public class StoreResponse { private Store store; @Data static class Store { private List<Book> book; private Bicycle bicycle; } @Data static class Book { private String category; private String author; private String title; private double price; private String isbn; } @Data static class Bicycle { private String color; private double price; } }
Bạn hoàn toàn có thể dùng static class để không phải tạo mỗi 1 class ở 1 file riêng.
Code mẫu:
Response res = ... //call api StoreResponse storeRes = res.jsonPath().getObject("", StoreResponse.class);
Từ object StoreResponse
, bạn có thể lấy mọi thứ trong json.
- Lấy toàn bộ
title
các cuốn sách.
List<String> titles = storeRes.getStore().getBook() .stream() .map(StoreResponse.Book::getTitle) .collect(Collectors.toList()); System.out.println(titles); //[Sayings of the Century, Sword of Honour, Moby Dick, The Lord of the Rings]
- Lấy
price
của bicycle:
double price = storeRes.getStore().getBicycle().getPrice(); System.out.println(price); //19.95
2. Bạn chỉ muốn lấy 1 vài fileds vì object đó quá nhiều fields.
Ví dụ:
[ { "description": "h", "direction": 3, "id": "W4ECoXQBUKCmoPq7wNg0", "ip": "4.6.7.8", "port": 0, "protocol": 500, "time_created": 1600429495 }, { "description": "import from file", "direction": 3, "id": "w0eBfHEB9R5R0nHL3f61", "ip": "1.1.1.80", "port": 33, "protocol": 58, "time_created": 1586931817 }, { "description": "import from file", "direction": 1, "id": "u0eBfHEB9R5R0nHL3P6h", "ip": "1.1.1.70", "port": 33, "protocol": 6, "time_created": 1586931817 } ]
Mình chỉ muốn lấy 2 thông tin là ip
và port
, mình ko nhất thiết phải làm POJO mapping vào từng field của json, bạn có thể dùng annotation của Jackson.
@JsonIgnoreProperties(ignoreUnknown=true)
POJO tương ứng:
@Data @JsonIgnoreProperties(ignoreUnknown=true) public class Config { private String ip; private int port; }
Code mẫu:
List<Config> configs = JsonPath.with(res).getList("", Config.class); configs.forEach(System.out::println); //Config(ip=4.6.7.8, port=0) //Config(ip=1.1.1.80, port=33) //Config(ip=1.1.1.70, port=33)
3. Bạn chỉ muốn lấy 1 object con bên trong 1 object to.
Json ban đầu, mình chỉ muốn lấy phần menuitem
{ "menu": { "id": "file", "value": "File", "popup": { "menuitem": [ { "value": "New", "onclick": "CreateNewDoc()" }, { "value": "Open", "onclick": "OpenDoc()" }, { "value": "Close", "onclick": "CloseDoc()" } ] } } }
POJO
@Data public class MenuItem { private String value; private String onclick; }
Code mẫu:
List<MenuItem> items = JsonPath.with(res).getList("menu.popup.menuitem", MenuItem.class); items.forEach(System.out::println); //MenuItem(value=New, onclick=CreateNewDoc()) //MenuItem(value=Open, onclick=OpenDoc()) //MenuItem(value=Close, onclick=CloseDoc())
IV. Tổng kết
Trong bài, mình đã giới thiệu tổng hợp 1 số các kiến thức và các trường hợp khi mapping từ json sang POJO. Hi vọng có ích cho các bạn đang làm api testing có sử dụng rest-assured.