簡體   English   中英

無法在 angular + spring boot 應用程序中一次上傳多個文件

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

嗨,我正在開發一個 angular+spring boot 應用程序,我寫了一個代碼,我可以通過循環遍歷文件列表並一次發送一個文件來上傳多個文件,但是當我嘗試一次發送所有文件(文件列表)時時間我不能這樣做

html代碼

  <label>
    welcome {{name}}, welcome to new app.
</label>
<div>
    <input type="file" multiple placeholder="Select Files to be upload" 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);
    //return this.http.post(url,selectedfiles);
  }
}

一次一個文件的 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="succesfull";
            System.out.println(multifile.getOriginalFilename());
            return ResponseEntity.status(HttpStatus.OK).body(message);
        } catch (Exception e) {
            e.printStackTrace();
            message="failed";
            return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(message);
        }
        
    }

}

一次上傳所有文件的邏輯

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;

  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;
      this.uploadservice.uploadtoserver(this.selectedxlfiles).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(selectedfiles:FileList): Observable<HttpEvent<{}>>{

    let url:string=environment.url+'uploadfile';
    console.log(url);
    const data: FormData=new FormData();
    data.append('selectedfiles', selectedfiles);
    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("selectedfiles") MultipartFile[] multifile){
        String message="";
        try {
            message="succesfull";
            for(int i=0;i<multifile.length;i++){
            System.out.println(multifile[i].getOriginalFilename());
             }
            return ResponseEntity.status(HttpStatus.OK).body(message);
        } catch (Exception e) {
            e.printStackTrace();
            message="failed";
            return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(message);
        }
        
    }

}

任何人都可以建議出了什么問題我如何更正我的程序以便可以一次上傳所有文件以及哪種方法可以更有效地上傳文件,即循環遍歷文件列表或一次性發送整個文件列表,提前致謝

我得到的錯誤

2020-09-21 00:38:24.114 ERROR 11348 --- [nio-5200-exec-5] oaccC[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] 在上下文中路徑[]拋出異常[請求處理失敗; 嵌套異常是 org.springframework.web.multipart.MultipartException: Current request is not a multipart request] 具有根本原因

org.springframework.web.multipart.MultipartException:當前請求不是 org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:196) ~[spring-web-5.2.9.RELEASE. jar:5.2.9.RELEASE] 在 org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:114) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE] org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE] 在 org.springframework.web.method.support .InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:167) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE] 在 org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java: 134)~[spring-web-5.2.9.RELEASE.jar:5.2.9.RE LEASE] 在 org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE] 在 org. springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE] 在 org.springframework.web.servlet .mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE] 在 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] 在 org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc- 5.2.9.RELEASE.jar:5.2.9.RELEASE] 在 org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9 .RELEASE] 在 org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE] 在 javax.servlet.http.HttpServlet .service(HttpServlet.java:652) ~[tomcat-embed-core-9.0.38.jar:4.0.FR] 在 org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring- webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE] 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.38.jar:4.0.FR ] 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.38.jar:9.0.38] 在 org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38] 在 org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.38.jar:9.0.38] 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar :9.0.38] 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38] 在 org.springframework.web.filter .RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE] 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE] 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38 .jar:9.0.38] 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38] 在 org.springframework.web .filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.9.RELEASE .jar:5.2.9.RELEASE] 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE] 在 org .apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar:9.0.38] 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain. java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38] 在 org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.9 .RELEASE.jar:5.2.9.RELEASE] 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar:9.0.38] 在 org.apache.catalina.core.ApplicationFilterChain.doFilter( ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38]在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.38.jar:9.0.38] 在 org.apache.catalina.core.StandardContextValve.invoke( StandardContextValve.java:97) ~[tomcat-embed-core-9.0.38.jar:9.0.38] 在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core -9.0.38.jar:9.0.38] 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.38.jar:9.0.38] 在 org .apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.38.jar:9.0.38] 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve. java:78) ~[tomcat-embed-core-9.0.38.jar:9.0.38] 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0 .38.jar:9.0.38] 在 org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-embed-core-9.0.38.jar:9.0.38] 在 org.apache .coyote.A bstractProcessorLight.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] 在 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) ~[tomcat-embed-core-9.0.38. jar:9.0.38] 在 org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.38.jar:9.0.38] 在 java.base/ java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na] 在 java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na] ] 在 org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.38.jar:9.0.38] 在 java.base/java.lang .Thread.run(Thread.java:830) ~[na:na]

錯誤

您嘗試在控制器中獲取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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM