问题描述
问题1:当你使用FormData.from(Flutter3直接不能用)的时候,可能会提示没有这个方法,或者使用FormData.fromMap(flutter3的dio支持)的时候也提示没有,这时候可能就是和get库里面的Formdata冲突了
问题1:The method 'fromMap' isn't defined for the type 'FormData'. (Documentation) Try correcting the name to the name of an existing method, or defining a method named 'fromMap'
解决办法:有可能是库冲突了,因为get和dio库里面都有FormData导致的,使用别名更换一下
The method 'from' isn't defined for the type 'FormData'. (Documentation) Try correcting the name to the name of an existing method, or defining a method named 'from'
解决办法:更换使用 FormData.fromMap 这个方法 FormData.fromMap({})
然后你点击进去这个库的源代码看一下:发现确实没有from或者fromMap方法,而且会默认跳转到get库里面的FormData,怎么回事?我们应该使用的是dio库里面的啊
这个时候就应该意识到是库冲突了,所以单独引入dio库:
这个时候就会报另外一个问题:
The name 'FormData' is defined in the libraries 'package:dio/src/form_data.dart (via package:dio/dio.dart)' and 'package:get/get_connect/http/src/multipart/form_data.dart'. (Documentation) Try using 'as prefix' for one of the import directives, or hiding the name from all but one of the imports.
解决办法
意思是:这个get库和dio库里面都有这个FormData,所以需要使用别名指定一下
import 'package:dio/dio.dart' as dio_package;
然后使用这个前缀来引用:
Map<String, String> data = {
"cardno": system.nfcId.toString(),
"gender": system.gender.toString(),
"username": system.nickName.toString(),
"headpicurl": system.avatar.toString()
};
dio_package.FormData formData = dio_package.FormData.fromMap(data);
然后在使用dio发送请求的时候:直接使用post,然后把data放进去就好了(因为dio底层做了判断是不是FormData,是的话,默认会加上contentType)
var result = await Request()
.request("/v1/server/nfcadduser", method: DioMethod.post, data: data);
// 返回数据
// print("getDetail:$result");
return result;
dio底层做的判断:
然后服务器就可以接收到这个数据了:
封装好的Dio对象
我这里封装了一个Request对象:
import 'package:dio/dio.dart';
import 'package:flutter_windows/utils/storeage.dart';
/// 请求方法:枚举类型
enum DioMethod {
get,
post,
put,
delete,
patch,
head,
}
// 创建请求类:封装dio
class Request {
/// 单例模式
static Request? _instance;
// 本地存储对象
final storage = Storage();
// 工厂函数:执行初始化
factory Request() => _instance ?? Request._internal();
// 获取实例对象时,如果有实例对象就返回,没有就初始化
static Request? get instance => _instance ?? Request._internal();
/// Dio实例
static Dio _dio = Dio();
// 初始化ip和端口
String ip = "baseUrl地址";
int port = 9080;
/// 初始化
Request._internal() {
// 初始化基本选项
BaseOptions options = BaseOptions(
baseUrl: 'http://$ip:$port',
connectTimeout: const Duration(seconds: 3),
receiveTimeout: const Duration(seconds: 3));
_instance = this;
// 初始化dio
_dio = Dio(options);
// 添加拦截器
_dio.interceptors.add(InterceptorsWrapper(
onRequest: _onRequest, onResponse: _onResponse, onError: _onError));
}
// 重置ip地址
void setIP(String ip) {
_dio.options.baseUrl = ip;
}
/// 请求拦截器
void _onRequest(RequestOptions options, RequestInterceptorHandler handler) {
// 对非open的接口的请求参数全部增加userId
if (!options.path.contains("open")) {
// options.queryParameters["userId"] = "xxx";
}
// 头部添加token
// options.headers["token"] = "xxx";
// 更多业务需求
handler.next(options);
// super.onRequest(options, handler);
}
/// 相应拦截器
void _onResponse(
Response response, ResponseInterceptorHandler handler) async {
// 请求成功是对数据做基本处理
if (response.statusCode == 200) {
// 处理成功的响应
// print("响应结果: $response");
} else {
// 处理异常结果
print("响应异常: $response");
}
handler.next(response);
}
/// 错误处理: 网络错误等
void _onError(DioException error, ErrorInterceptorHandler handler) {
handler.next(error);
}
/// 请求类:支持异步请求操作
Future<T> request<T>(
String path, {
DioMethod method = DioMethod.get,
Map<String, dynamic>? params,
dynamic data,
CancelToken? cancelToken,
Options? options,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
const methodValues = {
DioMethod.get: 'get',
DioMethod.post: 'post',
DioMethod.put: 'put',
DioMethod.delete: 'delete',
DioMethod.patch: 'patch',
DioMethod.head: 'head'
};
// 默认配置选项
options ??= Options(method: methodValues[method]);
try {
Response response;
// 开始发送请求
response = await _dio.request(path,
data: data,
queryParameters: params,
cancelToken: cancelToken,
options: options,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress);
return response.data;
} on DioException catch (e) {
// print("发送请求异常: $e");
rethrow;
}
}
/// 开启日志打印
/// 需要打印日志的接口在接口请求前 Request.instance?.openLog();
void openLog() {
_dio.interceptors
.add(LogInterceptor(responseHeader: false, responseBody: true));
}
}