无法在Angular + Spring Boot应用程序中一次性上传多个文件。

huangapple go评论66阅读模式
英文:

unable to upload multiple files at once in angular + spring boot app

问题

以下是您提供的代码的翻译:

HTML代码:

<label>
    欢迎 {{name}},欢迎来到新应用。
</label>
<div>
    <input type="file" multiple placeholder="选择要上传的文件" accept=".xlsx" (change)=selectedfiles($event)>
</div>

遍历文件列表并逐个上传的上传逻辑:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { environment } from 'src/environments/environment';
import { UploadserviceService } from '../uploadservice.service';
import { HttpResponse, HttpEventType } from '@angular/common/http';

@Component({
  selector: 'app-welcome',
  templateUrl: './welcome.component.html',
  styleUrls: ['./welcome.component.css']
})
export class WelcomeComponent implements OnInit {

  name = '';
  selectedxlfiles: FileList;
  url = environment.url;
  result: any;
  currentfile: File;
  fileandinstancekeyobj: any = {};

  constructor(private router: ActivatedRoute, private http: HttpClient, private uploadservice: UploadserviceService) { }

  ngOnInit(): void {
    this.name = this.router.snapshot.params['name'];
  }

  selectedfiles(event) {
    this.selectedxlfiles = event.target.files;
    for (let i = 0; i < this.selectedxlfiles.length; i++) {
      console.log(this.selectedxlfiles[i]);
      this.currentfile = this.selectedxlfiles[i];
      this.uploadservice.uploadtoserver(this.currentfile).subscribe((res: any) => {
        console.log(res.body);
      });
    }
  }
}

逐个上传文件的服务调用逻辑:

