How to upload picture in Spring and Angular2 - spring

I want to upload picture in my app this is my Angular 2 code
constructor () {
this.progress = Observable.create(observer => {
this.progressObserver = observer
}).share();
}
public makeFileRequest (url: string, params: string[], files: File[]):
Observable<any> {
return Observable.create(observer => {
let formData: FormData = new FormData(),
xhr: XMLHttpRequest = new XMLHttpRequest();
for (let i = 0; i < files.length; i++) {
formData.append("uploads[]", files[i], files[i].name);
}
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
observer.next(JSON.parse(xhr.response));
observer.complete();
} else {
observer.error(xhr.response);
}
}
};
xhr.upload.onprogress = (event) => {
this.progress = Math.round(event.loaded / event.total * 100);
this.progressObserver.next(this.progress);
};
xhr.open('POST', url, true);
xhr.send(formData);
});
}
And this is my spring controller
#RequestMapping(value = "/upload", method = RequestMethod.POST)
#ResponseBody
public ResponseEntity<?> uploadFile(
#RequestParam("file") MultipartFile uploadfile) {
try {
// Get the filename and build the local file path (be sure that the
// application have write permissions on such directory)
String filename = uploadfile.getOriginalFilename();
String directory = "/assets/images";
String filepath = Paths.get(directory, filename).toString();
// Save the file locally
BufferedOutputStream stream =
new BufferedOutputStream(new FileOutputStream(new File(filepath)));
stream.write(uploadfile.getBytes());
stream.close();
}
catch (Exception e) {
System.out.println(e.getMessage());
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<>(HttpStatus.OK);
}
And I get this error
ERROR {"timestamp":1498220487868,"status":400,"error":"Bad Request","exception":"org.springframework.web.multipart.support.MissingServletRequestPartException","message":"Required request part 'file' is not present","path":"/webapp/api/picture/upload"}

You specify #RequestParam("file"), which means Spring waits for an argument with the key file, but you append your data with the key uploads.
Also, as said by #ledniov, your are receiving an array of multipart files, not only one.
Corrections if you want to use the key file:
// Front-End: change "uploads" to "file"
formData.append("file[]", files[i], files[i].name);
// Back-End: takes a MultipartFile array
#RequestParam("file") MultipartFile[] uploadfile
Corrections if you want to use the key uploads:
// Back-End: change "file" to "uploads" and takes a MultipartFile array
#RequestParam("uploads") MultipartFile[] uploadfile

Related

How to pass file in Wep API in asp.net core 2.2

I want to pass file in web api
Controller:
[HttpPost]
public IActionResult Upload(IFormFile file)
{
string d = file.FileName;
//string contents = JsonConvert.SerializeObject(d);
using (HttpResponseMessage response = objAPI.CallAPIGet("/BusinessProfile/saveFolder", d))
{
if (response.IsSuccessStatusCode)
{
string responseString = response.Content.ReadAsStringAsync().Result;
if (!string.IsNullOrEmpty(responseString))
{
}
}
}
return Ok();
}
Web Api:
[HttpPost]
[Route("saveFolder")]
public IActionResult WriteFile(IFormFile file)
{
string fileName;
try
{
var extension = "." + file.FileName.Split('.')[file.FileName.Split('.').Length - 1];
//fileName = Guid.NewGuid().ToString() + extension; //Create a new Name
fileName = file.FileName;
var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot\\BProfileFile", fileName);
using (var bits = new FileStream(path, FileMode.Create))
{
file.CopyToAsync(bits);
}
}
catch (Exception ex)
{
throw ex;
}
return Ok(fileName);
}
from UI to web api method is not heat. the error is
Unsupported Media Type.
How to solve this error.

Sending file object to Spring Rest controller through angular 5

I am trying to upload a file on client side and send HTTP Post request to Spring Rest Controller. But when I receive the file object in Rest controller I could see it as 'null'.
HTML code :
<input type="file" id="myFile" (change) = "onFileChange($event)" #fileInput>
Corresponding .ts file :
onFileChange($event) : void {
let file:File = $event.target.files[0];
let myReader: FileReader = new FileReader();
myReader.onloadend = function(e) {
}
myReader.readAsText(file);
const req = this.http.post('/abc',myReader.result, {
headers: new HttpHeaders().set('content-type','application/pdf')
});
req.subscribe(
(data) => {
console.log(data);
},
(err: HttpErrorResponse) => {
if(err.error instanceof Error) {
//client side error
console.log('An error occured: ',err.error.message);
} else {
console.log('Backend returned code', err.status, 'body was ',err.error);
}
}
)
}
My Spring Rest Controller :
#RequestMapping(value="/abc", method = RequestMethod.POST, consumes = "application/pdf")
public ResponseEntity<String> uploadFile(#RequestBody MultipartFile file) {
System.out.println("Inside Controller");
return new ResponseEntity<>("true", HttpStatus.CREATED);
}
Could anyone please help to find out the issue here.
Try below code
HTML Template
<input type="file" id="myFile" (change)="onFileChange(fileInput.files)" #fileInput>
TypeScript
import { Headers, RequestOptions } from '#angular/http'; // Import header and requestOptions
//On File Select
onFileChange(files: any) {
let file: File = files[0];
let headers = new Headers();
let options = new RequestOptions({ headers: headers }); // Create header
let formData = new FormData();
formData.append('file', file); // Append file to formdata
const req = this.http.post('/abc', formData, options);
req.subscribe( (data) => {
console.log(data); // Sucess response
}, (err: HttpErrorResponse) => {
// Erro response
if(err.error instanceof Error) {
//client side error
console.log('An error occured: ',err.error.message);
}
else {
console.log('Backend returned code', err.status, 'body was ',err.error);
}
})
}
Spring Controller
#RequestMapping(value="/abc", method = RequestMethod.POST)
public ResponseGenerator uploadFile(#RequestParam MultipartFile file) {
ResponseGenerator responseGenerator = new ResponseGenerator();
try {
if (file != null) {
System.out.println(file.getOriginalFilename());
}
return responseGenerator;
} catch (Exception e) {
logger.error("Error while updating user : ", e);
return responseGenerator;
}
}
It will be better way if you create one service and put your http method code in that service. refer this link Angular 2 template form with input type=file and spring boot
the easiest thing to do (according to me) is to use a FormData object.
Here is how :
#viewChild() fileInput: ElementRef;
onFileChange(event) {
const files = this.fileInput.nativeElement.files as FileList;
const file = files.item(0);
const formData = new FormData();
formData.append('pdf', file, file.name);
this.http.post('abc', formData, {
headers: new HttpHeaders().set('content-type','application/pdf')
}).subscribe(
data => console.log(data),
err => console.log(err)
);
}
Try this and tell me what you see on Spring side.

Bad request when trying to upload file in angular 2 using spring as backend

Hello i am trying to upload a file immediately when selected. i am getting a bad request 400.
Failed to load resource: the server responded with a status of 400 (Bad Request)
My codes are below.
<input type="file" (change)="fileChange($event)" placeholder="Upload file" >
fileChange(event) {
let fileList: FileList = event.target.files;
if(fileList.length > 0) {
let file: File = fileList[0];
let formData:FormData = new FormData();
formData.append('uploadFile', file, file.name);
let headers = new Headers();
headers.append('Content-Type', 'multipart/form-data;boundary=gc0p4Jq0M2Yt08jU534c0p');
headers.append('Accept', 'application/json');
let options = new RequestOptions({ headers: headers });
alert(ConnectionHelper.SERVER_URL
+ConnectionHelper.MEDIACHANNEL+ConnectionHelper.UPLOADFILE)
this._http.post(ConnectionHelper.SERVER_URL
+ConnectionHelper.MEDIACHANNEL+ConnectionHelper.UPLOADFILE, formData,options)
.subscribe(
data => console.log('success'),
error => console.log(error)
)
}
}
Spring controller
#RequestMapping(value = "/api/mediaChannel/logoUpload", method = RequestMethod.POST)
#ResponseBody
public String logoUpload(#RequestParam("fileUpload") MultipartFile file,HttpServletResponse res, MultipartHttpServletRequest req) {
WebUtil wu = new WebUtil(res, req);
wu.allowCrossSiteMessages();
if (file.isEmpty()) {
}
try {
// Get the file and save it somewhere
byte[] bytes = file.getBytes();
Path path = Paths.get("images\\" + file.getOriginalFilename());
Files.write(path, bytes);
} catch (IOException e) {
e.printStackTrace();
}
return "successfull";
}
Hi you cannot able upload file using http post,instead of you need use xhr request
fileChange(event) {
let fileList: FileList = event.target.files;
if(fileList.length > 0) {
let file: File = fileList[0];
return new Promise((resolve, reject) => {
let formData: any = new FormData();
let xhr = new XMLHttpRequest();
formData.append('uploadFile', file, file.name);
xhr.open('POST', url, true);
xhr.setRequestHeader('Authorization', 'JWT ' + localStorage.getItem('id_token'));//If you need pass authentication token
xhr.send(formData);
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
resolve(JSON.parse(xhr.responseText));
}
}
});
}
}

