React upload a file to spring controller - reactjs

We have a Java spring-boot based server and a react JS UI app.
And we need to implement a file upload from the react app to the server.
Server controller code:
#RequestMapping(value = "/aaa/{id}/upload", method = RequestMethod.PUT, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Object uploadFile(#PathVariable("id") Integer id, #RequestParam("file") MultipartFile file, HttpServletRequest request) {
...
logic
...
}
With postman, we can upload the file successfully. We can't do it via the react JS app.
This is react JS upload file code:
uploadFile(file, type) {
const formData = new FormData();
formData.append('file', file);
return axios.put(`aaa/1/upload`, file, {
headers: {
'content-type': 'multipart/mixed; boundary=--ABC123Boundary'
}
})
.then(() => {
NotificationsManager.info('File successfully uploaded.')
})
.catch((err) => {
NotificationsManager.error(err.message, `Error in uploading file`);
});
}
We tried with boundary, without boundary, with default boundary... nothing works.
UPDATE: We get this error:
"Bad Request"
exception:
"org.springframework.web.multipart.support.MissingServletRequestPartException"
message:"Required request part 'file' is not present"
What did we do wrong?
Regards,
Ido

Related

Getting bad request from server (Spring boot) when using axios request

I'm currently stuck sending a request to my server and can not get a response. I have tried it on postman and it runs completely fine. However, when I try to put it on react, the back-end always response with a bad request.
Here is my code for the back-end
#GetMapping(value = "/searchPatient")
public ResponseEntity<?> searchPatients(#RequestParam String id_num,
#RequestParam String name) {
List<PatientForSearchDto> patientForSearchDtos = patientService.viewSearchedPatient(id_num, name);
return ResponseEntity.status(HttpStatus.OK).body(
new ResponseObject("ok", "Success", patientForSearchDtos)
);
}
Here is my code for Front end (react)
async function sendRequest () {
const formData = new FormData();
formData.append('id_num', id_num);
formData.append('name', name);
console.log(formData)
console.log(formData.get('name'))
console.log(formData.get('id_num'))
const config = {
method: 'get',
url: 'http://localhost:8080/api/searchPatient',
// headers : {
// 'Content-Type': 'from-data'
// },
data : formData
};
await axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
setPatientList(response.data.data.object)
})
.catch(function (error) {
console.log(error);
});
}
Here is what I get when sending request via postman
enter image description here
Here is when sending request using react
enter image description here
From the Axios docs about Request Config data param:
// data is the data to be sent as the request body
// Only applicable for request methods 'PUT', 'POST', 'DELETE , and
'PATCH'
So, data with GET method is not supported.
Can't you use params instead?

React Native File Upload not working using Axios

I am trying to upload a file to the server and the server APIs are written using django. The file upload is working perfectly from Postman but when i try to upload from mobile app (React Native) using axios the backend is not able to read it.
Following is the Frontend Snippet:
let accessToken = await AsyncStorage.getItem('accessToken')
let formData = new FormData()
formData.append('doc_type', this.state.selectedDoc.id)
formData.append('document', this.state.selectedFiles) // <- This is the fetched file in array format . [{filname:'abc', size:12344,.....}]
formData.append('description', this.state.description.value)
formData.append('data', JSON.stringify(this.state.selectedDoc.fields))
let url = `${AppConstants.url}api/${AppConstants.apiVersion}/upload_doc`
var config = {
method: 'post',
url: url,
data: formData,
headers: {
'Authorization': `Bearer ${accessToken}`,
}
}
axios(config)
.then((resp) => {
resolve(resp)
})
.catch((err) => {
reject(err)
});
And the backend-end if else statement is as follows:
if(request.FILES.getlist("document")):
files = request.FILES.getlist("document")
....
....
....
else:
return response.JsonResponse({
'success' : False,
'message' : 'Please Upload a file'
}, status = status.HTTP_200_OK)
The above else block is executed even though the UI is sending a valid file.
Request you to please share a solution.

unable to upload file from my react application

I want to need upload file from react application to backend.
my upload handle function is:
handleupload(info) {
this.setState({ 'selectedFiles': info.fileList });
}
But we are unable to send file data to server.
we are using axios:
export async function saveApplication(applicationData) {
return http.post(
getJobsEndPoint+"/store-application",
applicationData,
{
headers: { "Content-Type": "multipart/form-data" },
}
);
}
But stil unable to get request on my backend controller, we are getting all input type in my backend controller. But still unable to find file object.
Please help me any buddy for regarding same.

Uploading document from angularjs to springboot

