일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 테스트
- textview
- 계측
- ScrollView
- android
- binding
- livedata
- Coroutines
- DART
- Button
- Kotlin
- drift
- TEST
- Dialog
- textfield
- 안드로이드
- LifeCycle
- appbar
- viewmodel
- activity
- data
- Navigation
- intent
- Flutter
- scroll
- 앱바
- Compose
- CustomScrollView
- tabbar
- 앱
- Today
- Total
Study Record
[Flutter] 서버와 통신하기 (dio v5.1.1) 본문
🎁 dio
Dart 와 Flutter 에서 사용할 수 있는 HTTP 통신을 지원하는 라이브러리로 사용방법이 간단하다. 인터셉트, 파일 업로드/다운로드, 요청 시간 설정 등 여러가지 기능을 지원한다.
😶 초기 설정
터미널에서 "dart pub add dio" 를 실행하면 자동으로 dio 라이브러리를 추가해 준다.
dart pub add dio
혹은 직접 pubspec.yaml 파일에 라이브러리를 추가해 준 뒤, pub get 버튼을 눌러 프로젝트에 반영한다.
dependencies:
...
dio: ^5.1.1
🎁 HTTP 요청
😶 get 요청
dio.get() 함수로 쉽게 요청할 수 있다. url 에 직접 파라미터를 넣을 수 있고 queryParameters 인자로 Map<String, dynamic> 형식으로 넣을 수도 있다.
import 'package:dio/dio.dart';
void request() async {
final dio = Dio();
Response response = await dio.get(
'https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=1&ie=utf8&query=%EC%82%AC%EB%9E%91',
);
print(response.data.toString());
Response response2 = await dio.get(
'https://search.naver.com/search.naver',
queryParameters: {
'where': 'nexearch',
'sm': 'top_hty',
'fbm': 1,
'ie': "utf8",
'query': '%EC%82%AC%EB%9E%91',
},
// header 옵션 넣기
options: Options(
headers: {
"headerOption": "23123",
}
),
);
print(response2.data.toString());
}
😶 post 요청
dio.post() 함수로 post 요청을 할 수 있다. data 인자로 파라미터를 넣을 수 있다. 직접 Map 형태로 넣거나 FormData.fromMap() 을 사용할 수 있다.
import 'package:dio/dio.dart';
void request() async {
final dio = Dio();
final formData = FormData.fromMap({
'id': 12,
'name': 'dio',
});
Response response = await dio.post('http://www.example.com/test', data: formData);
Response response2 = await dio.post(
'http://www.example.com/test',
data: {'id': 12, 'name': 'dio'},
// header 옵션 넣기
options: Options(
headers: {
"headerOption": "23123",
},
),
);
print(response.data.toString());
print(response2.data.toString());
}
😶 옵션 설정하기
dio 옵션으로 baseurl, 연결 시간, 수신 시간을 설정할 수 있다. baseUrl 은 dio 로 요청할 때 앞에 기본으로 붙는 url 로 dio.get("/test") 라면 baseUrl + "/test" 로 http 요청을 시도한다.
import "package:dio/dio.dart"
void configureDio() async{
final dio = Dio();
// Set default configs
dio.options.baseUrl = 'https://www.naver.com';
dio.options.connectTimeout = Duration(seconds: 5);
dio.options.receiveTimeout = Duration(seconds: 3);
// Or create `Dio` with a `BaseOptions` instance.
final options = BaseOptions(
baseUrl: 'https://api.pub.dev',
connectTimeout: Duration(seconds: 5),
receiveTimeout: Duration(seconds: 3),
);
final anotherDio = Dio(options);
// http://www.naver.com/test
Response resp = await dio.get("/test");
// http://api.pub.dev/test
Response resp2 = await anotherDio.get("/test");
}
😶 Request 요청하기
dio.request() 를 사용하여 그때그때 적합한 요청을 만들 수 있다.
final dio = Dio();
dio.options.baseUrl = "https://search.naver.com";
final response = await dio.request(
'/test',
queryParameters: {
"id": 2,
"name": "dsasd",
},
options: Options(method: 'GET'),
);
final response2 = await dio.request(
'/test',
data: {
"id": 2,
"name": "dsasd",
},
options: Options(
method: 'POST',
headers: {
"headerOption": "rewer",
},
),
);
😶 Interceptors 적용하기 + 요청 Log 남기기
interceptors 를 적용하여 요청을 보낼때(onRequest), 응답을 받을 때(onResponse), 에러가 났을 때(onError)를 캐치하여 여러 가지 작업을 할 수 있다. dio 가 http 요청을 보낼 때 onRequest() 에서 super.onRequest(options, handler) 를 실행할 때 실제로 요청이 보내진다. 그 이전에 options 를 수정하면 수정된 값으로 요청할 수 있다.
import "package:dio/dio.dart";
final dio = Dio();
// interceptors 추가하기
dio.interceptors.add(CustomInterceptors());
// interceptor 를 상속한 클래스 만들기
class CustomInterceptors extends Interceptor {
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
print('REQUEST[${options.method}] => PATH: ${options.baseUrl}${options.path}${options.queryParameters}');
// 요청 전 header 를 추가한다.
options.headers.addAll({
'authorization' : 'Bearer token',
});
// 실제로 http 요청이 보내진다.
super.onRequest(options, handler);
}
@override
void onResponse(Response response, ResponseInterceptorHandler handler) {
print('RESPONSE[${response.statusCode}] => PATH: ${response.requestOptions.path}');
super.onResponse(response, handler);
}
@override
void onError(DioError err, ErrorInterceptorHandler handler) {
print('ERROR[${err.response?.statusCode}] => PATH: ${err.requestOptions.path}');
// 에러가 난 요청의 response
final errResponse = err.response;
// 에러가 난 요청의 requestOptions
final errRequestOption = err.requestOptions;
super.onError(err, handler);
}
}
+ reject(), resolve()
Interceptor 를 상속한 클래스에서 onRequest, onResponse, onError 의 handler 에는 reject(DioError), resolve(Response) 함수가 있는데 reject() 는 실제 요청의 결과가 어떻든 에러라는 결과를 반환하고 resolve() 는 실제 요청이 실패해도 성공한 것으로 반환한다. 따라서 onError() 에서 handler.solve(Response resp) 를 실행하면 요청이 성공한 것으로 간주되고 데이터는 resp 를 반환한다.
// example
class CustomInterceptors extends Interceptor {
@override
void onError(DioError err, ErrorInterceptorHandler handler) {
print('ERROR[${err.response?.statusCode}] => PATH: ${err.requestOptions.path}');
if(err.response.statusCode != null && err.response.statusCode == 411){
return handler.reject(err);
} else {
return handler.resolve(Response(data: 'fake data'));
}
}
}
😶 Handling Error
try-catch 문으로 dio 에러를 직접 관리할 수 있다.
import "package:dio/dio.dart";
final dio = Dio();
try {
await dio.get('https://api.pub.dev/not-exist');
} on DioError catch (e) {
if (e.response != null) {
print(e.response.data)
print(e.response.headers)
print(e.response.requestOptions)
} else {
// Something happened in setting up or sending the request that triggered an Error
print(e.requestOptions)
print(e.message)
}
}
'Flutter > 라이브러리' 카테고리의 다른 글
[Flutter] 토스트 팝업 메시지 (fluttertoast v8) (0) | 2023.04.22 |
---|---|
[Flutter] JSON (json_serializable 라이브러리) (0) | 2023.04.17 |
[Flutter] 간단한 데이터 저장 (flutter_secure_storage) (0) | 2023.04.07 |
[Flutter] drift 에서 Future 와 Stream 차이점 (2) | 2023.03.26 |
[Flutter] 데이터베이스 importing (drift) (0) | 2023.03.26 |