简体   繁体   English

Spring Boot + Angular - MultipartException:当前请求不是多部分请求

[英]Spring Boot + Angular - MultipartException: Current request is not a multipart request

I'm having an issue using Angular 9 with Spring Boot for a simple application that uploads files along with data from the UI, in the same request.我在将 Angular 9 与 Spring Boot 一起用于一个简单的应用程序时遇到问题,该应用程序在同一请求中上传文件以及来自 UI 的数据。 Until I've implemented security with basic authentication, everything worked just fine.在我使用基本身份验证实现安全之前,一切正常。 Now, after I'm logged in and want to upload data, I get the following error:现在,在我登录并想要上传数据后,我收到以下错误:

org.springframework.web.multipart.MultipartException: Current request is not a multipart request

with the headers set up to Content-Type: 'multipart/form-data' and the Spring Controller using MultipartFile.将标头设置为Content-Type: 'multipart/form-data'和使用 MultipartFile 的 Spring Controller。 The strange thing is that the GET request works well, with the exception it's content type is application/json .奇怪的是 GET 请求运行良好,除了它的内容类型是application/json If I'm disabling the http-interceptor, the error becomes Access to XMLHttpRequest at 'http://localhost:8080/pacients' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource .如果我禁用了 http-interceptor,则错误变为Access to XMLHttpRequest at 'http://localhost:8080/pacients' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource I've also tried every workaround for handling CORS, both Angular and Spring related, with no success.我还尝试了所有处理 Angular 和 Spring 相关的 CORS 的解决方法,但没有成功。

Angular component for uploading the file:用于上传文件的 Angular 组件:

pacient: Pacient;
pacientForm: FormGroup = new PacientCreateFormBuilder().build();
submitPromise: Promise<Pacient>;

onSubmit() {
    if(this.pacientForm.valid) {
      const formData: FormData = new FormData();
      formData.append('pacientFile', <File>this.pacientForm.value.pacientFile);
      formData.append('newPacient', new Blob([JSON.stringify(this.pacientForm.value)], {type: "application/json"}));

      this.submitPromise = this.pacientCreateService.save(formData);
    } else {
      ValidationUtils.markFormAsDirty(this.pacientForm);
    }
  }

Angular service for upload:用于上传的 Angular 服务:

public save(formData: FormData) {
    var headers = new HttpHeaders(
      {
        'Content-Type': 'multipart/form-data',
        'Authorization': `Basic ${window.btoa(this.authService.username + ":" + this.authService.password)}`
      }
    );

    return this.httpClient.post<Pacient>("http://localhost:8080/pacient", formData, {headers: headers})
      .toPromise();
  }

Angular authentication service:角度认证服务:

authenticate(username: String, password: String) {
    return this.http.get(`http://localhost:8080/auth`, {
      headers: { authorization: this.createBasicAuthToken(username, password) }}).pipe(map((res) => {
      this.username = username;
      this.password = password;
      this.registerInSession(username, password);
    }));
  }

  createBasicAuthToken(username: String, password: String) {
    return 'Basic ' + window.btoa(username + ":" + password);
  }

  registerInSession(username, password) {
    sessionStorage.setItem(this.SESSION_KEY, username);
  }

Angular http-interceptor:角http拦截器:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (this.authService.isUserLoggedin() && req.url.indexOf('basicauth') === -1) {
      const request = req.clone({
        headers: new HttpHeaders({
          'Content-Type': 'application/json',
          'Authorization': `Basic ${window.btoa(this.authService.username + ":" + this.authService.password)}`
        })
      });
      return next.handle(request);
    }

    return next.handle(req);
  }

Spring Security config:弹簧安全配置:

@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        PasswordEncoder encoder = new StandardPasswordEncoder();

        auth
                .inMemoryAuthentication()
                .withUser("user")
                .password("password")
                .roles("USER")
                .and()
                .withUser("admin")
                .password("admin")
                .roles("USER", "ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().
                disable()
                .authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS, "/**")
                .permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .httpBasic();
    }

Spring Controller:弹簧控制器:

@PostMapping("/pacient")
    public Pacient create(@RequestPart("pacientFile") MultipartFile pacientFile, @RequestPart("newPacient") PacientDTO pacientDTO)

EDIT: If I'm using @PostMapping(value = "/pacient", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) in the Controller, the error is changing and appears only on browser's console and sais编辑:如果我在控制器中使用@PostMapping(value = "/pacient", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) ,则错误正在发生变化,并且仅出现在浏览器的控制台和 sais

Access to XMLHttpRequest at ' http://localhost:8080/pacient ' from origin ' http://localhost:4200 ' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.从源“ http://localhost:4200 ”访问“ http://localhost:8080/pacient ”的 XMLHttpRequest 已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头.

In order to get past it, I updated the Controller with @CrossOrigin(origins = {"http://localhost:4200"}) , added the following fields to the headers from service为了克服它,我用@CrossOrigin(origins = {"http://localhost:4200"})更新了控制器,将以下字段添加到服务的标题中

'Access-Control-Allow-Headers': `Content-Type`,
'Access-Control-Allow-Methods': `POST`,
'Access-Control-Allow-Origin': `*`

and also created a proxy.conf.json file with并且还创建了一个 proxy.conf.json 文件

{
  "/": {
    "target": "http://localhost:8080",
    "secure": false
  }
}

and added it to package.json, to start with "start": "ng serve --proxy-config proxy.conf.json" and added CORS configuration in my Spring Security config class并将其添加到 package.json,以"start": "ng serve --proxy-config proxy.conf.json"并在我的 Spring Security 配置类中添加 CORS 配置

@Bean
    CorsConfigurationSource corsConfigurationSource()
    {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

but still no luck...但仍然没有运气...

I just came across this issue myself and it was a really dumb error on my end but I thought I should share in case someone made the same mistake.我自己也遇到了这个问题,这对我来说是一个非常愚蠢的错误,但我想我应该分享一下,以防有人犯同样的错误。 I had just moved the file over to my VM and my user account did not have access to the file... Once I changed the permissions to the file, it worked as expected.我刚刚将文件移到了我的虚拟机上,而我的用户帐户无权访问该文件……一旦我更改了文件的权限,它就按预期工作了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 org.springframework.web.multipart.MultipartException:当前请求不是多部分请求 spring boot - org.springframework.web.multipart.MultipartException: Current request is not a multipart request spring boot MultipartException:当前请求不是多部分请求 - MultipartException: Current request is not a multipart request 当前请求不是多部分请求:Spring boot - Current request is not a multipart request : Spring boot Spring 启动:当前请求不是多部分请求 - Spring boot: Current request is not a multipart request “当前请求不是多部分请求” angularjs和spring boot - “the current request is not a multipart request” angularjs and spring boot Spring-boot rest api当前请求不是邮递员的多部分请求 - Spring-boot rest api current request is not multipart request with postman Spring 引导多部分 REST 端点在从 Postman 调用时给出“当前请求不是多部分请求” - Spring Boot Multipart REST endpoint gives 'Current request is not a multipart request' when called from Postman Spring / Jboss-当前请求不是多部分请求 - Spring/Jboss - Current Request is not multipart request 当前请求不是多部分请求 - Spring MVC - Current request is not a multipart request - Spring MVC 当前请求不是多部分请求 Spring Boot 和 Postman (Uploading json file plus extra field) - Current request is not a multipart request Spring Boot and Postman (Uploading json file plus extra field)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM