当前位置: 首页 > 知识库问答 >
问题:

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

邹丰羽
2023-03-14

我在使用Angular 9 with Spring Boot来实现一个简单的应用程序时遇到了一个问题,该应用程序可以在相同的请求中从UI上传文件和数据。在我用基本身份验证实现安全性之前,一切都很正常。现在,在我登录并想要上载数据后,出现以下错误:

<代码>组织。springframework。网状物多部分。MultipartException:当前请求不是多部分请求

标题设置为内容类型:“multipart/form data”,Spring控制器使用MultipartFile。奇怪的是,GET请求工作得很好,除了它的内容类型是应用程序/json之外。如果我禁用http拦截器,错误将变成访问位于的XMLHttpRequesthttp://localhost:8080/pacients'从原点'http://localhost:4200“”已被CORS策略阻止:请求的资源上不存在“Access Control Allow Origin”标头。我还尝试了处理CORS的各种解决方法,包括角度和Spring,但都没有成功。

用于上载文件的角度组件:

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);
    }
  }

上传的角度服务:

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();
  }

角度身份验证服务:

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);
  }

角超文本传输协议拦截器:

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配置:

@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控制器:

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

编辑:如果我在控制器中使用@PostMapping(value=“/pacient”,consumes={MediaType.MULTIPART\u FORM\u DATA\u value}),则错误正在更改,并且仅出现在浏览器控制台和sais上

访问位于'http://localhost:8080/pacient'从原点'http://localhost:4200“”已被CORS策略阻止:请求的资源上不存在“Access Control Allow Origin”标头。

为了克服它,我用CrossOrigin(origins={)更新了控制器http://localhost:4200“}),将以下字段添加到服务的标头中

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

还创建了一个代理。conf.json文件

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

并将其添加到包中。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;
    }

但还是没有运气...

共有1个答案

许庆
2023-03-14

我自己也遇到了这个问题,这是一个非常愚蠢的错误,但我想我应该分享一下,以防有人犯了同样的错误。我刚刚将文件移到我的虚拟机上,我的用户帐户没有访问该文件的权限。。。一旦我更改了该文件的权限,它就会按预期工作。

 类似资料:
  • 我试图使一个宁静的控制器上传文件。我看到了这一点,做了这个控制器: 然后我用邮递员发送了一份pdf: 但服务器崩溃,出现以下错误: 我再次找到了这个,并添加了一个文件 不幸的是,它仍然抱怨同样的错误。

  • 问题内容: 我试图使一个宁静的控制器来上传文件。我已经看到 了,并做了这个控制器: and then i used postman to send a pdf: But the server crashes with the error: 我再次找到了这个,并添加了一个bean.xml文件 不幸的是,它仍然抱怨相同的错误。 问题答案: 当您将邮递员用于多部分请求时,请不要 在页眉中指定自定义Con

  • Spring3.1。1.发布 我想上传两个文件的html格式,但我总是得到一个多部分请求异常。我在谷歌上搜索了很多,但没有找到正确的解决方案。 我的控制器: 我的. jsp页面: spring-serverlet.xml

  • 我正在尝试用angularjs上传文件,但有一个问题是“当前请求不是多部分请求”,我几乎尝试了谷歌的所有解决方案,但都没有解决我的问题,希望有人能回答我的问题,谢谢。 这是我的springMVC配置 这是角控制器 这是角服务 这是上传控制器 表单数据 -----WebKitFormBoundaryRZP8MUHA8LCBDZDN 内容-处置:表单-数据;name=“文件”;filename=“1.

  • 我有一个场景,在执行GET请求时,在从命令行调用jetty服务器时(mvn jetty:run),不返回JSON对象。有趣的是,当我使用Eclipse中安装的“Run Jetty Run”功能时,会返回JSON对象。 我在后端使用Spring rest控制器,带有以下注释: @RequestMapping(value=“/Customer”,method=RequestMethod.GET,hea

  • 我正在开发一个Spring API,我有一个接收MultipartFile作为参数的endpoint,但在正式生产环境中,我在某些情况下会收到以下错误: 组织。springframework。网状物util。NestedServletException:请求处理失败;嵌套异常为org。springframework。网状物多部分。MultipartException:无法解析多部分servlet请