Flutter HTTP-запрос
В этом разделе будет рассказано, как выполнять сетевые HTTP-запросы в приложениях Flutter, включая GET- и POST-запросы, а также обработку данных JSON.
Добавление HTTP-зависимости
Добавьте пакет http в pubspec.yaml:
dependencies: http: ^1.0.0
Затем выполните:
$ flutter pub get
Отправить GET-запрос
Пример: GET-запрос
import 'dart:convert';
import 'package:http/http.dart' as http;
// Простой GET-запрос
Future<void> fetchData() async {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
if (response.statusCode == 200) {
// Парсинг данных JSON
final data = jsonDecode(response.body);
print('Заголовок: ${data['title']}');
} else {
print('Ошибка запроса: ${response.statusCode}');
}
}
// GET-запрос с параметрами
Future<void> searchData(String query) async {
final uri = Uri.parse('https://api.example.com/search')
.replace(queryParameters: {'q': query, 'page': '1'});
final response = await http.get(uri);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
print(Результат: $data);
}
}
import 'package:http/http.dart' as http;
// Простой GET-запрос
Future<void> fetchData() async {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
if (response.statusCode == 200) {
// Парсинг данных JSON
final data = jsonDecode(response.body);
print('Заголовок: ${data['title']}');
} else {
print('Ошибка запроса: ${response.statusCode}');
}
}
// GET-запрос с параметрами
Future<void> searchData(String query) async {
final uri = Uri.parse('https://api.example.com/search')
.replace(queryParameters: {'q': query, 'page': '1'});
final response = await http.get(uri);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
print(Результат: $data);
}
}
Отправить POST-запрос
Пример: POST-запрос
import 'dart:convert';
import 'package:http/http.dart' as http;
// POST-запрос — отправка данных JSON
Future<void> postData() async {
final uri = Uri.parse('https://jsonplaceholder.typicode.com/posts');
final response = await http.post(
uri,
headers: {
'Content-Type': 'application/json', // Установить заголовок запроса
},
body: jsonEncode({ // Преобразовать объект Dart в строку JSON
'title': Руководство по Flutter,
'body': 'Изучение сетевых запросов во Flutter',
'userId': 1,
}),
);
if (response.statusCode == 201) {
final data = jsonDecode(response.body);
print('Успешно создано: $data');
} else {
print('Ошибка запроса: ${response.statusCode}');
}
}
// POST-запрос - отправка данных формы
Future<void> postFormData() async {
final uri = Uri.parse('https://example.com/api/login');
final response = await http.post(
uri,
body: {
'username': 'admin',
'password': '123456',
},
);
print('Ответ: ${response.body}');
}
import 'package:http/http.dart' as http;
// POST-запрос — отправка данных JSON
Future<void> postData() async {
final uri = Uri.parse('https://jsonplaceholder.typicode.com/posts');
final response = await http.post(
uri,
headers: {
'Content-Type': 'application/json', // Установить заголовок запроса
},
body: jsonEncode({ // Преобразовать объект Dart в строку JSON
'title': Руководство по Flutter,
'body': 'Изучение сетевых запросов во Flutter',
'userId': 1,
}),
);
if (response.statusCode == 201) {
final data = jsonDecode(response.body);
print('Успешно создано: $data');
} else {
print('Ошибка запроса: ${response.statusCode}');
}
}
// POST-запрос - отправка данных формы
Future<void> postFormData() async {
final uri = Uri.parse('https://example.com/api/login');
final response = await http.post(
uri,
body: {
'username': 'admin',
'password': '123456',
},
);
print('Ответ: ${response.body}');
}
Обработка данных JSON
Пример: парсинг JSON
import 'dart:convert';
// Определить модель данных
class Article {
final int id;
final String title;
final String body;
final User user;
Article({
required this.id,
required this.title,
required this.body,
required this.user,
});
// Разобрать из JSON
factory Article.fromJson(Map<String, dynamic> json) {
return Article(
id: json['id'],
title: json['title'],
body: json['body'],
user: User.fromJson(json['user']),
);
}
// Преобразовать в JSON
Map<String, dynamic> toJson() {
return {
'id': id,
'title': title,
'body': body,
'user': user.toJson(),
};
}
}
class User {
final int id;
final String name;
User({required this.id, required this.name});
factory User.fromJson(Map<String, dynamic> json) {
return User(id: json['id'], name: json['name']);
}
Map<String, dynamic> toJson() {
return {'id': id, 'name': name};
}
}
// Пример использования
void parseJson() {
final jsonString = '''
{
"id": 1,
"title": "Учебник по Flutter",
"body": "Изучите Flutter",
"user": {"id": 1, "name": "Чжан Сань"}
}
''';
// Разбор строки JSON
final Map<String, dynamic> json = jsonDecode(jsonString);
final article = Article.fromJson(json);
print('ID статьи: ${article.id}');
print('Автор: ${article.user.name}');
}
// Определить модель данных
class Article {
final int id;
final String title;
final String body;
final User user;
Article({
required this.id,
required this.title,
required this.body,
required this.user,
});
// Разобрать из JSON
factory Article.fromJson(Map<String, dynamic> json) {
return Article(
id: json['id'],
title: json['title'],
body: json['body'],
user: User.fromJson(json['user']),
);
}
// Преобразовать в JSON
Map<String, dynamic> toJson() {
return {
'id': id,
'title': title,
'body': body,
'user': user.toJson(),
};
}
}
class User {
final int id;
final String name;
User({required this.id, required this.name});
factory User.fromJson(Map<String, dynamic> json) {
return User(id: json['id'], name: json['name']);
}
Map<String, dynamic> toJson() {
return {'id': id, 'name': name};
}
}
// Пример использования
void parseJson() {
final jsonString = '''
{
"id": 1,
"title": "Учебник по Flutter",
"body": "Изучите Flutter",
"user": {"id": 1, "name": "Чжан Сань"}
}
''';
// Разбор строки JSON
final Map<String, dynamic> json = jsonDecode(jsonString);
final article = Article.fromJson(json);
print('ID статьи: ${article.id}');
print('Автор: ${article.user.name}');
}
Обработка ошибок
Пример: Полный пример сетевого запроса
import 'dart:convert';
import 'package:http/http.dart' as http;
class ApiService {
// Базовый URL
static const String baseUrl = 'https://jsonplaceholder.typicode.com';
// Универсальный метод GET-запроса
static Future<dynamic> get(String endpoint) async {
try {
final response = await http.get(
Uri.parse('$baseUrl/$endpoint'),
);
return _handleResponse(response);
} catch (e) {
throw ApiException('Ошибка сети: $e');
}
}
// Универсальный метод POST-запроса
static Future<dynamic> post(
String endpoint,
Map<String, dynamic> data,
) async {
try {
final response = await http.post(
Uri.parse('$baseUrl/$endpoint'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode(data),
);
return _handleResponse(response);
} catch (e) {
throw ApiException('Ошибка сети: $e');
}
}
// Обработка ответа
static dynamic _handleResponse(http.Response response) {
if (response.statusCode >= 200 && response.statusCode < 300) {
// Успешный ответ
if (response.body.isEmpty) {
return null;
}
return jsonDecode(response.body);
} else if (response.statusCode == 404) {
throw ApiException(Ресурс не найден, statusCode: 404);
} else if (response.statusCode >= 500) {
throw ApiException('Ошибка сервера', statusCode: response.statusCode);
} else {
throw ApiException(
'Запрос не выполнен',
statusCode: response.statusCode,
);
}
}
}
// Пользовательский класс исключения
class ApiException implements Exception {
final String message;
final int? statusCode;
ApiException(this.message, {this.statusCode});
@override
String toString() => 'ApiException: $message (статус: $statusCode)';
}
// Пример использования
Future<void> fetchArticles() async {
try {
final articles = await ApiService.get('posts');
print('Получено ${articles.length} статей');
} on ApiException catch (e) {
print('API error: $e');
}
}
import 'package:http/http.dart' as http;
class ApiService {
// Базовый URL
static const String baseUrl = 'https://jsonplaceholder.typicode.com';
// Универсальный метод GET-запроса
static Future<dynamic> get(String endpoint) async {
try {
final response = await http.get(
Uri.parse('$baseUrl/$endpoint'),
);
return _handleResponse(response);
} catch (e) {
throw ApiException('Ошибка сети: $e');
}
}
// Универсальный метод POST-запроса
static Future<dynamic> post(
String endpoint,
Map<String, dynamic> data,
) async {
try {
final response = await http.post(
Uri.parse('$baseUrl/$endpoint'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode(data),
);
return _handleResponse(response);
} catch (e) {
throw ApiException('Ошибка сети: $e');
}
}
// Обработка ответа
static dynamic _handleResponse(http.Response response) {
if (response.statusCode >= 200 && response.statusCode < 300) {
// Успешный ответ
if (response.body.isEmpty) {
return null;
}
return jsonDecode(response.body);
} else if (response.statusCode == 404) {
throw ApiException(Ресурс не найден, statusCode: 404);
} else if (response.statusCode >= 500) {
throw ApiException('Ошибка сервера', statusCode: response.statusCode);
} else {
throw ApiException(
'Запрос не выполнен',
statusCode: response.statusCode,
);
}
}
}
// Пользовательский класс исключения
class ApiException implements Exception {
final String message;
final int? statusCode;
ApiException(this.message, {this.statusCode});
@override
String toString() => 'ApiException: $message (статус: $statusCode)';
}
// Пример использования
Future<void> fetchArticles() async {
try {
final articles = await ApiService.get('posts');
print('Получено ${articles.length} статей');
} on ApiException catch (e) {
print('API error: $e');
}
}
Другие расширенияВ реальных приложениях рекомендуется инкапсулировать сетевые запросы в сервисные классы, чтобы единообразно обрабатывать ошибки, состояния загрузки и логику кэширования.