【发布时间】:2020-12-23 00:43:15
【问题描述】:
您好,我正在尝试创建一个非常基本的颤振应用程序,该应用程序从我的桌面拍摄照片并通过 HTTP.POST(作为多部分文件)将其发送到我的服务器。我一直在使用dio 来尝试这个,但由于某种原因,我的服务器一直在声明'image' is not present。我尝试调试帖子代码,图像显示在日志中(base64 等)。我在 PostMan 中尝试了这个并且成功了,虽然我得到了一个 POST http://localhost:8080/event/test 500 说 Required request part 'image' is not present。
这是我尝试使用的图像:
这是我测试过的一些数据是否为 null 或无效,在我创建 FormData 后它似乎恢复为有效:
print(formData.fields.last.key); // image
print(formData.fields.last.value); // Instance of 'MultipartFile'
print(formData.fields.last.value.length); // 27
print(formData.fields.last.value.isEmpty); // false
这是我的颤振代码:
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:flutter/material.dart';
import 'package:http_parser/http_parser.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
FilePickerCross filePickerCross;
String _fileString = '';
Set<String> lastFiles;
FileQuotaCross quota = FileQuotaCross(quota: 0, usage: 0);
@override
void initState() {
FilePickerCross.listInternalFiles()
.then((value) => setState(() => lastFiles = value.toSet()));
FilePickerCross.quota().then((value) => setState(() => quota = value));
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: Colors.blueGrey, accentColor: Colors.lightGreen),
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: ListView(
padding: EdgeInsets.all(8),
children: <Widget>[
Text(
'Last files',
style: Theme.of(context).textTheme.headline5,
),
(lastFiles == null)
? Center(
child: CircularProgressIndicator(),
)
: ListView.builder(
shrinkWrap: true,
primary: false,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) => ListTile(
leading: Text('$index.'),
title: Text(lastFiles.toList()[index]),
onTap: () async => setFilePicker(
await FilePickerCross.fromInternalPath(
path: lastFiles.toList()[index])),
),
itemCount: lastFiles.length,
),
RaisedButton(
onPressed: _selectFile,
child: Text('Open File...'),
),
(filePickerCross == null)
? Text('Open a file first, to save')
: RaisedButton(
onPressed: _selectSaveFile,
child: Text('Save as...'),
),
Text(
'File system details',
style: Theme.of(context).textTheme.headline5,
),
Text('Quota: ${(quota.quota / 1e6).round()} MB'),
Text(
'Usage: ${(quota.usage / 1e6).round()}; Remaining: ${(quota.remaining / 1e6).round()}'),
Text('Percentage: ${quota.relative.roundToDouble()}'),
Text(
'File details',
style: Theme.of(context).textTheme.headline5,
),
Text(
'File path: ${filePickerCross?.path ?? 'unknown'} (Might cause issues on web)\n'),
Text('File length: ${filePickerCross?.length ?? 0}\n'),
Text('File as String: $_fileString\n'),
],
),
),
);
}
void _selectFile() {
FilePickerCross.importFromStorage()
.then((filePicker) => setFilePicker(filePicker));
}
void _selectSaveFile() {
filePickerCross.exportToStorage();
}
setFilePicker(FilePickerCross filePicker) => setState(() {
filePickerCross = filePicker;
filePickerCross.saveToPath(path: filePickerCross.fileName);
FilePickerCross.quota().then((value) {
print(value);
setState(() => quota = value);
});
lastFiles.add(filePickerCross.fileName);
try {
_fileString = filePickerCross.toString();
} catch (e) {
_fileString = 'Not a text file. Showing base64.\n\n' +
filePickerCross.toBase64();
Upload(filePickerCross);
}
});
Future<void> Upload(FilePickerCross file) async {
Dio dio = new Dio();
try{
FormData formData = new FormData.fromMap({"image":
file.toMultipartFile()});
print(formData.fields.last.key);
print(formData.fields.last.value);
print(formData.fields.last.value.length);
print(formData.fields.last.value.isEmpty);
Response response = await dio.post("http://localhost:8080/event/test",data:formData, options: Options(
headers: {
"accept" : "*/*",
// "Authorization" : "TOKEN",
"Content-Type" : "multipart/form-data",
}
));
print(response);
print("d");
}catch(e){
}
}
}
这就是我对 Post man 感到厌倦的地方:
最后这是我的服务器代码:
@PostMapping(value = "/test")
@ApiOperation(value = "add an event data via the body ")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = ResponseModel.class)})
public ResponseEntity<?> post(@RequestPart("image") MultipartFile image) {
ResponseModel responseModel;
System.out.println(image.getName());
int responseNumber = 0;
String res = response(responseNumber);
if (responseNumber != 0) {
responseModel = new ResponseModel(false, responseNumber, res);
} else {
responseModel = new ResponseModel(true, responseNumber, res);
}
return new ResponseEntity<>( responseModel, HttpStatus.OK);
}
【问题讨论】:
-
请不要发图片。您应该改为发布代码和请求正文。请编辑它
-
唯一的请求正文是邮递员图像中看到的表单数据
-
您是否尝试过将其作为图像而不是多部分数据发布?
-
@JacksonLee wdym 像 json 或类似的东西?
-
@JacksonLee 我尝试在没有 MultipartFile 的情况下发帖,而是使用了字符串,但我仍然遇到同样的问题
标签: spring flutter dart xmlhttprequest flutter-web