Tổng hợp học liệu các khóa Online


Dear all
vì nhiều em không biết tải học liệu trên hệ thống và nhiều bạn cần để tham khảo. Nên Thầy cung cấp giáo trình, Slide, source code của toàn bộ 15 khóa học Online đang publish:
👉1) Giải đề thi Excel: http://www.mediafire.com/file/5agwyapc35cvbmi/communityuni.com%23%23%23Excel-Slides_BaiTap_DeThi.rar
👉2) C++: http://www.mediafire.com/file/992rxcbfq13oatc/communityuni.com%23%23%23C++-giaotrinh-sourcecode-slide.rar/file
👉3) CTDL & Giải thuật: http://www.mediafire.com/file/3qjtpgaa9a53o3t/communityuni.com%23%23%23CTDL_GT_Tap1.rar
👉4) C# cơ bản:
slide:http://www.mediafire.com/file/51vvkmm01qey5ze/communityuni.com%23%23%23Slides_LapTrinhC%23Trong5Tuan_CoBan.rar
code:http://www.mediafire.com/file/sb7kl39ro2trk1r/communityuni.com%23%23%23Sourecode_LapTrinhC%23Trong5Tuan_CoBan.rar
👉5) C# nâng cao:
Slide:http://www.mediafire.com/file/2abat1cxkm6sbkc/communityuni.com%23%23%23Slides_LapTrinhC%23Trong5Tuan_NangCao.rar
Code:http://www.mediafire.com/file/z01oxplzogc5jzy/communityuni.com%23%23%23Sourecode_LaptrinhC%235tuan_NangCao.rar
CSDL:http://www.mediafire.com/file/xrzrpzns2vqz247/communityuni.com%23%23%23CSDL_LapTrinhC%235tuan_NangCao.rar
👉6) LINQ:
Slide:http://www.mediafire.com/file/dgurkd7woav65xw/communityuni.com%23%23%23Slides_ThanhThaoLinQ6Tuan.rar
Code:http://www.mediafire.com/file/yntczuh8xyc0kyx/communityuni.com%23%23%23SourceCode_CSDL_ThanhThaoLinQ6Tuan.rar
CSDL:http://www.mediafire.com/file/70pl6v0fd2tep25/communityuni.com%23%23%23CSDL_LINQ.rar
Bài tập bổ sung: http://www.mediafire.com/file/j06qjl6bm0mmi49/communityuni.com%23%23%23Exercises_LINQ.rar
👉7) Java cơ bản:
Slide:http://www.mediafire.com/file/qg6agcpeqd4588y/communityuni.com%23%23%23Slides_MonLapTrinhJavaTrong4Tuan.rar
Code:http://www.mediafire.com/file/6dgmdta865a7p8t/communityuni.com%23%23%23SourceCode_JavaCoban.rar
Bài tập bổ sung:http://www.mediafire.com/file/0b9d4bn0f6s1zn5/communityuni.com%23%23%23Final_java1_Exercise.docx
👉8) Java nâng cao:
Slide-Code:http://www.mediafire.com/file/rl6ddvri3ci2dz9/communityuni.com%23%23%23HocLieuJavaNangCao.rar
Bài tập bổ sung:http://www.mediafire.com/file/xvwa8z9n1r0j5tn/communityuni.com%23%23%23Final_Java2_Excercise.docx
👉9) Android cơ bản:
Slide:http://www.mediafire.com/file/8ah35kt5u3rs4ju/communityuni.com%23%23%23Slides_Android_CoBan.rar
Code:http://www.mediafire.com/file/1qle7ga7slawhbe/communityuni.com%23%23%23SourceCodeAndroid_coban.rar
👉10) Android nâng cao:
Slide:http://www.mediafire.com/file/bbbd0b627gu1rn1/communityuni.com%23%23%23Slides_Android_NangCao.rar
Code:http://www.mediafire.com/file/612jtc3za39cddd/communityuni.com%23%23%23SourceCodeAndroid_NangCao.rar
Bài tập bổ sung: http://www.mediafire.com/file/5l4tlj9on5ft8a4/communityuni.com%23%23%23Bai%20Tap%20Android%20Bo%20Sung.docx
👉11) Android 6 tuần:
Slide + code: http://www.mediafire.com/file/qedu5upmgbvmlzb/communityuni.com%23%23%23Android6tuan_code_slide.rar
👉12) Kotlin cơ bản:
Slide:http://www.mediafire.com/file/ibe8wewbvbslb2f/communityuni.com%23%23%23Slides_Kotlin_ToanTap.rar
Code: http://www.mediafire.com/file/tt7cuf487i363ge/communityuni.com%23%23%23SourceCode_Kotlin_ToanTap.rar
Giáo trình bổ sung: http://www.mediafire.com/file/qij4wa7xnba44m7/communityuni.com%23%23%23Tailieulaptrinh-Kotlin.docx
👉13) Python Cơ bản:
Slide:http://www.mediafire.com/file/qjiitst3iwr9nil/communityuni.com%23%23%23Slides_Python.rar/file
Code:http://www.mediafire.com/file/css8f6c82bx1o42/communityuni.com%23%23%23Practice.rar/file
👉14) Webservice cho di động:
Slide:http://www.mediafire.com/file/bxe1dwq0e7d79fm/communityuni.com%23%23%23Slides_Webservice.rar
Code + CSDL: http://www.mediafire.com/file/5bi56q31i4dacae/communityuni.com%23%23%23SourceCode_Webservice.rar
👉15) Webservice Web API RESTful:
Slide:http://www.mediafire.com/file/hzo66tnqsdi6r5n/communityuni.com%23%23%23Slides_Restful.rar
Code: http://www.mediafire.com/file/3adsj8013sksjyt/communityuni.com%23%23%23SourceCode_restful.rar
Các khóa học khi có sẽ được cập nhật trên http://communityuni.com/
https://duythanhcse.wordpress.com/
Thầy Thanh

 

Các Em like và follow page https://www.facebook.com/communityuni/ để hỏi các câu hỏi lập trình trong này cũng như theo dõi các thông báo.
Cài sẵn Ultraview, để bài nào không hiểu mà sửa lỗi mãi không được thì Remote Thầy hướng dẫn.

Thầy Thanh

C#-Xuất dữ liệu SQL Server ra Excel để báo cáo


Trong quá trình thực hiện phần mềm, vấn đề xuất báo cáo: ra file cứng (giấy, tức là từ phần mềm xuất thẳng dữ liệu ra giấy trong máy in luôn), file mềm (Excel, PDF, Word, HTML, Image…) thì Tui thấy nhu cầu xuất ra file Excel cũng khá phổ biến. Vì vậy Tui làm một số Tips hữu ích không có sắp xếp thứ tự như các bài học giảng giải về 1 công nghệ. Mỗi bài sẽ là 1 Tip hoàn chỉnh.

Cụ Thể trong bài này: Ta có dữ liệu từ SQL Server –> xuất ra Excel để báo cáo:

Hình trên Tui chụp 1 CSDL mẫu tên là “CSDL_MAU”, nó chỉ có 1 bảng duy nhất là “SanPham”, trong bảng này có 4 cột (MaSP, TenSp, DonGiaNhap, DonGiaXuat). Sau đó nhiệm vụ của ta là xuất dữ liệu từ bảng đó ra file Excel gọi lfa file Thống Kê Sản Phẩm. Lưu ý File Excel này khi xuất ta phải định dạng y xì boong vậy luôn nha, có Merge dòng/cột. có màu nền màu chữ, có kẻ khung.

