9
respostas

Erro 413 com arquivos acima de 1 MB

spring.servlet.multipart.max-file-size=128MB spring.servlet.multipart.max-request-size=128MB spring.servlet.multipart.enabled=true

e assim

spring.http.multipart.max-file-size = 20MB spring.http.multipart.max-request-size = 20MB

O que está de errado ?

Access to XMLHttpRequest at 'https://crud.movimentoneem.life/crud-api/api/carrousel/' from origin 'https://app.movimentoneem.life' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. polyfills-es2015.d868f9f91e9b61395ae1.js:1 POST https://crud.movimentoneem.life/crud-api/api/carrousel/ net::ERR_FAILED 413

Este erro da no console

Alguém já passou por isso ?

É configuração do Spring que está errada ?

Configuração no servidor ?

9 respostas

Oi Guilherme,

Você testou também com arquivos pequenos?

Pois pela mensagem de erro or problema não é em relação aos arquivos e sim porque na API está faltando a configuração do CORS, para permitir que a outra aplicação(https://app.movimentoneem.life/) possa disparar requisições ajax pra ela.

Você testou também com arquivos pequenos?

Rodrigo só acontecem com arquivos acima de 1 mega

@Override
    public void doFilter(final ServletRequest req, final ServletResponse resp, final FilterChain chain) throws IOException, ServletException {
        final HttpServletResponse response = (HttpServletResponse) resp;
        final HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "*");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
        response.setHeader("Access-Control-Expose-Headers", "Location");
        for (final Enumeration<?> e = request.getHeaderNames(); e.hasMoreElements();) {
            final String nextHeaderName = (String) e.nextElement();
            final String headerValue = request.getHeader(nextHeaderName);
            log.info("nextHeaderName: " + nextHeaderName);
            log.info("headerValue: " + headerValue);
        }
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, response);
        }
    }

Log

2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                nextHeaderName: x-forwarded-for
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                headerValue: 191.185.125.215
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                nextHeaderName: host
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                headerValue: xxxxxx
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                nextHeaderName: connection
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                headerValue: close
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                nextHeaderName: content-length
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                headerValue: 228438
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                nextHeaderName: sec-ch-ua
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                headerValue: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                nextHeaderName: accept
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                headerValue: application/json, text/plain, */*
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                nextHeaderName: content-type
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                headerValue: multipart/form-data; boundary=----WebKitFormBoundaryBG5jKKXk4qGIDqYQ
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                nextHeaderName: authorization
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                headerValue: bearer 9e02166b-5c74-45ec-83be-9b4004029f75
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                nextHeaderName: sec-ch-ua-mobile
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                headerValue: ?0
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                nextHeaderName: user-agent
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                headerValue: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                nextHeaderName: sec-ch-ua-platform
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                headerValue: "Windows"
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                nextHeaderName: origin
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                headerValue: 
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                nextHeaderName: sec-fetch-site
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                headerValue: same-site
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                nextHeaderName: sec-fetch-mode
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                headerValue: cors
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                nextHeaderName: sec-fetch-dest
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                headerValue: empty
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                nextHeaderName: referer
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                headerValue: https://app.movimentoneem.life/
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                nextHeaderName: accept-encoding
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                headerValue: gzip, deflate, br
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                nextHeaderName: accept-language
2021-12-13 09:38:37 [http-nio-9103-exec-1] INFO  - b.c.g.g.crud.config.SmpleCORSFilter -
                headerValue: pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7,fr;q=0.6

Salvar do angular

async salvar(): Promise<void> {
  let httpReturn: any;

  try {
    const dto = "dto";
    const filesMultipartFormParam = "file";
    const formData: FormData = new FormData();
    const blob: Blob = new Blob([JSON.stringify(this.entidade)], {
      type: "application/json",
    });

    formData.append(dto, blob);

    if (this.arquivos !== undefined && this.arquivos !== null) {
      for (let i = 0; i < this.arquivos.length; i++) {
        formData.append(filesMultipartFormParam, this.arquivos[i]);
      }
    }

    if (this.formGroup.value.idString) {
      httpReturn = await this.http.put(
        this.environmentBackend + API + this.urlBase + "/" + this.formGroup.value.idString + "/",
        formData
      ).toPromise();
    } else {
      httpReturn = await this.http.post(
        this.environmentBackend + API + this.urlBase + "/", formData
      ).toPromise();
    }

    this.toastrService.success(httpReturn["texto"]);
    this.voltar();
  } catch (error: any) {
    this.erroSalvar = true;
    this.errorServiceS.error(error);
  }
}

Do java

@ApiOperation("Cadastrar produto")
@PostMapping(consumes = MULTIPART_FORM_DATA_VALUE, produces = APPLICATION_JSON_VALUE)
public ResponseEntity<?> inserir(
  @Valid @RequestPart final ProdutoFormDTO dto, 
  final MultipartFile file, 
  @ApiIgnore final Principal principal
) {
  try {
    service.salvar(dto, null, principal, file);
    return mensagemSalvar();
  } catch (final GeralException e) {
    return erroExceptionComRegra(e, ENTIDADE);
  } catch (final Exception e) {
    return excecaoGeralSalvar(e, ERROR, ENTIDADE, ENTIDADE);
  }
}

Entendi,

Talvez o problema seja no seu método inserir do Java. Acredito que a anotação @RequestPart deveria marcar o parâmetro file, ao invés do parâmetro dto:

@ApiOperation("Cadastrar produto")
@PostMapping(consumes = MULTIPART_FORM_DATA_VALUE, produces = APPLICATION_JSON_VALUE)
public ResponseEntity<?> inserir(@Valid final ProdutoFormDTO dto, @RequestPart final MultipartFile file, @ApiIgnore final Principal principal) {
    try {
        service.salvar(dto, null, principal, file);
        return mensagemSalvar();
    } catch (final GeralException e) {
        return erroExceptionComRegra(e, ENTIDADE);
    } catch (final Exception e) {
        return excecaoGeralSalvar(e, ERROR, ENTIDADE, ENTIDADE);
    }
}

Veja se resolve.

Tentei assim

@ApiOperation("Cadastrar produto")
@PostMapping(consumes = MULTIPART_FORM_DATA_VALUE, produces = APPLICATION_JSON_VALUE)
public ResponseEntity<?> inserir(@Valid final ProdutoFormDTO dto, @RequestPart final MultipartFile file, @ApiIgnore final Principal principal) {
    try {
        service.salvar(dto, null, principal, file);
        return mensagemSalvar();
    } catch (final GeralException e) {
        return erroExceptionComRegra(e, ENTIDADE);
    } catch (final Exception e) {
        return excecaoGeralSalvar(e, ERROR, ENTIDADE, ENTIDADE);
    }
}

assim

@ApiOperation("Cadastrar produto")
@PostMapping(consumes = MULTIPART_FORM_DATA_VALUE, produces = APPLICATION_JSON_VALUE)
public ResponseEntity<?> inserir(@Valid @RequestPart final ProdutoFormDTO dto, @RequestPart final MultipartFile file, @ApiIgnore final Principal principal) {
    try {
        service.salvar(dto, null, principal, file);
        return mensagemSalvar();
    } catch (final GeralException e) {
        return erroExceptionComRegra(e, ENTIDADE);
    } catch (final Exception e) {
        return excecaoGeralSalvar(e, ERROR, ENTIDADE, ENTIDADE);
    }
}

Estranho que localhost e no ambiente de homologação funcionam

No ambiente de produção não

Arquivos abaixo de 1Mega funciona

Outra sugestão seria testar substituindo a anotação @RequestPart por @RequestParam("file", required = false)