Angular2 to Asp.net Core Webapi IFormFile is null

I am using angular2 with asp.net core webapi. Using the following code to send file information. IFormFile is always null. I have used same name in post input and in api method parameter, still no luck. Please help me.
FormData
this.formData.append("file", f,f.name);
Component method
public UploadFiles() {
console.log("Form Data:" + this.formData);
let saved: boolean = false;
this.claimsService
.UploadFiles(this.formData)
.subscribe(data => {
saved = data;
}, error => {
console.log(error)
swal(error);
})
}
Service Method
UploadFiles(data: FormData): Observable<boolean> {
return this.ExecuteFilePost("Upload/Upload", data);
}
Base Service Method:
public ExecuteFilePost(action: string, data: FormData) {
let _body = data;
let headers = new Headers({ 'Content-Type': undefined});
let url = this._baseUrl + action;
let requestoptions: RequestOptions = new RequestOptions({
headers: headers,
});
console.log('req url:' + url);
return this.http.post(url,_body,requestoptions)
.share()
.map((res: Response) => {
if (res.status < 200 || res.status >= 300) {
throw new Error('This request has failed ' + res.status);
}
else {
return res.json();
}
});
}
WebApi Method
[HttpPost]
[ActionName("Upload")]
public async Task Upload(IFormFile file)
{
var uploads = Path.Combine(_environment.WebRootPath, "uploads");
// foreach (var file in files)
// {
if (file.Length > 0)
{
using (var fileStream = new FileStream(Path.Combine(uploads, file.FileName), FileMode.Create))
{
await file.CopyToAsync(fileStream);
}
}
// }
}
Chrome request screens
enter image description here
I know the post is old, but maybe for others. You can do things like this:
HTML:
<input #fileInput type="file" multiple />
<button (click)="addFile()">Add</button>
Component:
#ViewChild("fileInput") fileInput;
addFile(): void {
let fi = this.fileInput.nativeElement;
if (fi.files) {
let fileToUpload = fi.files;
this.settingsService
.upload(fileToUpload)
.subscribe(res => {
console.log(res);
});
}
}
Service:
upload(files: any) {
let formData = new FormData();
for (let i = 0; i < files.length; i++) {
formData.append("files", files[i]);
}
return this.http
.post(fileUploadApi, formData)
.map(response => this.extractData(response as Response))
.catch(error => this.httpErrorHandlerService.responseError(error));
}
Web API
[HttpPost]
[Route("Upload")]
public IActionResult UploadFiless([FromForm] IFormFileCollection files)
{
try
{
return this.Ok();
}
catch (Exception)
{
return this.BadRequest();
}
}

How can I upload a file in MVC 6 web api2 using angularjs(formData)

I am trying to upload file using formdata object create in angularjs
var formdata = new FormData();
formdata.append("imagefile", file)
$http.post('api/upload', formdata, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } });
want code for c# controller code using webapi2 in mvc 6
var fd = new FormData();
fd.append('file', $scope.teamLogo);
fd.append('aa', 'a');
$http.post('http://localhost:51815/api/upload/', fd, {
transformRequest: saangular.identity,
headers: { 'Content-Type': undefined }
}).then(function (teamList) { });
in Controller
public async Task<HttpResponseMessage> PostFormData()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
try
{
// Read the form data.
await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the file names.
foreach (MultipartFileData file in provider.FileData)
{
// Trace.WriteLine(file.Headers.ContentDisposition.FileName);
//Trace.WriteLine("Server file path: " + file.LocalFileName);
}
return Request.CreateResponse(HttpStatusCode.OK);
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
use this code in js file

Resources