Để làm được bài này thì trước tiên ta phải biết cách kết nối Cơ sở dữ liệu (ta có thể học 2 Khóa độc lập C# nâng cao hoặc LINQ). Trong tip này Tui dùng LINQ.

Đồng thời để kết xuất ra File Excel, ta có rất nhiều thư viện. Tuy nhiên trong Tip này Tui sử dụng thư viện có sẵn của Microsoft khi ta cài đặt công cụ Office, đó là thư viện: Microsoft.Office.CoreMicrosoft.Office.Interop.Excel

Ta tiến hành làm nha:

Bước 1: Phải có dữ liệu trước thì mới làm ra cơm phở.

Vụ CSDL các em tự xử nha, dùng version nào cũng được. Tui dùng SQL Server 2017. Để tiết kiệm thời gian cho các Em, Tui để Script của CSDL này, các Em chỉ cần Run Script 1 cái vèo cho lẹ:

Script bấm vào đây mà tải (CSDL_MAU)

Bước 2:

Tạo 1 project C# tên là “TestReportExcel” (dùng Winform hay WPF cũng được, không quan trọng). Ở đây Tui dùng Winform:

Chọn như trên đó, rùi bấm OK:

Bước 3: Kết nối CSDL bằng LINQ

Bấm chuột phải vào Project chọn Add/ New Item:

Chọn LINQ to SQL Classes, mục Name đặt CSDL_MAU.dbml (Lưu ý nếu không thấy LINQ tức là chưa biết cài Visual Studio nha)

Sau đó bấm nút Add:

Tập tin CSDL_MAU.dbml sẽ xuất hiện như trên. Ta bấm vào mục Server Explorer để kết nối CSDL:

Bấm vào nút Connect to Database:

Chọn Microsoft SQL Server rồi bấm OK:

Server Name (1): Chọn Tên Server của bạn lúc cài đặt SQL Server

Authentication (2): Chọn Windows hoặc SQL Mode. Chọn loại nào cũng được. miễn sao kết nối được

Database Name (3): Chọn Tên CSDL mà ta đã tạo CSDL_MAU

OK(4) : bấm OK để truy suất

Ta thấy CSDL_MAU xuất hiện trong Server Explorer. Bấm vào bảng SanPham Túm kéo nó vào phần mềm như hướng dẫn ở trên, ta có kết quả:

Như vậy là đã kết nối xong

Bước 4: Hiển thị dữ liệu lên Giao diện, cụ thể là GridView

Ta kéo thả 2 Button và 1 DataGridView như trên. Coding cho nút tải dữ liệu như sau:


private void btnTaiDuLieu_Click(object sender, EventArgs e)
{
CSDL_MAUDataContext context = new CSDL_MAUDataContext();
gvSanPham.DataSource = context.SanPhams.ToList();
}

Vô cùng đơn giản, chỉ cần 2 dòng lên trên thôi ta đã có dữ liệu hiển thị lên Giao diện.

Bước 5: Xuất dữ liệu ra File Excel để báo cáo (Theo đúng định dạng yêu cầu)

Ta tham chiếu thư viện như sau:

Bấm chuột phải vào References/ chọn add Reference…

Ta chọn COM, rồi tick vào 2 thư viện như trên: Microsoft Office 16.0 Object Library,  Microsoft Excel 16.0 Object Library (Dĩ nhiên do Tui dùng Office 2016 nên có cái này, còn bạn sài 2010, 2013… thì nó phải khác nha, thấy số 14, 15 thì chọn. tên na ná như vậy).

BẤM OK, thấy được thư viện tham chiếu như bên dưới là Ngon lành cành đào:

Bây giờ Coding Xuất Excel nha (Lưu ý là khi dữ liệu lớn thì bắt buộc phải viết dạng đa tiến trình, cụ thể là dùng BackgroundWorker để export Step by Step giúp chạy realtime mà không bị Treo phần mềm). Tuy nhiên để đơn giản thì Tui lược bỏ phần đa tiến trình này đi, bạn muốn dùng thì xem Khóa C# nâng cao có hướng dẫn phần Background Worker, hoặc ở một bài khác Tui sẽ ví dụ cách dùng Đa tiến trình để chạy xuất file báo cáo.

Quay lại yêu cầu của bài toán, là sau khi chạy thì kết quả xuất Báo cáo File Excel phải y xì như bên dưới:

Quan sát : Dòng đầu tiền (dòng có số thứ tự là 1. Cột chạy từ A->E : Và Trộn các cột này lại với nhau thành dòng tiêu đề “Thống kê sản phẩm“.

Bên dưới dòng 2 và 3 là Tên Trường (tên cột) để hiển thị thông tin chi tiết. Thì lưu ý  Cột A, B, C là trộn 2 dòng. Còn cột D, E thì dòng bên trên là trộn 2 cột để ra chữ “Giá sản phẩm”, và ngay bên dưới có 2 cột là “Giá bán” và “Giá Xuất”.

==> Đây chính là chỗ khó nhất để xuất file báo cáo này.

Còn tất cả dữ liệu bên dưới ta dùng vòng lặp xuất ra là xong.

sau khi xuất dữ liệu xong thì phải Kẻ bảng cũng như tô màu nền màu chữ nếu có.

Chi tiết Coding cho phần xuất Excel như sau:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
using Microsoft.Office.Interop.Excel;

namespace TestReportExcel
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void btnTaiDuLieu_Click(object sender, EventArgs e)
{
CSDL_MAUDataContext context = new CSDL_MAUDataContext();
gvSanPham.DataSource = context.SanPhams.ToList();
}

private void btnXuatExcel_Click(object sender, EventArgs e)
{
try
{
string saveExcelFile = @"f:\excel_report.xlsx";

Excel.Application xlApp = new Excel.Application();

if (xlApp == null)
{
MessageBox.Show("Lỗi không thể sử dụng được thư viện EXCEL");
return;
}
xlApp.Visible = false;

object misValue = System.Reflection.Missing.Value;

Workbook wb = xlApp.Workbooks.Add(misValue);

Worksheet ws = (Worksheet)wb.Worksheets[1];

if (ws == null)
{
MessageBox.Show("Không thể tạo được WorkSheet");
return;
}
int row = 1;
string fontName = "Times New Roman";
int fontSizeTieuDe = 18;
int fontSizeTenTruong = 14;
int fontSizeNoiDung = 12;
//Xuất dòng Tiêu đề của File báo cáo: Lưu ý
Range row1_TieuDe_ThongKeSanPham = ws.get_Range("A1", "E1");
row1_TieuDe_ThongKeSanPham.Merge();
row1_TieuDe_ThongKeSanPham.Font.Size = fontSizeTieuDe;
row1_TieuDe_ThongKeSanPham.Font.Name = fontName;
row1_TieuDe_ThongKeSanPham.Cells.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
row1_TieuDe_ThongKeSanPham.Value2 = "Thống kê sản phẩm";

//Tạo Ô Số Thứ Tự (STT)
Range row23_STT = ws.get_Range("A2", "A3");//Cột A dòng 2 và dòng 3
row23_STT.Merge();
row23_STT.Font.Size = fontSizeTenTruong;
row23_STT.Font.Name = fontName;
row23_STT.Cells.HorizontalAlignment = XlHAlign.xlHAlignCenter;
row23_STT.Value2 = "STT";

//Tạo Ô Mã Sản phẩm :
Range row23_MaSP = ws.get_Range("B2", "B3");//Cột B dòng 2 và dòng 3
row23_MaSP.Merge();
row23_MaSP.Font.Size = fontSizeTenTruong;
row23_MaSP.Font.Name = fontName;
row23_MaSP.Cells.HorizontalAlignment = XlHAlign.xlHAlignCenter;
row23_MaSP.Value2 = "Mã Sản Phẩm";
row23_MaSP.ColumnWidth = 20;

//Tạo Ô Tên Sản phẩm :
Range row23_TenSP = ws.get_Range("C2", "C3");//Cột C dòng 2 và dòng 3
row23_TenSP.Merge();
row23_TenSP.Font.Size = fontSizeTenTruong;
row23_TenSP.Font.Name = fontName;
row23_TenSP.Cells.HorizontalAlignment = XlHAlign.xlHAlignCenter;
row23_TenSP.ColumnWidth = 20;
row23_TenSP.Value2 = "Tên Sản Phẩm";

//Tạo Ô Giá Sản phẩm :
Range row2_GiaSP = ws.get_Range("D2", "E2");//Cột D->E của dòng 2
row2_GiaSP.Merge();
row2_GiaSP.Font.Size = fontSizeTenTruong;
row2_GiaSP.Font.Name = fontName;
row2_GiaSP.Cells.HorizontalAlignment = XlHAlign.xlHAlignCenter;
row2_GiaSP.Value2 = "Giá Sản Phẩm";

//Tạo Ô Giá Nhập:
Range row3_GiaNhap = ws.get_Range("D3", "D3");//Ô D3
row3_GiaNhap.Font.Size = fontSizeTenTruong;
row3_GiaNhap.Font.Name = fontName;
row3_GiaNhap.Cells.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
row3_GiaNhap.Value2 = "Giá Nhập";
row3_GiaNhap.ColumnWidth = 20;

//Tạo Ô Giá Xuất:
Range row3_GiaXuat = ws.get_Range("E3", "E3");//Ô E3
row3_GiaXuat.Font.Size = fontSizeTenTruong;
row3_GiaXuat.Font.Name = fontName;
row3_GiaXuat.Cells.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
row3_GiaXuat.Value2 = "Giá Xuất";
row3_GiaXuat.ColumnWidth = 20;
//Tô nền vàng các cột tiêu đề:
Range row23_CotTieuDe = ws.get_Range("A2", "E3");
//nền vàng
row23_CotTieuDe.Interior.Color = ColorTranslator.ToOle(System.Drawing.Color.Yellow);
//in đậm
row23_CotTieuDe.Font.Bold = true;
//chữ đen
row23_CotTieuDe.Font.Color = ColorTranslator.ToOle(System.Drawing.Color.Black);

int stt = 0;
row = 3;//dữ liệu xuất bắt đầu từ dòng số 4 trong file Excel (khai báo 3 để vào vòng lặp nó ++ thành 4)
CSDL_MAUDataContext context = new CSDL_MAUDataContext();
foreach (SanPham sp in context.SanPhams)
{
stt++;
row++;
dynamic []arr = { stt,sp.MaSP,sp.TenSP,sp.DonGiaNhap,sp.DonGiaXuat};
Range rowData = ws.get_Range("A"+row, "E"+row);//Lấy dòng thứ row ra để đổ dữ liệu
rowData.Font.Size = fontSizeNoiDung;
rowData.Font.Name = fontName;
rowData.Value2 = arr;
}
//Kẻ khung toàn bộ
BorderAround(ws.get_Range("A2", "E" + row));

//Lưu file excel xuống Ổ cứng
wb.SaveAs(saveExcelFile);

//đóng file để hoàn tất quá trình lưu trữ
wb.Close(true, misValue, misValue);
//thoát và thu hồi bộ nhớ cho COM
xlApp.Quit();
releaseObject(ws);
releaseObject(wb);
releaseObject(xlApp);

//Mở File excel sau khi Xuất thành công
System.Diagnostics.Process.Start(saveExcelFile);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
//Hàm kẻ khung cho Excel
private void BorderAround(Range range)
{
Borders borders = range.Borders;
borders[XlBordersIndex.xlEdgeLeft].LineStyle = XlLineStyle.xlContinuous;
borders[XlBordersIndex.xlEdgeTop].LineStyle = XlLineStyle.xlContinuous;
borders[XlBordersIndex.xlEdgeBottom].LineStyle = XlLineStyle.xlContinuous;
borders[XlBordersIndex.xlEdgeRight].LineStyle = XlLineStyle.xlContinuous;
borders.Color = Color.Black;
borders[XlBordersIndex.xlInsideVertical].LineStyle = XlLineStyle.xlContinuous;
borders[XlBordersIndex.xlInsideHorizontal].LineStyle = XlLineStyle.xlContinuous;
borders[XlBordersIndex.xlDiagonalUp].LineStyle = XlLineStyle.xlLineStyleNone;
borders[XlBordersIndex.xlDiagonalDown].LineStyle = XlLineStyle.xlLineStyleNone;
}
//Hàm thu hồi bộ nhớ cho COM Excel
private static void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
obj = null;
}
finally
{ GC.Collect(); }
}
}
}

