Unhandled Exception: Bad state: Cannot set the body fields of a Request with content-type "application/json".
이 에러는 body에 json이 아닌 내용이 들어간 것이라고 알려주는 exception이다.
jsonEncode()를 적용하지 않은 {"message" :"hi"}와 같은 딕셔너리를 바로 body에 아래와 같이 입력하면 이런게 나온다.
var response = Uri.post('http://127.0.0.1:8000', body : {"message" :"hi"}, headers: {"Content-Type": "application/json"});
Unhandled Exception: Converting object to an encodable object failed: Instance of 'DateTime'
이후에 class instance였던 futureGoal을 class method를 통해 json으로 변형한 것을 넣자 생긴 에러로 json이 지원하는 데이터타입에 DateTime이 포함되지 않기 때문에 생긴 에러였다. 아래와 같이 만들면 생긴다. DateTime 유형의 변수에 .toString()을 붙여서 toJson 함수를 고치면 된다.
models.dart
class Goal{
int goal_id = 0;
String? goal_text;
int? user_id;
DateTime? created_at;
//constructor
Goal(this.goal_text, this.user_id)
:
goal_id = 1,
created_at = DateTime.now()
{
print('Goal Generated : $goal_text from $goal_id');
}
Goal.createGoal(this.goal_text, this.user_id, this.goal_id)
:
created_at = DateTime.now()
{
goal_id = goal_id + 1; // 값을 변경하는 건 {} 안에서 하는 게 맞는 것 같다.
print('Goal Generated : $goal_text from $goal_id');
}
//json encode
Map<String, dynamic> toJson() => {
'goal_id': goal_id,
'goal_text': goal_text,
'user_id' : user_id,
'created_at' : created_at
};
}
backup.dart
import 'dart:convert';
import 'package:http_test/models.dart';
import 'package:http/http.dart' as http;
Stream<int> setPost(int seconds) async* {
yield* Stream.periodic(Duration(seconds: seconds), (int i) {
backupGoal();
return i;
});
}
//send http post about goal
Future<int> backupGoal() async {
// initialize goal
var goal = initGoal();
//send post
var url = Uri.parse("http://127.0.0.1:8000");
var response;
response = await http.post(url, body: jsonEncode(goal.toJson()), headers: {"Content-Type": "application/json"});
return response.statusCode;
}
Goal initGoal(){
// set content
final goal_id = 2;
final user_id = 0;
final goal_text = "text";
return Goal.createGoal(goal_text, user_id, goal_id);
}
Unhandled Exception: ClientException with SocketException: Connection refused
이번 문제는 android emulater가 인지하는 localhost의 주소가 10.0.2.2이기 때문에 발생했다. 127.0.0.1을 10.0.2.2로 대체해주고 Django의 settings.py에 ALLOWED_HOSTS = ['10.0.2.2'] 를 넣어주면 된다.