繁体   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