Chạy lên ta sẽ có kết quả như mong muốn.

Đây là source code đầy đủ: Tải code

Ngoài ra Tui có tạo 1 Facebook Fanpage để hướng dẫn cũng như trả lời các thắc mắc của Sinh viên về các kiến thức lập trình mà Tui đang đảm nhiệm, các bạn có thể Like + Follow để dễ dàng theo dõi các Tip cũng như có thể tham gia thảo luận: https://www.facebook.com/communityuni

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

Bài 35-Truy cập NodeJS RESTful Web Services với thư viện Volley và Retrofit (FINAL)


Đây là bài học cuối cùng, kết thúc chuỗi series bài học về NodeJS- MongoDB. Toàn bộ bài học được tổng hợp trong trang này.

Có rất nhiều kỹ thuật để truy cập các WEB API, tùy vào nhu cầu của lập trình viên mà ta lựa chọn các thư viện khác nhau. Ở đây dân chúng hay bàn luận về Volley Retrofit cũng như so sánh phân vân nên chọn cái nào? mấy câu hỏi này bạn tự Google search nha. Bạn chỉ cần biết là ta có thêm 2 thư viện Volley Retrofit để truy cập WEB API là đủ rồi, còn cụ thể như thế nào thì cứ hỏi bác Google là OK á.

Trong bài này Tui chỉ giới thiệu sơ Volley để lấy danh sách Product thôi nha (chi tiết bạn xem trên Blog của Alif’s Blog để áp dụng cho các Web API còn lại, nó vô cùng đơn giản nhưng Tui busy quá không quá trình bày tất tần tật được), Retrofit bạn tự search.

Bước 1:

Tạo một Android Kotlin Project tên VolleyToNodeJS.

thêm lệnh api ‘com.android.volley:volley:1.1.0’ trong build.gradle của app level

Sau khi gõ lệnh xong thì nhớ bấm mục số 2 (Sync now)==>Lúc này thư viện volley sẽ được đưa vào ứng dụng và ta sử dụng nó một cách dễ dàng, đơn giản nhất.

Bước 2:

Thêm một ListView cho màn hình chính MainActivity như sau:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">

<ListView
android:id="@+id/lvProduct"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

Bước 3:

Coding sử dụng Volley để triệu gọi Web API lấy danh sách Product đơn giản như sau:


fun TaiDanhSachProduct_Volley()
{
var url="http://192.168.1.137/nodejsapi/products"
val queue = Volley.newRequestQueue(this)

val getRequest = JsonArrayRequest(Request.Method.GET, url, null,
object : Response.Listener<JSONArray> {
override fun onResponse(response: JSONArray) {
//response là 1 JSonArray chưa danh sách Product->ta phân tích để lấy dữ liệu trong này ra là ok
}
},
object : Response.ErrorListener {
override fun onErrorResponse(error: VolleyError) {
Log.d("Error.Response", error.toString())
}
}
)
queue.add(getRequest)
}

Tổng thể ta có coding cuối cùng cho MainActivity như sau:


package com.communityuni.volleytonodejs

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.ArrayAdapter
import android.widget.ListView
import com.android.volley.Request
import com.android.volley.toolbox.Volley
import com.android.volley.RequestQueue
import com.android.volley.Response
import com.android.volley.VolleyError
import com.android.volley.toolbox.JsonArrayRequest
import org.json.JSONObject
import com.android.volley.toolbox.JsonObjectRequest
import org.json.JSONArray

class MainActivity : AppCompatActivity() {

lateinit var lvProduct:ListView
lateinit var adapter: ArrayAdapter<String>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
addControls()
}
private fun addControls() {
lvProduct=findViewById(R.id.lvProduct)
adapter= ArrayAdapter(this,android.R.layout.simple_list_item_1)
lvProduct.adapter=adapter
}

override fun onResume() {
super.onResume()
TaiDanhSachProduct_Volley()
}
fun TaiDanhSachProduct_Volley()
{
var url="http://192.168.1.137/nodejsapi/products"
val queue = Volley.newRequestQueue(this)

val getRequest = JsonArrayRequest(Request.Method.GET, url, null,
object : Response.Listener<JSONArray> {
override fun onResponse(response: JSONArray) {
//response là 1 JSonArray chưa danh sách Product
adapter.clear()
for (i in 0 until response.length())
{
var jsonObject=response.getJSONObject(i)
var line=jsonObject.getString("Ma")+
"\n"+jsonObject.getString("Ten")+
"\n"+jsonObject.getDouble("DonGia")
adapter.add(line)
}
}
},
object : Response.ErrorListener {
override fun onErrorResponse(error: VolleyError) {
Log.d("Error.Response", error.toString())
}
}
)
queue.add(getRequest)
}
}

Chạy lên ta có kết quả:

Còn các API khác (POST, PUT, DELETE, GET chi tiết Product) các bạn cố gắng tự mày mò nha.Vì Volley là một trong những thư viện vô cùng đơn giản, dễ sử dụng và rất hiệu quả, nếu không làm được thì có thể add Facebook http://facebook.com/duythanhcse , Tui sẽ support khi rảnh

Coding của bài này tải ở đây

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

Bài 34-Truy cập NodeJS RESTful Web Services bằng Android Kotlin-HTTPPOST


Chúc mừng các bạn đã lết được tới Web API cuối cùng, đó là triệu gọi HTTPPOST để thêm mới Product. Tiếp tục mở lại project AndroidKotlinToNodeJS bài 33.

Trong bài này các bạn bổ sung 1 Menu “Thêm Product”, nhấn vào menu này sẽ hiển thị ra màn hình Thêm mới để cho phép người dùng nhập mới Product, bấm lưu để thêm Product vào MongoDB bằng cách triệu gọi Web API http://192.168.1.137/nodejsapi/addProduct (dĩ nhiên máy bạn cấu hình sao thì lấy theo vậy, copy y xì Tui là đạp xích lô đó nha).

