Bài 33-Xử lý JSon trong Kotlin – Bài 2


Trong bài 32 Tui đã trình bày chi tiết cách sử dụng thư viện GSon để Lưu Kotlin Model thành JSon và Đọc JSon thành Kotlin Model như thế nào. Ở bài này Tui tiếp tục làm thêm một ví dụ phức tạp hơn về JSon trong Kotlin, đó là tạo ra 2 lớp có mối quan hệ Master-Detail, đây là một trong những trường hợp thường gặp nhiều nhất trong quá trình triển khai dự án thật. Cụ thể Tui sẽ bổ sung thêm một Lớp Danh Mục, nó có mối quan hệ với Lớp Sản Phẩm: Một Danh Mục có nhiều Sản phẩm và Một Sản phẩm thuộc về một danh Mục nào đó. Để qua đây chúng ta tìm hiểu xem GSon tạo ra file JSon như thế nào cũng như phục hồi lại Kotlin Model ra sao.

Bài này Tui sẽ đi trực tiếp vào kỹ thuật lập trình luôn, còn lý thuyết các bạn tự xem lại bài 32 nhé.

Lớp Sản Phẩm có cấu trúc như sau:


import java.io.Serializable

/**
* Created by cafe on 03/06/2017.
*/
class SanPham {
var MaSanPham:Int=0
var TenSanPham:String=""
var DonGia:Double=0.0
constructor()
constructor(MaSanPham: Int, TenSanPham: String, DonGia: Double) {
this.MaSanPham = MaSanPham
this.TenSanPham = TenSanPham
this.DonGia = DonGia
}
override fun toString(): String {
return MaSanPham.toString()+"\t"+TenSanPham+"\t"+DonGia
}
}

Cấu trúc của lớp Danh Mục:


import java.io.Serializable

/**
* Created by cafe on 03/06/2017.
*/
class DanhMuc {
var MaDanhMuc:Int=0
var TenDanhMuc:String=""
var SanPhams:MutableList<SanPham> = mutableListOf()
constructor()
constructor(MaDanhMuc: Int, TenDanhMuc: String) {
this.MaDanhMuc = MaDanhMuc
this.TenDanhMuc = TenDanhMuc
}
override fun toString(): String {
var s=""
for (sp in SanPhams)
s+="\t"+sp.toString() + "\n"
var infor="Danh Mục:["+MaDanhMuc.toString()+ "\t"+TenDanhMuc+"]"
infor+="\nCác Sản phẩm của danh Mục này là:\n"+s
return infor
}
fun ThemSanPham(sp:SanPham)
{
SanPhams.add(sp)
}
}

Như Tui đã nói ở bài 32, GSon không quan tâm cấu trúc và mối quan hệ giữa các lớp mà bạn viết như thế nào. Nó “cân” hết (đừng bị đệ quy là được, nếu ko nó bị stack over flow)

Giờ ta tiếp tụ tạo lớp JSonFileFactory, nó có cấu trúc như dưới đây (giống nhau trong mọi trường hợp nếu bạn dùng kiểu dữ liệu là Any)


import com.google.gson.Gson
import java.io.FileWriter
import java.io.FileReader
import com.google.gson.reflect.TypeToken

/**
* Created by cafe on 02/06/2017.
*/
class JSonFileFactory {
/**
* @author Trần Duy Thanh
* @param data: Dữ liệu là Danh sách sản phẩm muốn lưu
* @param path: Đường dẫn lưu trữ
* @return true nếu lưu thành công, false nếu lưu thất bại
*/
fun LuuFile(data:MutableList<DanhMuc>,path:String):Boolean
{
try {
val gs= Gson()
val file=FileWriter(path)
gs.toJson(data,file)
file.close()
return true
}
catch (ex:Exception)
{
ex.printStackTrace()
}
return false
}
/**
* @author Trần Duy Thanh
* @param path:đường dẫn muốn đọc dữ liệu
* @return Danh sách sản phẩm MutableList
*/
fun DocFile(path:String):MutableList<DanhMuc>
{
var data:MutableList<DanhMuc> = mutableListOf()
try
{
val gson = Gson()
var file=FileReader(path)
data = gson.fromJson<MutableList<DanhMuc>>(file,
object : TypeToken<MutableList<DanhMuc>>()
{
}.type
)
file.close()
}
catch (ex:Exception)
{
ex.printStackTrace()
}
return data
}
}

Cuối cùng ta tạo hàm main để kiểm tra:


