I´'m trying to send a multipart request from Flutter to an API. In this multipart request there is a MultipartFile (image) and a Json object. The request works on Postman and React, so is not really a server problem. Every time I try to do the request i get a 415 error. Also the problem doesn´t seems to be from the headers.
This is the following method I´ve made in flutter:
Future<dynamic> postMultipartChetada(String url, List<XFile> files, dynamic data, String dataName) async {
late LocalStorageService _localStorageService;
GetIt.I
.getAsync<LocalStorageService>()
.then((value) => _localStorageService = value);
final request = http.MultipartRequest(
'POST',
Uri.parse(ApiConstants.baseUrl + url),
);
if(files.isNotEmpty){
for (final file in files) {
final bytes = await file.readAsBytes();
request.files.add(http.MultipartFile.fromBytes(
'file',
bytes,
filename: file.name.substring(1, 10),
));
}
}
request.fields[dataName] = jsonEncode(data.toJson());
var boundary = Uuid().v4();
final headers = {
'Authorization': 'Bearer ${_localStorageService.getFromDisk("user_token")}',
'Content-Type': 'multipart/form-data; boundary=$boundary',
"Accept": "*/*",
};
request.headers.addAll(headers);
try {
final response = await request.send();
return response;
} catch (error) {
throw new Exception("Error en el cliente");
}
}
Using the request register of SpringBoot(where the API is made) I get the following information:
2023-05-29 22:50:33.344 DEBUG 27288 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : POST "/question", parameters={multipart}
2023-05-29 22:50:33.383 DEBUG 27288 --- [io-8080-exec-10] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.triana.salesianos.HazTuHuertoAPI.controller.QuestionController#register(MultipartFile, CreateQuestion, User)
2023-05-29 22:50:33.386 DEBUG 27288 --- [io-8080-exec-10] o.s.web.method.HandlerMethod : Could not resolve parameter [1] in public org.springframework.http.ResponseEntity<com.triana.salesianos.HazTuHuertoAPI.model.dto.question.QuestionDetails> com.triana.salesianos.HazTuHuertoAPI.controller.QuestionController.register(org.springframework.web.multipart.MultipartFile,com.triana.salesianos.HazTuHuertoAPI.model.dto.question.CreateQuestion,com.triana.salesianos.HazTuHuertoAPI.model.User): Content type 'application/octet-stream' not supported
2023-05-29 22:50:33.387 DEBUG 27288 --- [io-8080-exec-10] .m.m.a.ExceptionHandlerExceptionResolver : Using @ExceptionHandler com.triana.salesianos.HazTuHuertoAPI.error.GlobalRestControllerAdvice#handleException(Exception, WebRequest)
2023-05-29 22:50:33.401 DEBUG 27288 --- [io-8080-exec-10] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json', given [*/*] and supported [application/json, application/*+json, application/json, application/*+json]
2023-05-29 22:50:33.413 DEBUG 27288 --- [io-8080-exec-10] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [ApiErrorImpl(status=415 UNSUPPORTED_MEDIA_TYPE, message=Content type 'application/octet-stream' not (truncated)...]
2023-05-29 22:50:33.416 DEBUG 27288 --- [io-8080-exec-10] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/octet-stream' not supported]
2023-05-29 22:50:33.417 DEBUG 27288 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : Completed 415 UNSUPPORTED_MEDIA_TYPE
I suppose the error is that is not detecting well the Content-Type header, but i´m not sure if its the Conten-Type of the whole request or just for one of the fields and no idea of how to fix it.
final String _baseURL="baseurlhere";
final http.Client _client=http.Client();
Map<String,String> _headers(){
Map<String,String> headers={
'Content-Type':'application/json'
};
if(Global.isLogged){
headers['Authorization']='Bearer ${Global.user['token']}';
}
return headers;
}
void postMultipart({
required String endpoint,
Map body=const{},
Map<String,File> files=const{},
required Function(Map response) onSuccess,
required Function(Map response)onError
})async{
try{
final http.MultipartRequest multipartRequest= http.MultipartRequest('POST',Uri.parse(_baseURL+endpoint));
multipartRequest.headers.addAll(_headers());
body.forEach((key, value) {
multipartRequest.fields[key]=value;
});
files.forEach((key,file) async{
var multipartFile= await http.MultipartFile.fromPath(key,file.path);
multipartRequest.files.add(multipartFile);
});
final http.StreamedResponse streamedResponse=await multipartRequest.send();
final http.Response response=await http.Response.fromStream(streamedResponse);
_handleResponse(response: response,onSuccess: onSuccess, onError: onError);
}on http.ClientException catch(e) {
onError({"error":e.message});
}catch(e){
onError({"error":e.toString()});
}
}