Chi tiết các bước coding như sau:

Bước 1: Tạo 1 Option Menu cho ứng dụng, Option menu này chứa 1 MenuItem là Thêm Product

Bấm chuộc phải vào thư mục res/ chọn New/ chọn Directory:

Đặt tên là menu rồi bấm OK

Khi thư mục menu được tạo ra, ta bấm chuột phải vào nó/ chọn New/ chọn Menu Resource file:

Đặt tên main_menu rồi bấm OK

Ta kéo một Menu Item vào trong menu, đặt id là mnuThemProduct, nhãn là “Thêm Product”

cấu trúc XML của main_menu.xml như sau:


<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android">

<item android:id="@+id/mnuThemProduct" android:title="Thêm Product" />
</menu>


Nạp Menu này vào cho màn hình chính (MainActivity) bằng cách override 2 hàm sau:


override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.main_menu,menu)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
if(item!!.itemId==R.id.mnuThemProduct)
{
var intent=Intent(this,ThemProductActivity::class.java)
startActivity(intent)
}
return super.onOptionsItemSelected(item)
}

Chú ý ở trên Tui có xử lý sự kiện khi người dùng nhấn vào menu Thêm Product thì mở màn hình ThemProductActivity (xem bước 2)
Bước 2: Tạo một màn hình mới tên là ThemProductActivity

Tương tự như tạo màn hình ChiTietActivity, ta cũng Bấm chuột phải vào Package chứa MainActivity rồi chọn New/ chọn Activity/ chọn Empty Activity

đặt tên ThemProductActivity và cấu hình như trên rồi bấm Finish

tiến hành thiết kế giao diện cho màn hình Thêm Product (chỉnh layout cho activity_them_product.xml), màn hình này phải cung cấp ô nhập: Mã, Tên, Đơn giá:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".ThemProductActivity">
<TextView android:id="@+id/textView2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Mã Product:" android:textSize="20sp" />

<EditText android:id="@+id/edtMa" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:inputType="textPersonName" />

<TextView android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Tên Product:" android:textSize="20sp" />

<EditText android:id="@+id/edtTen" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:inputType="textPersonName" />
<TextView android:id="@+id/textView3" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Đơn giá:" android:textSize="20sp" />

<EditText android:id="@+id/edtDonGia" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:inputType="numberDecimal" />

<Button android:onClick="xuLyThemMoiProduct" android:id="@+id/btnLuu" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Đổi thông tin" android:textSize="20sp" />

</LinearLayout>

Giao diện bên GUI sẽ như sau:

Bước 3: Coding cho ThemProductActivity

Coding khởi tạo các biến control để truy suất tới các ô nhập liệu như Mã, Tên, đơn giá:


package com.communityuni.androidkotlintonodejs

import android.os.AsyncTask
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.EditText
import android.widget.Toast
import com.communityuni.model.Product
import java.io.BufferedWriter
import java.io.OutputStreamWriter
import java.net.HttpURLConnection
import java.net.URL

class ThemProductActivity : AppCompatActivity() {
lateinit var edtMa: EditText
lateinit var edtTen: EditText
lateinit var edtDonGia: EditText
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_them_product)
addControls()
}
private fun addControls() {
edtMa=findViewById(R.id.edtMa)
edtTen=findViewById(R.id.edtTen)
edtDonGia=findViewById(R.id.edtDonGia)
}
fun xuLyThemMoiProduct(v:View)
{

}
private fun thongBao(result: Boolean?) {
if(result==true)
{
Toast.makeText(applicationContext,"Thêm mới Product thành công", Toast.LENGTH_LONG).show()
finish()
}
else
{
Toast.makeText(applicationContext,"Thêm mới Product thất bại", Toast.LENGTH_LONG).show()
}
}
}