fun main(args: Array<String>) {
var database:MutableList<DanhMuc> = mutableListOf<DanhMuc>()

var dmDienTu:DanhMuc=DanhMuc(1,"Mặt hàng điện tử")
database.add(dmDienTu)

var bongden:SanPham=SanPham(1,"Bóng đèn điện Quang",150.0)
dmDienTu.ThemSanPham(bongden)
var acquy:SanPham=SanPham(2,"Ắc quy Đồng Nai",250.0)
dmDienTu.ThemSanPham(acquy)
var maydien:SanPham=SanPham(3,"Máy phát điện ABC",90.0)
dmDienTu.ThemSanPham(maydien)

var dmTieuDung:DanhMuc=DanhMuc(2,"Mặt hàng tiêu dùng")
database.add(dmTieuDung)

var xabong:SanPham=SanPham(4,"Xà Bông Lifeboy",15.0)
dmTieuDung.ThemSanPham(xabong)
var nuocruachen:SanPham=SanPham(5,"Nước rửa chén Sunlight",12.0)
dmTieuDung.ThemSanPham(nuocruachen)

var dmHoaChat:DanhMuc=DanhMuc(3,"Mặt hàng Hóa Chất")
database.add(dmHoaChat)

var dietmuoi:SanPham=SanPham(6,"Thuốc Diệt Muỗi XYZ",80.0)
dmHoaChat.ThemSanPham(dietmuoi)
var dietchuot:SanPham=SanPham(7,"Thuốc Diệt Chuỗi ABC",70.0)
dmHoaChat.ThemSanPham(dietchuot)

for (dm in database)
println(dm)

var kqLuu= JSonFileFactory().LuuFile(database,"d:/dulieudanhmuc.json")
if(kqLuu)
{
println("Lưu Json file thành công")
}
else
{
println("Lưu Json file thất bại")
}
}

Khi chạy hàm main ở trên thì ta có kết quả sau:

Danh Mục:[1 Mặt hàng điện tử]
Các Sản phẩm của danh Mục này là:
1 Bóng đèn điện Quang 150.0
2 Ắc quy Đồng Nai 250.0
3 Máy phát điện ABC 90.0Danh Mục:[2 Mặt hàng tiêu dùng]
Các Sản phẩm của danh Mục này là:
4 Xà Bông Lifeboy 15.0
5 Nước rửa chén Sunlight 12.0

Danh Mục:[3 Mặt hàng Hóa Chất]
Các Sản phẩm của danh Mục này là:
6 Thuốc Diệt Muỗi XYZ 80.0
7 Thuốc Diệt Chuỗi ABC 70.0

Lưu Json file thành công

Bây giờ ta vào ổ D xem tập tin dulieudanhmuc.json có được lưu thành công hay chưa:

Rõ ràng kết quả đã lưu thành công, bạn quan sát thấy cấu trúc Json này có gì khác biệt? Đó là mỗi một đối tượng danh Mục nó một mảng SanPhams–>được GSon tự động tạo ra từ mối quan hệ của 2 Lớp DanhMuc + SanPham

Bây giờ ta sẽ gọi hàm đọc thông tin lên nhé:


fun main(args: Array<String>) {
var database:MutableList<DanhMuc> =
JSonFileFactory().DocFile("d:/dulieudanhmuc.json")
for (dm in database)
println(dm)
}

Khi chạy hàm main ở trên thì ta có kết quả sau:

Danh Mục:[1 Mặt hàng điện tử]
Các Sản phẩm của danh Mục này là:
1 Bóng đèn điện Quang 150.0
2 Ắc quy Đồng Nai 250.0
3 Máy phát điện ABC 90.0Danh Mục:[2 Mặt hàng tiêu dùng]
Các Sản phẩm của danh Mục này là:
4 Xà Bông Lifeboy 15.0
5 Nước rửa chén Sunlight 12.0

Danh Mục:[3 Mặt hàng Hóa Chất]
Các Sản phẩm của danh Mục này là:
6 Thuốc Diệt Muỗi XYZ 80.0
7 Thuốc Diệt Chuỗi ABC 70.0

Có vẻ tới đây các bạn thấy rằng JSon sẽ dễ lập trình hơn Text File, Serialize File, và XML File đúng không? Hiện nay cấu trúc JSon được sử dụng rất nhiều, ngày càng phổ biến và các lập trình viên rất thích điều này.

Như vậy ta đã Ví dụ xong trường hợp phức  tạp của JSon File đó là có mối quan hệ giữa các lớp, các bạn tự áp dụng vào các dự án cụ thể nhé. Bài sau Tui sẽ trình bày thêm cách lấy dữ liệu Json từ Internet trong Kotlin. Cụ thể là lấy Tỉ Giá hối đoái của Ngân Hàng Đông Á, Json có cấu trúc phức tạp, các bạn chú ý theo dõi nhé

Các bạn có thể tải source code bài này ở đây: http://www.mediafire.com/file/hk795a31148wsb0/HocJSon_DanhMucSanPham.rar

Hẹn gặp các bạn ở những bài tiếp theo

Chúc các bạn thành công!

Trần Duy Thanh (http://ssoftinc.com/)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: