昨天介紹了一下GET
但是POST就麻煩得多,基本上有以下三種
另外在Flutter裡有三種常見的網路請求作法
今天就來測試一下3*3
種情境該怎麼寫
網路開放資源,可隨意測試
application/json
http://httpbin.org/delay/1
application/x-www-form-urlencoded
https://reqres.in/api/login
multipart/form-data
https://postman-echo.com/post
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:dio/dio.dart';
import 'package:idlf/model/User.dart';
typedef UsersCallback = void Function(Users);
class APIManager {
//以下POST HttpClient分隔線=================
void loginHttpClientWWW(void Function() success, void Function() fail) async {
var urlString = "https://reqres.in/api/login";
HttpClient()
.postUrl(Uri.parse(urlString))
.then((HttpClientRequest request) {
request.headers.contentType = ContentType("application", "x-www-form-urlencoded");
request.write("{\"email\":\"eve.holt@reqres.in\",\"password\":\"cityslicka\"}");
// request.write("email=eve.holt@reqres.in");
// request.write("password=cityslicka");
return request.close();
}).then((HttpClientResponse response) {
if (response.statusCode == 200) {
response.transform(utf8.decoder).join().then((String string) {
print("HttpClientWWW Success:$string");
success();
});
} else {
print("HttpClientWWW Fail:${response.statusCode}");
fail();
}
});
}
void loginHttpClientJson(void Function() success, void Function() fail) async {
var urlString = "http://httpbin.org/delay/1";
HttpClient()
.postUrl(Uri.parse(urlString))
.then((HttpClientRequest request) {
request.headers.contentType = ContentType("application", "json");
Map<String,String> p = {"UserName":"eve.holt@reqres.in", "Password":"cityslicka"};
request.add(utf8.encode(json.encode(p)));
return request.close();
}).then((HttpClientResponse response) {
if (response.statusCode == 200) {
response.transform(utf8.decoder).join().then((String string) {
print("HttpClientJson Success:$string");
success();
});
} else {
print("HttpClientJson Fail:${response.statusCode}");
fail();
}
});
}
void loginHttpClientForm(void Function() success, void Function() fail) async {
}
//以下POST http分隔線=================
void loginHttpWWW(void Function() success, void Function() fail) async {
var urlString = "https://reqres.in/api/login";
Map<String, String> headersMap = new Map();
headersMap["content-type"] = "application/x-www-form-urlencoded";
Map<String, String> bodyParams = new Map();
bodyParams["email"] = "eve.holt@reqres.in";
bodyParams["password"] = "cityslicka";
http.Client()
.post(urlString, headers: headersMap, body: bodyParams, encoding: Utf8Codec())
.then((http.Response response) {
if (response.statusCode == 200) {
print("httpWWW Success:${response.body}");
success();
} else {
print("httpWWW Fail:${response.statusCode}");
fail();
}
}).catchError((error) {
print("httpWWW Fail:${error.toString()}");
fail();
});
}
void loginHttpJson(void Function() success, void Function() fail) async {
var urlString = "http://httpbin.org/delay/1";
Map<String, String> headersMap = new Map();
headersMap["content-type"] = ContentType.json.toString();
Map<String, String> bodyParams = new Map();
bodyParams["email"] = "eve.holt@reqres.in";
bodyParams["password"] = "cityslicka";
http.Client()
.post(urlString, headers: headersMap, body: jsonEncode(bodyParams), encoding: Utf8Codec())
.then((http.Response response) {
if (response.statusCode == 200) {
print("httpJson Success:${response.body}");
success();
} else {
print("httpJson Fail:${response.statusCode}");
fail();
}
}).catchError((error) {
print("httpJson Fail:${error.toString()}");
fail();
});
}
void loginHttpForm(void Function() success, void Function() fail) async {
var urlString = "https://postman-echo.com/post";
var client = new http.MultipartRequest("post", Uri.parse(urlString));
client.fields["email"] = "eve.holt@reqres.in";
client.fields["password"] = "cityslicka";
client.send().then((http.StreamedResponse response) {
if (response.statusCode == 200) {
response.stream.transform(utf8.decoder).join().then((String string) {
print("httpForm Success:$string");
success();
});
} else {
print("httpForm Fail:${response.statusCode}");
fail();
}
}).catchError((error) {
print("httpForm Fail:${error.toString()}");
fail();
});
}
//以下POST Dio分隔線=================
void loginDioWWW(void Function() success, void Function() fail) async {
var urlString = "https://reqres.in/api/login";
try {
Response response = await Dio()
.post(urlString,
data: {"email":"eve.holt@reqres.in", "password":"cityslicka"},
options: Options(contentType:Headers.formUrlEncodedContentType));
print("DioWWW Success:${response.data}");
success();
} catch (error) {
print("DioWWW Fail:${error.toString()}");
fail();
}
}
void loginDioJson(void Function() success, void Function() fail) async {
var urlString = "http://httpbin.org/delay/1";
try {
Response response = await Dio()
.post(urlString,
data: {"email":"eve.holt@reqres.in", "password":"cityslicka"},
options: Options(contentType:Headers.jsonContentType));
print("DioJson Success:${response.data}");
success();
} catch (error) {
print("DioJson Fail:${error.toString()}");
fail();
}
}
void loginDioForm(void Function() success, void Function() fail) async {
var urlString = "https://postman-echo.com/post";
try {
Response response = await Dio()
.post(urlString,
data: FormData.fromMap({"email":"eve.holt@reqres.in", "password":"cityslicka"}));
print("DioForm Success:${response.data}");
success();
} catch (error) {
print("DioForm Fail:${error.toString()}");
fail();
}
}
}
class LessonPageApiPost extends StatefulWidget {
@override
_LessonPageApiPostState createState() => _LessonPageApiPostState();
}
class _LessonPageApiPostState extends State<LessonPageApiPost> {
final long = 66.0;
final List<bool> formDataResults = [null, null, null];
final List<bool> jsonResults = [null, null, null];
final List<bool> wwwResults = [null, null, null];
Widget _createContainer(String text) {
return Container(
height: long,
alignment: Alignment.center,
child: Text(text),
);
}
Widget _createResultWidget(bool result) {
if (result == true) {
return _createContainer("⭕️");
} else if (result == false) {
return _createContainer("❌");
} else {
return Container(
height: long,
child: CupertinoActivityIndicator()
);
}
}
Widget _createTable() {
return Table(
columnWidths: {
1: FixedColumnWidth(long),
2: FixedColumnWidth(long),
3: FixedColumnWidth(long),
},
children: [
TableRow(
children: [
_createContainer(""),
_createContainer("HttpClient"),
_createContainer("http"),
_createContainer("Dio"),
]
),
TableRow(
children: [
_createContainer("json"),
_createResultWidget(jsonResults[0]),
_createResultWidget(jsonResults[1]),
_createResultWidget(jsonResults[2]),
]
),
TableRow(
children: [
_createContainer("x-www-form-urlencoded"),
_createResultWidget(wwwResults[0]),
_createResultWidget(wwwResults[1]),
_createResultWidget(wwwResults[2]),
]
),
TableRow(
children: [
_createContainer("form-data"),
_createResultWidget(formDataResults[0]),
_createResultWidget(formDataResults[1]),
_createResultWidget(formDataResults[2]),
]
)
]
);
}
@override
void initState() {
super.initState();
//=============www
APIManager().loginHttpClientWWW(() {
setState(() { wwwResults[0] = true; });
}, () {
setState(() { wwwResults[0] = false; });
});
APIManager().loginHttpWWW(() {
setState(() { wwwResults[1] = true; });
}, () {
setState(() { wwwResults[1] = false; });
});
APIManager().loginDioWWW(() {
setState(() { wwwResults[2] = true; });
}, () {
setState(() { wwwResults[2] = false; });
});
//=============json
APIManager().loginHttpClientJson(() {
setState(() { jsonResults[0] = true; });
}, () {
setState(() { jsonResults[0] = false; });
});
APIManager().loginHttpJson(() {
setState(() { jsonResults[1] = true; });
}, () {
setState(() { jsonResults[1] = false; });
});
APIManager().loginDioJson(() {
setState(() { jsonResults[2] = true; });
}, () {
setState(() { jsonResults[2] = false; });
});
//=============Form
APIManager().loginHttpClientForm(() {
setState(() { formDataResults[0] = true; });
}, () {
setState(() { formDataResults[0] = false; });
});
APIManager().loginHttpForm(() {
setState(() { formDataResults[1] = true; });
}, () {
setState(() { formDataResults[1] = false; });
});
APIManager().loginDioForm(() {
setState(() { formDataResults[2] = true; });
}, () {
setState(() { formDataResults[2] = false; });
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("第十六堂課"),
),
body: Padding(
padding: EdgeInsets.only(right: 8),
child: _createTable()
)
);
}
}
本集內容Android版請見:iOS Developer Learning Android. Lesson 18
下集預告:生命週期
最後提供一下github.com/mark33699/IDLF