Tiếp tục bổ sung thêm đa tiến trình HTTPPOSTProductTask trong màn hình ThemProductActivity để triệu gọi API thêm mới Product (http://192.168.1.137/nodejsapi/addProduct)


inner class HTTPPOSTProductTask : AsyncTask<Product, Void, Boolean>()
{
override fun doInBackground(vararg p0: Product?): Boolean {
var p:Product?=p0[0]
try
{
var api="http://192.168.1.137/nodejsapi/addProduct"
var url=URL(api)
var urlConnection= url.openConnection() as HttpURLConnection
urlConnection.requestMethod="POST"
urlConnection.doOutput=true
urlConnection.doInput=true
urlConnection.addRequestProperty("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
val outputStream = urlConnection.getOutputStream()
val bufferedWriter = BufferedWriter(OutputStreamWriter(outputStream, "UTF-8"))
val put_data = p!!.parameters()
bufferedWriter.write(put_data)
bufferedWriter.flush()
bufferedWriter.close()
outputStream.close()
var result =urlConnection.inputStream.bufferedReader().readText()
urlConnection.disconnect()
return result.equals("true")
}
catch (ex:Exception)
{
Log.e("LOI",ex.toString())
}
return false
}
override fun onPostExecute(result: Boolean?) {
super.onPostExecute(result)
thongBao(result)
}
}

Bổ sung thêm coding cho sự kiện xuLyThemMoiProduct:


fun xuLyThemMoiProduct(v:View)
{
var Ma=edtMa.text.toString()
var Ten=edtTen.text.toString()
var DonGia=edtDonGia.text.toString().toDouble()
var p=Product(Ma,Ten,DonGia)
HTTPPOSTProductTask().execute(p)
}

Cuối cùng cho có Coding toàn bộ của màn hình ThemProductActivity như sau:


package com.communityuni.androidkotlintonodejs

import android.os.AsyncTask
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.EditText
import android.widget.Toast
import com.communityuni.model.Product
import java.io.BufferedWriter
import java.io.OutputStreamWriter
import java.net.HttpURLConnection
import java.net.URL

class ThemProductActivity : AppCompatActivity() {
lateinit var edtMa: EditText
lateinit var edtTen: EditText
lateinit var edtDonGia: EditText
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_them_product)
addControls()
}
private fun addControls() {
edtMa=findViewById(R.id.edtMa)
edtTen=findViewById(R.id.edtTen)
edtDonGia=findViewById(R.id.edtDonGia)
}
fun xuLyThemMoiProduct(v:View)
{
var Ma=edtMa.text.toString()
var Ten=edtTen.text.toString()
var DonGia=edtDonGia.text.toString().toDouble()
var p=Product(Ma,Ten,DonGia)
HTTPPOSTProductTask().execute(p)
}
private fun thongBao(result: Boolean?) {
if(result==true)
{
Toast.makeText(applicationContext,"Thêm mới Product thành công", Toast.LENGTH_LONG).show()
finish()
}
else
{
Toast.makeText(applicationContext,"Thêm mới Product thất bại", Toast.LENGTH_LONG).show()
}
}
inner class HTTPPOSTProductTask : AsyncTask<Product, Void, Boolean>()
{
override fun doInBackground(vararg p0: Product?): Boolean {
var p:Product?=p0[0]
try
{
var api="http://192.168.1.137/nodejsapi/addProduct"
var url=URL(api)
var urlConnection= url.openConnection() as HttpURLConnection
urlConnection.requestMethod="POST"
urlConnection.doOutput=true
urlConnection.doInput=true
urlConnection.addRequestProperty("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
val outputStream = urlConnection.getOutputStream()
val bufferedWriter = BufferedWriter(OutputStreamWriter(outputStream, "UTF-8"))
val put_data = p!!.parameters()
bufferedWriter.write(put_data)
bufferedWriter.flush()
bufferedWriter.close()
outputStream.close()
var result =urlConnection.inputStream.bufferedReader().readText()
urlConnection.disconnect()
return result.equals("true")
}
catch (ex:Exception)
{
Log.e("LOI",ex.toString())
}
return false
}
override fun onPostExecute(result: Boolean?) {
super.onPostExecute(result)
thongBao(result)
}
}
}

Chạy phần mềm lên ta sẽ có được kết quả như mong muốn : Mở được màn hình thêm mới Product, triệu gọi API thêm mới thành công. Như vậy ta đã hoàn thành xong bài triệu gọi Web API HTTPPOST để thêm mới 1 Product.

Source code Triệu gọi Web API thêm mới Product tải ở đây.

Bài sau Tui sẽ giới thiệu cho các Thím một số thư viện Third Party để truy suất RESTful Webservice, như Volley, Retrofit… các Thím tranh thủ theo dõi để đọc nhé

Các khóa học online khác, bạn có thể tham khảo tại đây: http://communityuni.com/

Innovate Trading System (Kênh đầu tư lợi nhuận rất cao), các bạn nào quan tâm thì vào đây đầu tư nhé:

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

Bài 33-Truy cập NodeJS RESTful Web Services bằng Android Kotlin-HTTPDELETE


Như vậy các bạn đã triệu gọi thành công được 3 RESTful Web API trong ví dụ (lấy danh sách Product, xem chi tiết Product và chỉnh sửa thông tin Product). Bài này ta sẽ coding để Xóa Product khỏi MongoDB thông qua việc triệu gọi API HTTPDELETE.

Cụ thể, trong màn hình đầu tiên hiển thị danh sách Product, ta nhấn vào biểu tượng sọt rác, Chương trình sẽ hiển thị cửa sổ hỏi có muốn Xóa hay không (AlertDialog). Nếu chọn Không thì trở về màn hình ban đâu, nếu chọn Có Chứ thì sẽ Xóa Product đó đồng thời gọi lại API hiển thị Danh sách Product để tại lại và hiển thị lên Listview với danh sách mới sau khi xóa.

Vậy ta coding như sau:

Bước 1:

Trong lớp ProductAdapter, bổ sung thêm inner class để xử lý đa tiến trình tên là HTTPDELETEProductTask triệu gọi API xóa Product, coding:


inner class HTTPDELETEProductTask : AsyncTask<Product, Void, Boolean>()
{
override fun doInBackground(vararg p0: Product?): Boolean {
var p:Product?=p0[0]
try
{
var api="http://192.168.1.137/nodejsapi/deleteProduct"
var url= URL(api)
var urlConnection= url.openConnection() as HttpURLConnection
urlConnection.requestMethod="DELETE"
urlConnection.doOutput=true
urlConnection.doInput=true
urlConnection.addRequestProperty("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
val outputStream = urlConnection.getOutputStream()
val bufferedWriter = BufferedWriter(OutputStreamWriter(outputStream, "UTF-8"))
val put_data = "Ma="+p!!.Ma
bufferedWriter.write(put_data)
bufferedWriter.flush()
bufferedWriter.close()
outputStream.close()
var result =urlConnection.inputStream.bufferedReader().readText()
urlConnection.disconnect()
return result.equals("true")
}
catch (ex:Exception)
{
Log.e("LOI",ex.toString())
}
return false
}
override fun onPostExecute(result: Boolean?) {
super.onPostExecute(result)
if(result==true)
{
(context as MainActivity).HTTPGetListProductTask().execute()
}
}
}

Đầu vào là 1 Product (Product này được lấy ra khi ta nhấn vào nút Xóa)

Vì muốn Xóa thì chỉ cần gửi Ma lên mà thôi, nên trong coding Tui viết luôn: val put_data = “Ma=”+p!!.Ma

Bước 2:

Trong hàm getView của ProductAdapter, ta bổ sung khai báo biến và gán sự kiện cho nút Xóa như sau:


var imgDelete=custom.findViewById<ImageView>(R.id.imgDelete)
imgDelete.setOnClickListener{xuLyDelete(p)}

hàm xuLyDelete được viết như sau:


private fun xuLyDelete(p: Product?) {
var builder=AlertDialog.Builder(context)
builder.setTitle("Xác nhận xóa")
builder.setMessage("Thím có chắc chắn muốn xóa Product ["+p!!.Ten+"] không?")
builder.setNegativeButton("Không",
DialogInterface.OnClickListener
{ dialogInterface, i -> dialogInterface.dismiss()})
builder.setPositiveButton("Có chứ", DialogInterface.OnClickListener
{ dialogInterface, i ->
HTTPDELETEProductTask().execute(p)
})
builder.create().show()
}

Vậy cuối cùng ta có coding đầy đủ của lớp ProductAdapter như dưới đây:

package com.communityuni.adapter

import android.app.Activity
import android.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.os.AsyncTask
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
import com.communityuni.androidkotlintonodejs.ChiTietActivity
import com.communityuni.androidkotlintonodejs.MainActivity
import com.communityuni.androidkotlintonodejs.R
import com.communityuni.model.Product
import java.io.BufferedWriter
import java.io.OutputStreamWriter
import java.net.HttpURLConnection
import java.net.URL

class ProductAdapter(internal var context: Activity, internal var resource: Int) : ArrayAdapter<Product>(context, resource) {

override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
var custom = context.layoutInflater.inflate(resource, null)
var txtMa = custom.findViewById<TextView>(R.id.txtMa)
var txtTen = custom.findViewById<TextView>(R.id.txtTen)
var txtDonGia = custom.findViewById<TextView>(R.id.txtDonGia)
var p = getItem(position)
txtMa.text = p!!.Ma
txtTen.text = p.Ten
txtDonGia.text = p.DonGia.toString()
var img=custom.findViewById<ImageView>(R.id.imgEdit)
img.setOnClickListener { xuLyEdit(p) }
var imgDelete=custom.findViewById<ImageView>(R.id.imgDelete)
imgDelete.setOnClickListener{xuLyDelete(p)}
return custom
}
private fun xuLyEdit(p: Product?) {
var i=Intent(context,ChiTietActivity::class.java)
i.putExtra("Ma",p!!.Ma)
context.startActivity(i)
}
private fun xuLyDelete(p: Product?) {
var builder=AlertDialog.Builder(context)
builder.setTitle("Xác nhận xóa")
builder.setMessage("Thím có chắc chắn muốn xóa Product ["+p!!.Ten+"] không?")
builder.setNegativeButton("Không",
DialogInterface.OnClickListener
{ dialogInterface, i -> dialogInterface.dismiss()})
builder.setPositiveButton("Có chứ", DialogInterface.OnClickListener
{ dialogInterface, i ->
HTTPDELETEProductTask().execute(p)
})
builder.create().show()
}
inner class HTTPDELETEProductTask : AsyncTask<Product, Void, Boolean>()
{
override fun doInBackground(vararg p0: Product?): Boolean {
var p:Product?=p0[0]
try
{
var api="http://192.168.1.137/nodejsapi/deleteProduct"
var url= URL(api)
var urlConnection= url.openConnection() as HttpURLConnection
urlConnection.requestMethod="DELETE"
urlConnection.doOutput=true
urlConnection.doInput=true
urlConnection.addRequestProperty("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
val outputStream = urlConnection.getOutputStream()
val bufferedWriter = BufferedWriter(OutputStreamWriter(outputStream, "UTF-8"))
val put_data = "Ma="+p!!.Ma
bufferedWriter.write(put_data)
bufferedWriter.flush()
bufferedWriter.close()
outputStream.close()
var result =urlConnection.inputStream.bufferedReader().readText()
urlConnection.disconnect()
return result.equals("true")
}
catch (ex:Exception)
{
Log.e("LOI",ex.toString())
}
return false
}
override fun onPostExecute(result: Boolean?) {
super.onPostExecute(result)
if(result==true)
{
(context as MainActivity).HTTPGetListProductTask().execute()
}
}
}
}

Chạy phần mềm lên và thao tác Xóa sẽ thành công như Tui hướng dẫn nha.

Như vậy ta đã hoàn thành xong bài triệu gọi Web API HttpDelete để xóa 1 Product.

Source code Triệu gọi Web API xóa Product tải ở đây.

Bài sau Tui sẽ hướng dẫn các Thím cách dùng Android Kotlin để  truy cập API RESTful Thêm mới Product như thế nào. Các bạn chú ý theo dõi nhé (vẫn dùng lại Project này)

Các khóa học online khác, bạn có thể tham khảo tại đây: http://communityuni.com/

Innovate Trading System (Kênh đầu tư lợi nhuận rất cao), các bạn nào quan tâm thì vào đây đầu tư nhé:

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

Bài 32-Truy cập NodeJS RESTful Web Services bằng Android Kotlin-HTTPPUT


Tiếp tục mở lại Project AndroidKotlinToNodeJS trong bài 31. Bài học này Tui sẽ hướng dẫn các bạn cách triệu gọi API với HTTPPUT Method (để chỉnh sửa dữ liệu của một Product).

Lưu ý là IISNode của toàn bộ API này được deploy trong bài 28. Và API Edit Product được trình bày chi tiết trong bài 26. Nếu nếu các Thím có quên thì coi lại những bài này (tốt nhất là đừng quên, cứ làm theo tuần tự từ bài 1->bài cuối cùng thì chắc chắn không bao giờ quên. Đừng tỏ vẻ nguy hiểm nhảy cóc sẽ mất thời gian, vì các bài học Tui đã chủ ý thiết kế từ cơ bản đến nâng cao mà bài sau kế thừa bài trước).

Nhắc lại ở bài 31 ta đã triệu gọi API HTTPGET để lấy chi tiết thông tin của một Product hiển thị lên 1 màn hình mới rồi, giờ cũng trong màn hình hiển thị chi tiết đó ta chỉnh sửa thông tin của TÊN + ĐƠN GIÁ rồi bấm lưu thay đổi–>triệu gọi API HTTPPUT để thay đổi.

Xem giao diện minh họa dưới đây:

Bước 1: Trong màn hình chính hiển thị danh sách Product, nhấn vào nút Edit

Bước 2: Thông tin chi tiết được hiển thị lên màn hình chi tiết

Bước 3: Trong màn hình chi tiết ta sửa tên và đơn giá rồi bấm nút “Đổi thông tin”

Bước 4: Chương trình tải lại và ta thấy kết quả thay đổi.

Chi tiết các bước lập trình để triệu gọi API HTTPUT chỉnh sửa thông tin Product như sau (trong bài học Tui hướng dẫn thì API này là: http://192.168.1.137/nodejsapi/editProduct (của bạn cấu hình thế nào thì lấy thế đó nha, copy y xì như của Tui là đi đạp xích lô đó nha).

Xem lại hình thử nghiệm trong bài 28:

Ở trên ta thấy cần phải truyền 3 Parameter (Ma, Ten, DonGia) từ Android lên cho NodeJS xử lý. Vậy truyền như thế nào? Lưu ý có nhiều thư viện như volley, retrofit… để hỗ trợ tương tác dịch vụ Web. Tuy nhiên các thư viện này Tui chưa sài, nếu có Tui sẽ hướng dẫn thêm ở những bài khác. Bây giờ hãy làm theo chuẩn HttpURLConnection trước.

OK, action nha.

Trong Project AndroidKotlinToNodeJS  các bạn làm theo bước sau:

Bước 1: Chỉnh sửa lớp Product.kt để tạo Parameter gửi lên Server NodeJS


package com.communityuni.model

import java.net.URLEncoder

class Product {
lateinit var _id:Any
lateinit var Ma:String
lateinit var Ten:String
var DonGia:Double=0.0
constructor(ma:String,ten:String,donGia:Double)
{
Ma=ma
Ten=ten
DonGia=donGia
}
override fun toString(): String {
return Ma+"\n"+Ten+"\n"+DonGia+"VNĐ"
}
public fun parameters(): String
{
return "Ma="+Ma+"&Ten="+URLEncoder.encode(Ten,"UTF-8")+"&DonGia="+DonGia
}
}

bạn thấy hàm parameters() ở trên không? Tui coding cho nó trả về 1 chuỗi có cú pháp, đây chính là các nội dung ta gửi lên Server NodeJS để xử lý. Những chuỗi nào liên quan Unicode thì ta phải dùng URLEncoder như trên để mã hóa nó nha, nếu quên sẽ bị failed. Các đối số cách nhau bởi dấu & nha, bạn thay dấu & bằng dấu khác cũng được nhưng mà sai.

Bước 2:

Xử lý coding nhấn vào nút Thay đổi thông tin.

Trong lớp ChiTietActivity.kt bổ sung thêm 1 inner class HTTPPUTProductTask nhiệm vụ của nó là triệu gọi API HTTPUT (http://192.168.1.137/nodejsapi/editProduct) và gửi dữ liệu lên NodeJS Server(dữ liệu được coding trong hàm parameter() của lớp Product.kt. (Bổ sung thêm coding tức là phải giữ nguyên coding cũ, coding cũ Tui không có đưa vào đây nha)


inner class HTTPPUTProductTask : AsyncTask<Product, Void, Boolean>()
{
override fun doInBackground(vararg p0: Product?): Boolean {
var p:Product?=p0[0]
try
{
var api="http://192.168.1.137/nodejsapi/editProduct"
var url=URL(api)
var urlConnection= url.openConnection() as HttpURLConnection
urlConnection.requestMethod="PUT"
urlConnection.doOutput=true
urlConnection.doInput=true
urlConnection.addRequestProperty("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
val outputStream = urlConnection.getOutputStream()
val bufferedWriter = BufferedWriter(OutputStreamWriter(outputStream, "UTF-8"))
val put_data = p!!.parameters()
bufferedWriter.write(put_data)
bufferedWriter.flush()
bufferedWriter.close()
outputStream.close()
var result =urlConnection.inputStream.bufferedReader().readText()
urlConnection.disconnect()
return result.equals("true")
}
catch (ex:Exception)
{
Log.e("LOI",ex.toString())
}
return false
}
override fun onPostExecute(result: Boolean?) {
super.onPostExecute(result)
thongBao(result)
}
}

Bước 3: Viết sự kiện cho nút Thay đổi thông tin để gọi đa tiến trình ở bước 2 (Sự kiện các bạn dùng onclick XML nha, nên Tui không chụp lại XML layout nữa vì nó chỉ có 1 thay  đổi nhỏ):


fun xuLyCapNhat(v:View)
{
var Ma=edtMa.text.toString()
var Ten=edtTen.text.toString()
var DonGia=edtDonGia.text.toString().toDouble()
var p=Product(Ma,Ten,DonGia)
HTTPPUTProductTask().execute(p)
}
private fun thongBao(result: Boolean?) {
if(result==true)
{
Toast.makeText(applicationContext,"Cập nhật thành công",Toast.LENGTH_LONG).show()
finish()
}
else
{
Toast.makeText(applicationContext,"Cập nhật thất bại",Toast.LENGTH_LONG).show()
}
}

OK, vậy là ngon lành cành đạo như cơm mẹ nấu rồi đó, chạy lên ta sẽ có kết quả như mong muốn

Như vậy ta đã hoàn thành xong bài triệu gọi Web API HttpPUT để chỉnh sửa thông tin của 1 Product.

Source code Triệu gọi Web API thay đổi thông tin Product tải ở đây.

Bài sau Tui sẽ hướng dẫn các Thím cách dùng Android Kotlin để  truy cập API RESTful Xóa Product như thế nào. Các bạn chú ý theo dõi nhé (vẫn dùng lại Project này)

Các khóa học online khác, bạn có thể tham khảo tại đây: http://communityuni.com/

Innovate Trading System (Kênh đầu tư lợi nhuận rất cao), các bạn nào quan tâm thì vào đây đầu tư nhé:

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

Bài 31-Truy cập NodeJS RESTful Web Services bằng Android Kotlin-HTTPGET


Như vậy các Thím đã biết cách truy cập API lấy toàn bộ Product bằng HTTPGET trong Android Kotlin. Bài này ta tiếp tục truy cập API dùng method HTTP GET để lấy thông tin chi tiết của một Product.

Tiếp tục mở lại Project AndroidKotlinToNodeJS trong bài 30. Trong bài này ta đã có Custom layout có nút Edit. Bây giờ ta xử lý nhấn vào nút Edit đó thì mở màn hình thông tin chi tiết lên (lấy Mã của Product đang chọn rồi truy cập API lấy thông tin chi tiết Product, ví dụ lấy Product có mã P999: http://192.168.1.137/nodejsapi/products/P999

cụ thể, ta có hình sau:

Chi tiết các bước làm như sau:

Tạo một Activity mới tên là ChiTietActivity:

Layout XML của activity_chi_tiet.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".ChiTietActivity">

    <TextView
        android:id="@+id/textView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Mã Product:"
        android:textSize="20sp" />

    <EditText
        android:id="@+id/edtMa"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Tên Product:"
        android:textSize="20sp" />

    <EditText
        android:id="@+id/edtTen"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName" />
    <TextView
        android:id="@+id/textView3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Đơn giá:"
        android:textSize="20sp" />

    <EditText
        android:id="@+id/edtDonGia"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="numberDecimal" />

    <Button

        android:id="@+id/btnLuu"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Đổi thông tin"
        android:textSize="20sp" />

</LinearLayout>

Tiến hành sửa Coding ProductAdapter:

package com.communityuni.adapter

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.AsyncTask
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
import com.communityuni.androidkotlintonodejs.ChiTietActivity
import com.communityuni.androidkotlintonodejs.R
import com.communityuni.model.Product


class ProductAdapter(internal var context: Activity, internal var resource: Int) : ArrayAdapter<Product>(context, resource) {

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        var custom = context.layoutInflater.inflate(resource, null)
        var txtMa = custom.findViewById<TextView>(R.id.txtMa)
        var txtTen = custom.findViewById<TextView>(R.id.txtTen)
        var txtDonGia = custom.findViewById<TextView>(R.id.txtDonGia)
        var p = getItem(position)
        txtMa.text = p!!.Ma
        txtTen.text = p.Ten
        txtDonGia.text = p.DonGia.toString()
        var img=custom.findViewById<ImageView>(R.id.imgEdit)
        img.setOnClickListener { xuLyEdit(p) }
        return custom
    }

    private fun xuLyEdit(p: Product?) {
        var i=Intent(context,ChiTietActivity::class.java)
        i.putExtra("Ma",p!!.Ma)
        context.startActivity(i)
    }
}

Coding ở trên ta bổ sung sự kiện cho ImageView, ta truyền Mã Product được chọn qua màn hình ChiTietActivity.

Bên màn hình ChiTietActivity sẽ nhận được Mã Product này mà truy cập API xem chi tiết Product là xong, Xem coding của lớp ChiTietActivity:

package com.communityuni.androidkotlintonodejs

import android.os.AsyncTask
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.EditText
import com.communityuni.model.Product
import org.json.JSONObject
import java.net.URL

class ChiTietActivity : AppCompatActivity() {
    lateinit var edtMa:EditText
    lateinit var edtTen:EditText
    lateinit var edtDonGia:EditText
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_chi_tiet)
        addControls()
    }

    private fun addControls() {
        edtMa=findViewById(R.id.edtMa)
        edtTen=findViewById(R.id.edtTen)
        edtDonGia=findViewById(R.id.edtDonGia)
    }

    override fun onResume() {
        super.onResume()
        var ma=intent.getStringExtra("Ma")
        HTTPGetProductDetailTask().execute(ma)
    }
    inner class HTTPGetProductDetailTask : AsyncTask<String, Void, Product?>()
    {
        override fun doInBackground(vararg p0: String?): Product? {
            var p:Product?=null
            var ma=p0[0]
            try
            {
                var url=URL("http://192.168.1.137/nodejsapi/products/"+ma)
                var urlConnection=url.openConnection()
                var data = urlConnection.inputStream.bufferedReader().readText()
                var jsonObject=JSONObject(data)
                var Ma=jsonObject.getString("Ma")
                var Ten=jsonObject.getString("Ten")
                var DonGia=jsonObject.getDouble("DonGia")
                p=Product(Ma,Ten,DonGia)
            }
            catch (ex:Exception)
            {
                Log.e("LOI",ex.toString())
            }
            return p
        }
        override fun onPostExecute(result: Product?) {
            super.onPostExecute(result)
            if(result!=null)
            {
                edtMa.setText(result.Ma)
                edtTen.setText(result.Ten)
                edtDonGia.setText(result.DonGia.toString())
            }
        }
    }
}

bài 30 ta đã biết cách triệu gọi danh sách Product rồi, trong bài 31 này lại đơn giản hơn, nó chỉ trả về duy nhất 1 Product nên ta không cần vòng lặp. Mà lấy luôn từ JSonObject.

Chỗ coding này đã quen thuộc nên Tui sẽ không giải thích kỹ lại nữa vì bạn đã hiểu trong bài 30 rồi.

Như vậy ta đã hoàn thành xong bài triệu gọi Web API lấy Chi Tiết Product được viết bằng NodeJS và Deploy trên IISNode WebServer.

Source code Triệu gọi Web API lấy thông tin chi tiết Product tải ở đây.

Bài sau Tui sẽ hướng dẫn các Thím cách dùng Android Kotlin để  truy cập API RESTful Chỉnh Sửa Product như thế nào. Các bạn chú ý theo dõi nhé (vẫn dùng lại Project này)

Các khóa học online khác, bạn có thể tham khảo tại đây: http://communityuni.com/

Innovate Trading System (Kênh đầu tư lợi nhuận rất cao), các bạn nào quan tâm thì vào đây đầu tư nhé:

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

 

Bài 30-Truy cập NodeJS RESTful Web Services bằng Android Kotlin-HTTPGET


bài 29 Tui đã nói sơ qua các chức năng bạn phải hoàn thành để truy cập mọi Web API được deploy trong bài 28.

Bài này Ta sẽ truy cập Web API lấy toàn bộ danh sách product (với Laptop của Tui thì URI là: http://192.168.1.137/nodejsapi/products , còn của bạn như thế nào thì tự thay đổi nha, copy y xì của Tui là đi bụi đó nha).

Bây giờ bạn tạo Project tên “AndroidKotlinToNodeJS“, Project này có nhiệm vụ gọi API http://192.168.1.137/nodejsapi/products để hiển thị lên giao diện mobile như sau:

Để thực hiện được bài này ta tiến hành làm các bước sau (Tui bỏ qua bước cách tạo Project nha, đi thẳng vào cấu trúc Project):

Bước 1:

Lên http://iconfinder.com/ tìm 2 hình đại diện cho nút Edit và Delete  như hình mô tả

Tạo 1 file layout item.xml để làm giao diện Custom layout cho ListView, nó sẽ được sử dụng trong lớp ProductAdapter, XML layout của file này như sau:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/txtMa"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textColor="@color/mauchuma"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/txtTen"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textColor="@color/mauchuten"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/txtDonGia"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textColor="@color/mauchudongia" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/imgEdit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="20dp"
            app:srcCompat="@drawable/editproduct" />

        <ImageView
            android:id="@+id/imgDelete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:srcCompat="@drawable/deleteproduct" />
    </LinearLayout>

</LinearLayout>

Định nghĩa màu trong colors.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>

    <color name="maunentieude">#179a2f</color>
    <color name="mauchutieude">#fcfbfb</color>
    <color name="mauchuma">#b92222</color>
    <color name="mauchuten">#0829e7</color>
    <color name="mauchudongia">#c50d7c</color>
</resources>

Bước 2:

Tạo lớp mô hình Product để sử dụng trong ProductApdater cũng như trong Đa tiến trình truy cấp API

package com.communityuni.model

class Product {
    lateinit var _id:Any
    lateinit var Ma:String
    lateinit var Ten:String
    var DonGia:Double=0.0
    constructor(ma:String,ten:String,donGia:Double)
    {
        Ma=ma
        Ten=ten
        DonGia=donGia
    }
    override fun toString(): String {
        return Ma+"\n"+Ten+"\n"+DonGia+"VNĐ"
    }
}

Bước 3:

Tạo lớp mô hình ProductAdapter để vẽ giao diện Customlayout lên List cho nó đẹp:

package com.communityuni.adapter

import android.app.Activity
import android.content.Context
import android.os.AsyncTask
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
import com.communityuni.androidkotlintonodejs.R
import com.communityuni.model.Product


class ProductAdapter(internal var context: Activity, internal var resource: Int) : ArrayAdapter<Product>(context, resource) {

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        var custom = context.layoutInflater.inflate(resource, null)
        var txtMa = custom.findViewById<TextView>(R.id.txtMa)
        var txtTen = custom.findViewById<TextView>(R.id.txtTen)
        var txtDonGia = custom.findViewById<TextView>(R.id.txtDonGia)
        var p = getItem(position)
        txtMa.text = p!!.Ma
        txtTen.text = p.Ten
        txtDonGia.text = p.DonGia.toString()

        return custom
    }
}


Bước 4:

Coding cho lớp MainActivity để triệu gọi Web API http://192.168.1.137/nodejsapi/products

package com.communityuni.androidkotlintonodejs

import android.os.AsyncTask
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.ListView
import com.communityuni.adapter.ProductAdapter
import com.communityuni.model.Product
import org.json.JSONArray
import java.net.URL
import java.util.ArrayList

class MainActivity : AppCompatActivity() {
    lateinit var lvProduct: ListView
    lateinit var productAdapter: ProductAdapter
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        addControls()
    }
    private fun addControls() {
        lvProduct=findViewById<ListView>(R.id.lvProduct)
        productAdapter= ProductAdapter(this,R.layout.item)
        lvProduct.adapter=productAdapter
    }

    override fun onResume() {
        super.onResume()
        HTTPGetListProductTask().execute()
    }
    inner class HTTPGetListProductTask : AsyncTask<Void,Void,List<Product>>()
    {
        override fun onPreExecute() {
            super.onPreExecute()
            productAdapter.clear()
        }
        override fun doInBackground(vararg p0: Void?): List<Product> {
            var arrayListProduct=ArrayList<Product>()
            try
            {
                var url=URL("http://192.168.1.137/nodejsapi/products")
                var urlConnection=url.openConnection()
                var data = urlConnection.inputStream.bufferedReader().readText()
                var jsonArray=JSONArray(data)
                for (i in 0 until jsonArray.length())
                {
                    var jsonObject=jsonArray.getJSONObject(i)
                    var Ma=jsonObject.getString("Ma")
                    var Ten=jsonObject.getString("Ten")
                    var DonGia=jsonObject.getDouble("DonGia")
                    var product=Product(Ma,Ten,DonGia)
                    arrayListProduct.add(product)
                }
            }
            catch (ex:Exception)
            {
                Log.e("LOI",ex.toString())
            }
            return arrayListProduct
        }
        override fun onPostExecute(result: List<Product>?) {
            super.onPostExecute(result)
            if(result!=null)
            {
                productAdapter.addAll(result)
            }
        }
    }
}


Lưu ý Tui không có giải thích chi tiết coding ở trong đó bởi vì mọi thứ đã được giải thích rất kỹ ở các bài sau:

Bước 5 :

Bước cuối cùng rất quan trọng nó liên quan tới cấu hình Manifest. Bình thường chỉ cần cấp quyền truy cập internet là đủ, nhưng vì Tui đang sài bản Android mới nhất tính tới thời điểm này (24/06/2018) là bạn 8.0 nên cần khai báo thêm

android:usesCleartextTraffic="true"

Nếu mà quên thì sẽ bị lỗi sau (version cũ không bị):

java.io.IOException: Cleartext HTTP traffic not permitted

Cụ thể chi tiết cho AndroidManifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.communityuni.androidkotlintonodejs">
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:usesCleartextTraffic="true"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Như vậy ta đã hoàn thành xong bài triệu gọi Web API lấy danh sách Product được viết bằng NodeJS và Deploy trên IISNode WebServer.

Source code Triệu gọi Web API lấy danh sách Product tải ở đây.

Bài sau Tui sẽ hướng dẫn các Thím cách dùng Android Kotlin để  truy cập API RESTful lấy Chi Tiết Product như thế nào. Các bạn chú ý theo dõi nhé

Các khóa học online khác, bạn có thể tham khảo tại đây: http://communityuni.com/

Innovate Trading System (Kênh đầu tư lợi nhuận rất cao), các bạn nào quan tâm thì vào đây đầu tư nhé:

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

Bài 29-Truy cập NodeJS RESTful Web Services bằng Android Kotlin


Như vậy các bạn đã hoàn thành 100% xây dựng RESTful Webservice bằng Nodejs. Nó đã được cấu hình trong bài 28 chạy trên IISNode Webserver.

Để cho sang miệng thì Tui gọi các Web API được cấu hình trong bài 28Back End, Bài này thiết kế phần mềm Android để triệu gọi sử dụng các API đó nên nó được gọi là Front End. Còn Thím nào vừa biết làm đồng thời bài 28 và vừa viết ứng dụng để triệu gọi các Web API này thì Thím đó được gọi là Full Stack.

Font End là cái bản mặt của các Thím, Back End là tâm tính của các Thím. Full Stack bao gồm bản mặt và tâm tính của các Thím. Hiện nay rất nhiều công ty tuyển dụng nhân sự muốn cả Bản mặt lẫn tâm tính. Do đó các Thím liệu hồn mà làm tốt Full Stack nha. ahahaha không đùa đâu, đói móp mỏ đó.

Nhiệm vụ của bạn trong bài này là truy cập và sử dụng toàn bộ các API đã được deploy trong bài 28 , cụ thể các API sau (Dĩ nhiên máy tính của bạn cấu hình chạy ra như thế nào thì sử dụng như vậy chứ không phải lấy y xì như của Tui nha các Thím):

Và bạn phải tự trả lời câu hỏi của Tui như sau: Tại sao trong các bài 13, bài 14, bài 15, bài 16, bài 17, ta đã dùng Android để kết nối và tương tác CSDL MongoDB được rồi thì mắc mớ gì mà phải xây dựng RESTful Webservice NodeJs để làm cái gì? vì các WEB API suy cho cùng nó cũng chỉ cung cấp các kênh để Android có thể tương tác CSDL MongoDB thôi mà? làm chi mà phức tạp rứa?… hahahaha…. phải tự trả lời được nha.

Đây là kết quả chương trình Android Kotlin bắt buộc các bạn phải hoàn thành:

Cụ thể các chức năng đó được viết chi tiết trong các bài học dưới đây, các bấm Thím vào học nha:

Các Thím chú ý theo dõi nha.

Các khóa học online khác, bạn có thể tham khảo tại đây: http://communityuni.com/

Innovate Trading System (Kênh đầu tư lợi nhuận rất cao), các bạn nào quan tâm thì vào đây đầu tư nhé:

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

Bài 28-NodeJS RESTful Web Services – Cấu hình IISNode


bài 21 Ta đã biết cách cấu hình IISNode rồi nha (và bắt buộc phải làm được thì mới tiếp tục với bài 28 này được).

Nhiệm vụ của Ta bây giờ là cấu hình bài 27 chạy 24/7(Bài đã hoàn thành đầy đủ 4 Method: HTTPPOST, HTTPGET, HTTPPUT, HTTPDELETE). Ở đây có sự khác biệt khó khăn hơn nữa là ta dùng thư viện express, dùng mongodb, dùng Web API. Bây giờ làm sao để cấu hình nó chạy trên Web Server đây ta?

Bây giờ mở bài 27 lên cấu hình IISNode, vì ta có liên quan tới iisnode+express nên cần có thêm một số cấu hình (lưu ý là phải hoàn thành bài 21 trước thì mới tiếp tục bài này):

Bước 1:  Làm bài 21

Bước 2:

Tải và cài đặt url-rewrite: https://www.iis.net/downloads/microsoft/url-rewrite

Bấm vào Install this extension để tải rồi cài vào máy, nó ra màn hình bên dưới bấm nút Save File:

Double click vào file tải về để cài:

bấm vào rồi chờ nhà:

Chờ nó chạy để ra màn hình Web Platform Installer như bên dưới:

Bấm Install để cài đặt, nó ra màn hình hỏi lung tung về URL Rewrite bên dưới:

Bấm I Accept nhé.

rồi rung đùi chờ nó tải và cài đặt

Rung đùi cho tới khi nào cài xong:

Tới đây là ngon lành cành đào nha. Bấm FINISH để kết thúc

Bước 3:

Thêm file cấu hình web.config cho Project NodejsRESTful bài 27. Cách file web.config đã hướng dẫn ở bài 21 rồi


<configuration>
<system.webServer>
<handlers>
<add name="iisnode" path="server.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<rule name="api">
<match url="/*" />
<action type="Rewrite" url="server.js" />
</rule>
</rules>
</rewrite>
<security>
<requestFiltering>
<hiddenSegments>
<add segment="node_modules" />
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
</configuration>

Xem hình:

Như vậy ta đã thêm thành công file web.config rồi

Bước 4:

Cấu hình Web Service cho Project để chạy 24/7 trên IIS (cái này bạn tùy thích đặt tên):

Ví dụ: Tui đặt alias là nodejsapi. Physical path trỏ tới đường dẫn lưu server.js. Cách tạo, đặt như thế nào đã nói rất rõ trong bài 21 tự coi lại nha

Bấm OK để tạo

Bước 5: Kiểm thử

Mở PostMan hoặc các phần mềm tương đương khác lên để kiểm thử:

Ở trên Tui test API http://localhost/nodejsapi/products

Các bạn tự test các API còn lại như:

http://localhost/nodejsapi/products/P1

Hay kiểm thử API thêm Product:

http://localhost/nodejsapi/addProduct

http://localhost/nodejsapi/editProduct

http://localhost/nodejsapi/deleteProduct

 

Như vậy các bạn đã biết toàn bộ các method: HTTPPOST, HTTPGET, HTTPUT, HTTPDELETE. Và đồng thời biết cách cấu hình IISNode cho WEB API chạy 24/7 rồi. Bài học sau Tui sẽ hướng dẫn các bạn cách thức dùng Android Kotlin để triệu gọi toàn bộ các Web API này.

Lưu ý khi các thiết bị (ứng dụng khác) muốn tương tác tới các WEB API này thì các Thím phải đưa về Địa chỉ IP hoặc đẩy lên 1 hosting nào đó để dùng. Ví dụ như trường hợp này thì ta lấy địa chỉ IP của máy Tui chẳng hạn, test API lấy danh sách Product (nếu để localhost sẽ sài vì thiết bị khác nếu nó có OS nó tưởng localhost là của nó):

Các bạn chú ý theo dõi nhé

Source code cho phần cấu hình này tải ở đây

Các khóa học online khác, bạn có thể tham khảo tại đây: http://communityuni.com/

Innovate Trading System (Kênh đầu tư lợi nhuận rất cao), các bạn nào quan tâm thì vào đây đầu tư nhé:

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

%d bloggers like this: