Uploading document from angularjs to springboot - angularjs

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 :-)

Related

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;
}

uploading files using angularjs and spring boot

I have an angularjs application deployed in a server, and a spring boot application deployed in another server.
in my angularjs application I have a form that uploads a file and send it via a rest controller, this controller then saves this file inside a folder in the server where the spring boot application is deployed.
this is my rest controller :
#CrossOrigin(origins="*")
#RestController
public class Upload {
#RequestMapping(value="/imageUpload", method = RequestMethod.POST)
public void UploadFile(MultipartHttpServletRequest request) throws IOException {
Iterator<String> itr=request.getFileNames();
MultipartFile file=request.getFile(itr.next());
String fileName=file.getOriginalFilename();
File dir = new File("C:\\file");
if (dir.isDirectory())
{
File serverFile = new File(dir,fileName);
BufferedOutputStream stream = new BufferedOutputStream(
new FileOutputStream(serverFile));
stream.write(file.getBytes());
stream.close();
}else {
System.out.println("not");
}
}
}
and this my angularjs controller which sends the file :
$scope.validerOffre= function(){
var file = $scope.fileUpload;
var uploadUrl = "/imageUpload";
fileUploadService.uploadFileToUrl(file, uploadUrl);
};
this controller then call the fileUploadService :
capValueRecruitApp.service('fileUploadService', function ($http) {
this.uploadFileToUrl = function(file, uploadUrl){
var fd = new FormData();
fd.append('file', file);
$http.post('http://localhost:8080' + uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
})
.error(function(){
});
}
});
and in my angularjs application I want to display the files that I uploaded but I cant do that since the files were uploaded in the spring boot application server, which is another server .
so my question is how can I save the files that I uploaded in a folder in the angularjs application server instead of the server where the spring boot application is deployed.
You basically have two solutions :
1: you create a new #RequestMapping that takes the filename ( or even better an id returned by your fileUpload controller) and that returns the file.
something like this :
#RequestMapping(value="/imageDownload", method = RequestMethod.POST)
public void downloadFile(#RequestParam(value = "fileName", required = true) String fileName,HttpServletResponse response) throws IOException {
File dir = new File("C:\\file");
File fileToDownload = new File(dir,fileName);
if (dir.isDirectory() && fileToDownload.exists()){
//read fileToDownload and send stream to to response.getOutputStream();
}else {
System.out.println("no such file "+ fileToDownload.toString());
response.sendError(404);
return;
}
}
Then you call http://localhost:8080/imageDownload?filename=yourUploadedFile.jpg
2: When you save the file in your upload, save it somewhere where your webserver has direct access.
If our angularjs files are served by your spring application, you could add a new folder in spring.resources.staticLocations in the application.properties file. (see this : http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-web-applications.html#boot-features-spring-mvc-static-content )

Download MS Excel/Word via AngularJS call to a REST service

I have an AngularJS application that sends a POST request to a REST service (onClick method of a button). The POST request contains a JSON object with various settings. The REST service uses those settings to create a MS Word/Excel file.
At the moment the REST service sends the contents of the file back as a byte stream (in response to the previously mentioned POST request). When the file arrives I want a save-file-dialog to show up, where I can save the file. The backend is a Spring Boot app using Spring-MVC.
Can this be done in AngularJS?
If you can't use something like location.href to get your data to the server instead of post it, then check it out others using html 5:
more info AngularJS $http-post - convert binary to excel file and download
$http({
url: 'your/webservice',
method: 'POST',
responseType: 'arraybuffer',
data: json, //this is your json data string
headers: {
'Content-type': 'application/json',
'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
}
}).success(function(data){
var blob = new Blob([data], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
saveAs(blob, 'File_Name_With_Some_Unique_Id_Time' + '.xlsx');
}).error(function(){
//Some error log
});
This is the Controller function I ended up using:
#RequestMapping(value = "/downloadDocx", method = RequestMethod.POST)
#ResponseStatus(value = HttpStatus.CREATED)
public void downloadDocx(#RequestBody DocxInputBean docxInput,
HttpServletResponse response) throws Exception {
File docxFile = outputManager.createDocxProfile(docxInput);
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
InputStream is = new FileInputStream(docxFile);
org.apache.commons.io.IOUtils.copy(is, response.getOutputStream());
response.flushBuffer();
is.close();
}

Bad Request Error while sending json data to spring mvc controller

I am trying to send some json data from angular ng grid to spring mvc controller,but i am getting error as 400 (Bad request) The request sent by the client was syntactically incorrect. .
This is my Request Paylod:
[{"orderId":1,"orderTitle":"Xcel","orderDetail":"cash","orderType":"Xcel","orderPriority":"22.0","retailerId":0,"orderRefno":"9.900499743E9","customerName":"high","customerContactno":"pen drive","customerEmailId":"nutral","paymentType":"iffu#gmail.com","orderStatus":"pen drive","reciptDate":null,"bayNumber":"Xcel","deliveredDate":null,"deliveredBy":"Irfan","updatedOn":null,"pudoOutlet":null,"retailer":null,"outletId":0}]
here is my spring mvc controller:
#RequestMapping(value="/createorder",method=RequestMethod.POST,headers="Content-Type=application/json")
public #ResponseBody ModelAndView createOrder(#RequestBody Order order){
System.out.println("hiiiii"+order);
try{
orderDao.createOrder(order);
return new ModelAndView("product1.html");
}
catch(Exception e)
{
System.out.println(e);
}
return new ModelAndView("pr.html");
}
here is my angular controller from where i am posting:
$scope.save = function() {
console.log("hii inside save function");
console.log($scope.mySelections);
console.log("after myselection")
var d=$scope.mySelections;
console.log("hhhhh" +d);
$http({
method: 'POST',
url: './createorder',
headers: {'Content-Type': 'application/json'},
data:d
}).success(function (data)
{
$scope.status=data;
});
};
I am totally confused why i am getting this error ? Is it because i am sending some null values to spring mvc controller ? if yes how to solve this issue ?
Is Order an inner class? If so, try taking that class into its own file. Worked for me.

Download file using angular js by calling spring rest api

I have a Spring Controller which send file in response
#RequestMapping(value = "/downloadData", method = RequestMethod.GET)
public void downloadData(HttpServletResponse response) throws IOException
{
File dataJSONFile = dataDownloadService.createAndWriteFile();
response.setContentType("application/text");
response.setContentLength(new Long(dataJSONFile.length()).intValue());
response.setHeader("Content-Disposition", "attachment; filename="data.json");
FileCopyUtils.copy(new FileInputStream(dataJSONFile),
response.getOutputStream());
}
If I write in browser url, //localhost:8080/myproject/rest/downloadData It downloads the file.
Now, want to download the file when click on button in using angular js.
I have written following code in angular js to download file
angular
.module('myApp.services')
.factory(
'DataDownloadService',
function($resource) {
"use strict";
return {
"query" : function() {
var ret, restResource;
restResource = $resource(
'/sand-pp/api/rest/downloadData',
{}, {
"query" : {
"method" : "GET",
"isArray" : true,
headers:
{
'Content-Type': 'application/text',
'Content-Disposition': 'attachment; filename=data.json'
}
}
});
ret = restResource.query();
return ret;
}
};
});
When I call above service nothing is happening but if I print data in callback function is printing data in console.
How to download file in angular js by calling Spring REST api?
I would use a service for the rest call. Try this following:
window.location.href = DataDownloadService.query();
It should prompt the browser to download the file (because of Content-Disposition header).

Resources