Angularjs $http.post gives a 404 exception but all the other methods works fine with the same codes, i am trying to upload a file via spring boot
The same codes works fine in my other project i did about last year, and the same $http.post works when i send information without a file
service.js
function addCompanyDoc(file, id) {
var deferred = $q.defer();
var data = new FormData();
data.append('file', file);
var config = {
transformRequest: angular.identity,
transformResponse: angular.identity,
headers: {
'Content-Type': undefined
}
}
console.log('appService file ');
console.dir(file); //cheking if file is available
$http.post('http://localhost:8080/listed/welcome/company/doc/' + id,
data, config)
.then(function(response) {
deferred.resolve(response.data);
},
function(errResponse) {
alert(errResponse.data.errorMessage);
console.error('Error while uploading company doc', errResponse);
this.flag = 'failed';
deferred.reject(errResponse);
});
return deferred.promise;
}
spring boot
#RequestMapping("/welcome")
public class controllers{
#RequestMapping(value = "/company/doc/{id}", method =
RequestMethod.POST, consumes = {"multipart/form-data" })
#ResponseBody
public ResponseEntity<Void> saveCompanyDoc(#RequestParam("file")
MultipartFile file, #PathVariable final int id){
//....uploading to DB
}
}
angularjs sends a document to spring boot and spring uploads to the DB / sends to a folder.
Working fine :-) with angularjs 1.7 & spring boot 2.*
Thanks for all the comments the above code is correct,
I created a dummy table and controller to test the app.
And it gave the same 404 error and i recalled a few weeks back i added an "admin folder" to handle CMS and directed all the ROLES to the "folder" and it blocked all the users from doing data POSTING. SO i just had to fix my WebSecurityConfig class :-)

How to set request part for POST request with angular-file-upload and Spring?

Unfortunately this answer does not help me. The problem appears to be that the request parameter file is not present in my POST request for some reason.
I am trying to upload a file, any file whether it's a binary file or a text file, in a POST request. The REST controller reveals:
#PostMapping(WordEmbeddingApiPaths.UPLOAD_MODEL)
#RequestMapping(method=RequestMethod.POST, headers={"Content-Type=multipart/form-data"})
public ResponseEntity<WordVectorListDto> uploadModel(
#RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) {
LOGGER.debug("POST uploadModel");
return new ResponseEntity<WordVectorListDto>((WordVectorListDto)null, HttpStatus.OK);
}
and on the client I am running:
var uploader = $scope.uploader = new FileUploader({
url: 'http://localhost:8080/rest-api/dl4j/we/uploadModel'
});
uploader.onAfterAddingFile = function($modelFile) {
console.info('onAfterAddingFile', $modelFile);
var fd = new FormData();
fd.append('file', $modelFile.file);
$http.post($modelFile.url, fd, {
headers: {
'Content-Type': 'multipart/form-data'
},
params: {'file' : $modelFile.file}
})
.then(
function (data) {
alert("upload success");
},
function (data, status) {
alert("upload error");
}
);
};
However, I am getting 400 Bad Request as server response.
Any idea what the problem is?
Update:
I saw that an internal exception got thrown on the server side stating:
org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
I thought that I am setting this already - how can I make this right?
Posting FormData with AngularJS
When doing a POST with a FormData API object, it is important to set the Content-Type header to undefined.
var fd = new FormData();
fd.append('file', $modelFile.file);
$http.post($modelFile.url, fd, {
headers: {
//'Content-Type': 'multipart/form-data'
'Content-Type': undefined
},
//params: {'file' : $modelFile.file}
})
When the XHR send() method gets a FormData object created by the FormData API it automatically sets the content type to multipart/form-data and includes the proper boundary.
By having the AngularJS framework override the content type, the boundary is not set properly.
Debugging Small Programs
This question is an example of putting several things together without debugging each part.
This question has several unknown code components:
An undebugged AngularJS POST method
An undebugged Spring Backend
An undebugged mysterious AngularJS service
This answer pointed out errors with the AngularJS POST method but there are a couple of other unknowns. Is the Spring backend working properly? Is the mysterious FileUploader service being used correctly?
Debugging involves isolating unknowns and testing them separately.
Does the Angular POST method work with a known backend such as HTTP BIN - HTTP Request & Response Service?
Does the Spring backend work with an uploader that has been tested?
For more information, see How to debug small programs.
if you are using #EnableAutoConfiguration then you need to do the following as discussed here https://github.com/spring-projects/spring-boot/issues/2958
#EnableAutoConfiguration(exclude = {MultipartAutoConfiguration.class})
define the following beans
#Bean(name = "multipartResolver")
public CommonsMultipartResolver commonsMultipartResolver(){
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setMaxUploadSize(50*1024*1024);
return resolver ;
}
#Bean
#Order(0)
public MultipartFilter multipartFilter(){
MultipartFilter multipartFilter = new MultipartFilter();
multipartFilter.setMultipartResolverBeanName("multipartResolver");
return multipartFilter;
}

Resources