upload method
Uploads data to the server.
This method uploads data (typically files) to the server. Progress can be
tracked using the optional onProgress callback.
Parameters:
request: The request configuration for the upload, including the data to uploadonProgress: Optional callback to track upload progress
Returns a Future that completes with an AdapterResponse when the upload is complete.
Throws AdapterException if the upload fails.
Example:
final request = AdapterRequest(
baseUrl: 'https://api.example.com',
path: '/upload',
method: HttpMethod.post,
bodyParams: {'file': File('/path/to/file.jpg')},
);
await adapter.upload(
request,
onProgress: (count, total) {
print('Uploaded: ${(count / total * 100).toStringAsFixed(1)}%');
},
);
Implementation
@override
Future<AdapterResponse> upload(
AdapterRequest request, {
ProgressCallback? onProgress,
}) async {
try {
// 构建 URI
final uri = _buildUri(request);
// 创建 multipart 请求
final multipartRequest = http.MultipartRequest(
request.method.name.toUpperCase(),
uri,
);
// 添加头部
final headers = _buildHeaders(request);
multipartRequest.headers.addAll(headers);
// 添加字段和文件
for (final entry in request.bodyParams.entries) {
if (entry.value is File) {
final file = entry.value as File;
multipartRequest.files.add(
await http.MultipartFile.fromPath(entry.key, file.path),
);
} else if (entry.value is http.MultipartFile) {
multipartRequest.files.add(entry.value as http.MultipartFile);
} else {
multipartRequest.fields[entry.key] = entry.value.toString();
}
}
// 发送请求
final streamedResponse = await multipartRequest.send();
// 读取响应
final responseBody = await streamedResponse.stream.bytesToString();
// 解析响应数据
dynamic data;
try {
final contentType = streamedResponse.headers['content-type'] ?? '';
if (contentType.contains('application/json')) {
data = jsonDecode(responseBody);
} else {
data = responseBody;
}
} catch (e) {
data = responseBody;
}
// 转换头部
final responseHeaders = <String, List<String>>{};
streamedResponse.headers.forEach((key, value) {
responseHeaders[key] = [value];
});
final response = AdapterResponse(
statusCode: streamedResponse.statusCode,
statusMessage: streamedResponse.reasonPhrase,
data: data,
headers: responseHeaders,
request: request,
);
// 检查是否是错误响应
if (!response.isSuccess) {
throw AdapterException(
message: 'HTTP ${response.statusCode}',
type: AdapterExceptionType.response,
statusCode: response.statusCode,
response: response,
);
}
return response;
} catch (e, stackTrace) {
if (e is AdapterException) {
rethrow;
}
throw _convertException(e, stackTrace);
}
}