Dio3.0上传文件具体使用如下:
void uploadPhoto(File file) async{
String path = file.path;
var name = path.substring(path.lastIndexOf("/") + 1, path.length);
String imageType = name.substring(name.lastIndexOf(".") + 1, name.length);
var image = await MultipartFile.fromFile(
path,
filename: name,
);
print("文件路径="+path);
print("文件名="+name);
print("文件image=$image");
FormData formData = FormData.fromMap({
"image": image
});
asyncRequestNetwork<Map>(
Method.post,
url: HttpConstants.UPDATE_USER_PHOTO,
params: formData,
isList: false,
isShow: true,
onSuccess: (data){
if(data != null) {
String url = data["URL"];
view.provider.setUserPhoto(url);
UserInfoBean userInfoBean = Provider.of<UserProvider>(view.context).user;
print("provider==="+userInfoBean.phone);
userInfoBean.photoURI = url;
Provider.of<UserProvider>(view.context).saveUser(userInfoBean);
}
},
);
}
封装dio请求dio_utils.dart
class DioUtils {
static final DioUtils _singleton = DioUtils._internal();
static DioUtils get instance => DioUtils();
factory DioUtils() {
return _singleton;
}
static Dio _dio;
Dio getDio(){
return _dio;
}
DioUtils._internal(){
var options = BaseOptions(
connectTimeout: 15000,
receiveTimeout: 15000,
responseType: ResponseType.plain,
validateStatus: (status){
return true;
},
);
_dio = Dio(options);
_dio.interceptors.add(AuthInterceptor());
if (!Constant.inProduction){
_dio.interceptors.add(LoggingInterceptor());
}
_dio.interceptors.add(AdapterInterceptor());
_dio.interceptors.add(CookieManager(
PersistCookieJar(dir:StorageManager.cookieDirectory.path+"/.cookies/")));
}
Future<BaseEntity<T>> _request<T>(String method, String url, {
dynamic data, Map<String, dynamic> queryParameters,
CancelToken cancelToken, Options options
}) async {
var response = await _dio.request(url, data: data, queryParameters: queryParameters, options: _checkOptions(method, options), cancelToken: cancelToken);
try {
Map<String, dynamic> _map = Constant.isTest ? parseData(response.data.toString()) : await compute(parseData, response.data.toString());
return BaseEntity.fromJson(_map);
}catch(e){
print(e);
return BaseEntity(ExceptionHandle.parse_error, "网络错误,请重试!", null);
}
}
Options _checkOptions(method, options) {
if (options == null) {
options = new Options();
}
options.method = method;
return options;
}
Future requestNetwork<T>(Method method, String url, {
Function(T t) onSuccess,
Function(List<T> list) onSuccessList,
Function(int code, String msg) onError,
dynamic params, Map<String, dynamic> queryParameters,
CancelToken cancelToken, Options options, bool isList : false
}) async {
String m = _getRequestMethod(method);
return await _request<T>(m, url,
data: params,
queryParameters: queryParameters,
options: options,
cancelToken: cancelToken).then((BaseEntity<T> result){
if (result.code == 200){
if (isList){
if (onSuccessList != null){
onSuccessList(result.listData);
}
}else{
if (onSuccess != null){
onSuccess(result.data);
}
}
}else{
_onError(result.code, result.message, onError);
}
}, onError: (e, _){
_cancelLogPrint(e, url);
NetError error = ExceptionHandle.handleException(e);
_onError(error.code, error.msg, onError);
});
}
asyncRequestNetwork<T>(Method method, String url, {
Function(T t) onSuccess,
Function(List<T> list) onSuccessList,
Function(int code, String msg) onError,
dynamic params, Map<String, dynamic> queryParameters,
CancelToken cancelToken, Options options, bool isList : false
}){
String m = _getRequestMethod(method);
Observable.fromFuture(_request<T>(m, url, data: params, queryParameters: queryParameters, options: options, cancelToken: cancelToken))
.asBroadcastStream()
.listen((result){
if (result.code == 200){
if (isList){
if (onSuccessList != null){
onSuccessList(result.listData);
}
}else{
if (onSuccess != null){
onSuccess(result.data);
}
}
}else{
_onError(result.code, result.message, onError);
}
}, onError: (e){
_cancelLogPrint(e, url);
NetError error = ExceptionHandle.handleException(e);
_onError(error.code, error.msg, onError);
});
}
_cancelLogPrint(dynamic e, String url){
if (e is DioError && CancelToken.isCancel(e)){
Log.i("取消请求接口: $url");
}
}
_onError(int code, String msg, Function(int code, String mag) onError){
if (code == null){
code = ExceptionHandle.unknown_error;
msg = "未知异常";
}
Log.e("接口请求异常: code: $code, msg: $msg");
if (onError != null) {
onError(code, msg);
}
}
String _getRequestMethod(Method method){
String m;
switch(method){
case Method.get:
m = "GET";
break;
case Method.post:
m = "POST";
break;
case Method.put:
m = "PUT";
break;
case Method.patch:
m = "PATCH";
break;
case Method.delete:
m = "DELETE";
break;
case Method.head:
m = "HEAD";
break;
}
return m;
}
}
Map<String, dynamic> parseData(String data){
return json.decode(data);
}
enum Method {
get,
post,
put,
patch,
delete,
head
}
dio请求拦截器intercept.dart
class AuthInterceptor extends Interceptor{
@override
onRequest(RequestOptions options) {
String dn = DeviceManager.getDeviceName();
String dt = DeviceManager.getDeviceType();
String av = DeviceManager.getAppVersion();
String os = DeviceManager.getDeviceVersion();
String rdi = "DT="+dt+";"+"DN="+dn+";"+"AV="+av+";"+"OS="+os;
options.contentType = "application/x-www-form-urlencoded";
options.headers = {"RDI":rdi};
return super.onRequest(options);
}
}
class LoggingInterceptor extends Interceptor{
DateTime startTime;
DateTime endTime;
@override
onRequest(RequestOptions options) {
startTime = DateTime.now();
Log.d("----------Start----------");
Log.i("RequestUrl: " + options.baseUrl + options.path);
Log.d("queryParameters: ${Transformer.urlEncodeMap(options.queryParameters)}");
Log.d("RequestMethod: " + options.method);
Log.d("RequestHeaders:" + options.headers.toString());
return super.onRequest(options);
}
@override
onResponse(Response response) {
endTime = DateTime.now();
int duration = endTime.difference(startTime).inMilliseconds;
if (response.statusCode == ExceptionHandle.success){
Log.d("ResponseCode: ${response.statusCode}");
}else {
Log.e("ResponseCode: ${response.statusCode}");
}
Log.json(response.data.toString());
Log.d("----------End: $duration 毫秒----------");
return super.onResponse(response);
}
@override
onError(DioError err) {
Log.d("----------Error-----------");
return super.onError(err);
}
}
class AdapterInterceptor extends Interceptor{
static const String msg = "msg";
static const String slash = "\"";
static const String message = "message";
static const String defaultText = "\"无返回信息\"";
static const String notFound = "未找到查询信息";
static const String failureFormat = "{\"code\":%d,\"message\":\"%s\"}";
static const String successFormat = "{\"code\":0,\"data\":%s,\"message\":\"\"}";
@override
onResponse(Response response) {
return super.onResponse(response);
}
@override
onError(DioError err) {
if (err.response != null){
adapterData(err.response);
}
return super.onError(err);
}
Response adapterData(Response response){
String result;
String content = response.data == null ? "" : response.data.toString();
if (response.statusCode == ExceptionHandle.success || response.statusCode == ExceptionHandle.success_not_content){
if (content == null || content.isEmpty){
content = defaultText;
}
result = sprintf(successFormat, [content]);
response.statusCode = ExceptionHandle.success;
}else{
if (response.statusCode == ExceptionHandle.not_found){
result = sprintf(failureFormat, [response.statusCode, notFound]);
response.statusCode = ExceptionHandle.success;
}else {
if (content == null || content.isEmpty){
result = content;
}else {
String msg;
try {
content = content.replaceAll("\\", "");
if (slash == content.substring(0, 1)){
content = content.substring(1, content.length - 1);
}
Map<String, dynamic> map = json.decode(content);
if (map.containsKey(message)){
msg = map[message];
}else if(map.containsKey(msg)){
msg = map[msg];
}else {
msg = "未知异常";
}
result = sprintf(failureFormat, [response.statusCode, msg]);
if (response.statusCode == ExceptionHandle.unauthorized){
response.statusCode = ExceptionHandle.unauthorized;
}else {
response.statusCode = ExceptionHandle.success;
}
} catch (e) {
Log.d("异常信息:$e");
result = sprintf(failureFormat, [response.statusCode, "服务器异常(${response.statusCode})"]);
}
}
}
}
response.data = result;
return response;
}
}
由于使用了MVP的设计模式,所以进一步封装在了basePresenter中
void asyncRequestNetwork<T>(Method method, {@required String url, bool isShow : true, bool isClose: true, Function(T t) onSuccess, Function(List<T> list) onSuccessList, Function(int code, String msg) onError,
dynamic params, Map<String, dynamic> queryParameters, CancelToken cancelToken, Options options, bool isList : false}){
if (isShow) view.showProgress();
DioUtils.instance.asyncRequestNetwork<T>(method, url,
params: params,
queryParameters: queryParameters,
options: options,
cancelToken: cancelToken?? _cancelToken,
isList: isList,
onSuccess: (data){
if (isClose) view.closeProgress();
if (onSuccess != null) {
onSuccess(data);
}
},
onSuccessList: (data){
if (isClose) view.closeProgress();
if (onSuccessList != null) {
onSuccessList(data);
}
},
onError: (code, msg){
_onError(code, msg, onError);
}
);
}
_onError(int code, String msg, Function(int code, String msg) onError){
view.closeProgress();
if (code != ExceptionHandle.cancel_error){
view.showToast(msg);
}
if (onError != null && view.getContext() != null) {
onError(code, msg);
}
}