import { Injectable } from '@angular/core';
import { HttpClient, HttpEvent, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
import { environment } from 'src/environments/environment';

@Injectable({
  providedIn: 'root'
})
export class UploadserviceService {

  constructor(private http: HttpClient) { }

  uploadtoserver(selectedfile: File): Observable<HttpEvent<{}>> {

    let url: string = environment.url + 'uploadfile';
    console.log(url);
    const data: FormData = new FormData();
    data.append('selectedfile', selectedfile);
    const newrequest = new HttpRequest('POST', url, data, {
      reportProgress: true,
      responseType: 'text'
    });

    return this.http.request(newrequest);
  }
}

逐个上传文件的Spring Boot控制器逻辑:

package com.example.demo;

import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.Map;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@CrossOrigin(origins = "http://localhost:4200")
@RestController
public class uploadController {
    Map<String, MultipartFile> filemap = new HashMap<String, MultipartFile>();

    @PostMapping("/uploadfile")
    public ResponseEntity<String> handlefileupload(@RequestParam("selectedfile") MultipartFile multifile) {
        String message = "";
        uploaddto dto = new uploaddto();
        try {
            message = "成功";
            System.out.println(multifile.getOriginalFilename());
            return ResponseEntity.status(HttpStatus.OK).body(message);
        } catch (Exception e) {
            e.printStackTrace();
            message = "失败";
            return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(message);
        }
    }
}

对于上传所有文件的逻辑和控制器部分,翻译保持不变,因为您的问题中已经提供了这些内容的翻译。请注意,代码翻译可能会有一些细微的格式差异,但逻辑保持不变。如果您有更多的问题或需要进一步的帮助,请随时提问。

英文:

Hi i am working on an angular+spring boot application I wrote a code i am able to upload multiple files by looping through a file list and sending one file at a time but when i am trying to send all files(filelist) at a single time i am unable to do so

html code

  &lt;label&gt;
    welcome {{name}}, welcome to new app.
&lt;/label&gt;
&lt;div&gt;
    &lt;input type=&quot;file&quot; multiple placeholder=&quot;Select Files to be upload&quot; accept=&quot;.xlsx&quot; (change)=selectedfiles($event)&gt;
&lt;/div&gt;

upload logic for traversing through a filellist and uploading one at a time

import { Component, OnInit } from &#39;@angular/core&#39;;
import { ActivatedRoute } from &#39;@angular/router&#39;;
import { HttpClient } from &#39;@angular/common/http&#39;;
import { environment } from &#39;src/environments/environment&#39;;
import {UploadserviceService} from &#39;../uploadservice.service&#39;;
import { HttpResponse, HttpEventType } from &#39;@angular/common/http&#39;;
@Component({
  selector: &#39;app-welcome&#39;,
  templateUrl: &#39;./welcome.component.html&#39;,
  styleUrls: [&#39;./welcome.component.css&#39;]
})
export class WelcomeComponent implements OnInit {

  name=&#39;&#39;;
  selectedxlfiles:FileList;
  url=environment.url;
  result:any;
  currentfile:File;
  fileandinstancekeyobj:any={};

  constructor(private router:ActivatedRoute,private http: HttpClient,private uploadservice:UploadserviceService) { }

  ngOnInit(): void {
    this.name=this.router.snapshot.params[&#39;name&#39;];
  }

  selectedfiles(event){

    this.selectedxlfiles=event.target.files;
    for(let i=0;i&lt;this.selectedxlfiles.length;i++){
      console.log(this.selectedxlfiles[i]);
      this.currentfile=this.selectedxlfiles[i];
      this.uploadservice.uploadtoserver(this.currentfile).subscribe((res:any)=&gt;{
        console.log(res.body);
      }); 
    }
  }

}

Servicecall logic for uploading one file at a time

import { Injectable } from &#39;@angular/core&#39;;
import { HttpClient, HttpEvent, HttpRequest } from &#39;@angular/common/http&#39;;
import { Observable } from &#39;rxjs&#39;;
import { environment } from &#39;src/environments/environment&#39;;

@Injectable({
  providedIn: &#39;root&#39;
})
export class UploadserviceService {

  constructor(private http:HttpClient) { }

  uploadtoserver(selectedfile:File): Observable&lt;HttpEvent&lt;{}&gt;&gt;{

    let url:string=environment.url+&#39;uploadfile&#39;;
    console.log(url);
    const data: FormData=new FormData();
    data.append(&#39;selectedfile&#39;, selectedfile);
    const newrequest=new HttpRequest(&#39;POST&#39;,url,data,{
      reportProgress: true,
      responseType: &#39;text&#39;
    });

    return this.http.request(newrequest);
    //return this.http.post(url,selectedfiles);
  }
}

spring-boot controller logic for one file at a time

package com.example.demo;

import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.Map;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@CrossOrigin(origins = &quot;http://localhost:4200&quot;)
@RestController
public class uploadController {
	Map&lt;String, MultipartFile&gt; filemap=new HashMap&lt;String, MultipartFile&gt;();
	
	@PostMapping(&quot;/uploadfile&quot;)
	public ResponseEntity&lt;String&gt; handlefileupload(@RequestParam(&quot;selectedfile&quot;) MultipartFile multifile){
		String message=&quot;&quot;;
		uploaddto dto=new uploaddto();
		try {
			message=&quot;succesfull&quot;;
			System.out.println(multifile.getOriginalFilename());
			return ResponseEntity.status(HttpStatus.OK).body(message);
		} catch (Exception e) {
			e.printStackTrace();
			message=&quot;failed&quot;;
			return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(message);
		}
		
	}

}

Uploading all file at once logic

import { Component, OnInit } from &#39;@angular/core&#39;;
import { ActivatedRoute } from &#39;@angular/router&#39;;
import { HttpClient } from &#39;@angular/common/http&#39;;
import { environment } from &#39;src/environments/environment&#39;;
import {UploadserviceService} from &#39;../uploadservice.service&#39;;
import { HttpResponse, HttpEventType } from &#39;@angular/common/http&#39;;
@Component({
  selector: &#39;app-welcome&#39;,
  templateUrl: &#39;./welcome.component.html&#39;,
  styleUrls: [&#39;./welcome.component.css&#39;]
})
export class WelcomeComponent implements OnInit {

  name=&#39;&#39;;
  selectedxlfiles:FileList;
  url=environment.url;
  result:any;
  currentfile:File;

  constructor(private router:ActivatedRoute,private http: HttpClient,private uploadservice:UploadserviceService) { }

  ngOnInit(): void {
    this.name=this.router.snapshot.params[&#39;name&#39;];
  }

  selectedfiles(event){

    this.selectedxlfiles=event.target.files;
      this.uploadservice.uploadtoserver(this.selectedxlfiles).subscribe((res:any)=&gt;{
        console.log(res.body);
      }); 
  }

}

Upload service for uploading all files at once

import { Injectable } from &#39;@angular/core&#39;;
import { HttpClient, HttpEvent, HttpRequest } from &#39;@angular/common/http&#39;;
import { Observable } from &#39;rxjs&#39;;
import { environment } from &#39;src/environments/environment&#39;;

@Injectable({
  providedIn: &#39;root&#39;
})
export class UploadserviceService {

  constructor(private http:HttpClient) { }

  uploadtoserver(selectedfiles:FileList): Observable&lt;HttpEvent&lt;{}&gt;&gt;{

    let url:string=environment.url+&#39;uploadfile&#39;;
    console.log(url);
    const data: FormData=new FormData();
    data.append(&#39;selectedfiles&#39;, selectedfiles);
    const newrequest=new HttpRequest(&#39;POST&#39;,url,data,{
      reportProgress: true,
      responseType: &#39;text&#39;
    });

    return this.http.request(newrequest);
  }
}

spring-boot controller for uploading all files at once (getting error)

package com.example.demo;

import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.Map;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@CrossOrigin(origins = &quot;http://localhost:4200&quot;)
@RestController
public class uploadController {
	Map&lt;String, MultipartFile&gt; filemap=new HashMap&lt;String, MultipartFile&gt;();
	
	@PostMapping(&quot;/uploadfile&quot;)
	public ResponseEntity&lt;String&gt; handlefileupload(@RequestParam(&quot;selectedfiles&quot;) MultipartFile[] multifile){
		String message=&quot;&quot;;
		try {
			message=&quot;succesfull&quot;;
            for(int i=0;i&lt;multifile.length;i++){
			System.out.println(multifile[i].getOriginalFilename());
             }
			return ResponseEntity.status(HttpStatus.OK).body(message);
		} catch (Exception e) {
			e.printStackTrace();
			message=&quot;failed&quot;;
			return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(message);
		}
		
	}

}

CAn anyone suggest what's going wrong how can i correct my program so that all files can be uploaded at once and what approach would be more effecient for uploading a file i.e looping through file list or sending whole filelist at a go, Thanks in advance

error that igot

2020-09-21 00:38:24.114 ERROR 11348 --- [nio-5200-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Current request is not a multipart request] with root cause

org.springframework.web.multipart.MultipartException: Current request is not a multipart request
at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:196) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:114) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:167) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:652) ~[tomcat-embed-core-9.0.38.jar:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.38.jar:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.38.jar:9.0.38]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at java.base/java.lang.Thread.run(Thread.java:830) ~[na:na]

答案1

得分: 2

错误

您试图在控制器中获取MultipartFile[]参数,但请求不是多部分请求。因此会收到以下错误。

当前请求不是多部分请求

解决方法

请将每个文件逐个添加到FormData中,然后按以下方式将其发送到控制器,

uploadtoserver(selectedfiles: FileList): Observable<HttpEvent<{}>> {
    let url: string = environment.url + 'uploadfile';
    const data: FormData = new FormData();

    for (let i = 0; i < selectedfiles.length; i++) {
        data.append('selectedfiles', selectedfiles[i]);
    }

    const newrequest = new HttpRequest('POST', url, data, {
        reportProgress: true,
        responseType: 'text'
    });

    return this.http.request(newrequest);
}
英文:

Error

You try to get the MultipartFile[] param in controller, but request is not a multipart request. hence get the following error.

> Current request is not a multipart request

Solution

please append every file into FormData individually and then send it to controller as follows,

uploadtoserver(selectedfiles:FileList): Observable&lt;HttpEvent&lt;{}&gt;&gt;{

    let url:string=environment.url+&#39;uploadfile&#39;;
    const data: FormData=new FormData();

    for(let i=0;i&lt;selectedfiles.length;i++){
        data.append(&#39;selectedfiles&#39;, selectedfiles[i]);
    }

    const newrequest=new HttpRequest(&#39;POST&#39;,url,data,{
    reportProgress: true,
    responseType: &#39;text&#39;
    });

    return this.http.request(newrequest);
}

huangapple
  • 本文由 发表于 2020年9月21日 01:47:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/63981959.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定