Solucionado (ver solução)
Solucionado
(ver solução)
8
respostas

Erro 415 - Upload de arquivos

pom.xml

<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>

Angular, método de salvar

 getSalvar(arquivo : Arquivo, selectedFile: File) {
        let arquivoImportar = JSON.stringify(
          { 
            'files' : selectedFile,
            'idEntidade' : arquivo.entidade,
            'idEmpresa' : arquivo.empresa
          }
        );
        return this.http.post(this.userUrl + "/salvar", arquivoImportar, this.options)
          .map((response: Response) => {
            console.log("Salvar arquivos importados " + response.status);
           return response.json();
          }).catch((error:any) => 
            Observable.throw(error.json().error || 'Erro em salvar arquivos importados ' + console.log(this.options))
          );
      }

Método Java

    @RestController
    @RequestMapping(value = "/admin")
    public class ArquivoImportadoController {

        @CrossOrigin(origins = "*")
            @PostMapping(value = "/arquivoImportadoRecurso/salvar", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
            public RetornoJackson gravarBanco(
                    @RequestParam("files") MultipartFile files,
                    @RequestParam("idEntidade") Long idEntidade,
                    @RequestParam("idEmpresa") Long idEmpresa) {
                RetornoJackson retorno = new RetornoJackson();
                ArquivoImportadoEntity arquivoImportacao = new ArquivoImportadoEntity();
                try {
                    ArquivosEntity arquivo = new ArquivosEntity();
                    ArquivoArquivoEntity arquivoArquivo = new ArquivoArquivoEntity();
                    arquivo(files, arquivo);
                    arquivoImportacao(files, idEntidade, idEmpresa, arquivoImportacao,
                            arquivoArquivo);
                    arquivoArquivo(arquivoImportacao, arquivo, arquivoArquivo);
                    arquivoImportadoServico.validarCampos(arquivoImportacao);
                    Set<ArquivoArquivoEntity> arquivosArquivos = new LinkedHashSet<ArquivoArquivoEntity>();
                    arquivosArquivos.add(arquivoArquivo);
                    arquivo.setArquivosArquivos(arquivosArquivos);
                    arquivoImportacao.setArquivosArquivos(arquivosArquivos);
                    arquivoImportadoServico.salvar(arquivoImportacao);
                    retorno.setTipo(TipoRetornoMensagemEnum.SUCESSO);
                    retorno.setMensagem(Constantes.SALVA_SUCESSO);
                } catch (RegraNegocioException e) {
                    logger.error(Constantes.erroSalvar(arquivoImportacao.getClass()
                            .getName()), e);
                    retorno.setTipo(TipoRetornoMensagemEnum.ERRO);
                    retorno.setMensagem(e.getMessage());
                } catch (Exception e) {
                    logger.error(Constantes.erroSalvar(arquivoImportacao.getClass()
                            .getName()), e);
                    retorno.setTipo(TipoRetornoMensagemEnum.ERRO);
                    retorno.setMensagem(e.getMessage());
                }
                return retorno;
            }
    }

Erro no console do navegador.

https://gist.github.com/guilhermecostalopes/6fff67248fd8ac611fc12a54f9969537

Conforme imagem 1, entendo que o arquivo está chegando no método de salvar.

Imagem 1

Conforme imagem 2, o files não está sendo preenchido para enviar para o servidor.

Imagem 2

Estou achando estraho isto está ocorrendo, pois pelo que entendi, antes de enviar para o servidor, o files está vazio.

O que pode ser ?

8 respostas

Olha, posso estar equivocado, mas você não vai conseguir mandar o arquivo através de uma requisição cujo tipo é application/json. Você precisa de um multipart form data, como você bem especificou na sua api. O problema parece estar no angular... Vamos ver se alguém de angular consegue ajudar... Como é algo específico do seu projeto, talvez demore para alguém pegar.

Parte do angular headers:

myHeaders = new Headers({
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Headers': '*',
    'Access-Control-Allow-Credentials': '*',
    'Access-Control-Expose-Headers': 'x-access-token',
    'Content-Type': 'application/json; multipart/form-data',
    'enctype': 'application/json; multipart/form-data',
    'Authorization': 'Bearer ' +  localStorage.getItem('token')
  });

  options = new RequestOptions({
    headers: this.myHeaders
  });

  constructor(
    private http: Http,
    private authenticationService: AuthenticationService
  ) {}

Opa Guilherme, não manjo de angular, mas talvez essa lib te ajude => https://github.com/danialfarid/ng-file-upload

Vou analisar. valeu

Mas analisando o link que me passou, se não me engano é para o angular 1.

solução!

Consegui modificando a forma de enviar para o servidor, ficando assim:

 constructor(
        private httpClient: HttpClient,
        private http: Http,
        private authenticationService: AuthenticationService
      ) {}

    salvarArquivo(files: File, arquivo : Arquivo): Observable<HttpEvent<{}>> {
        let formdata: FormData = new FormData();
        formdata.append('files', files);
        formdata.append('idEntidade', String(arquivo.entidade));
        formdata.append('idEmpresa', String(arquivo.empresa));
        const req = new HttpRequest('POST',  this.userUrl + "/salvar", formdata, {
          reportProgress: true,
          responseType: 'text'
        });
        return this.httpClient.request(req);
      }

Mas não entendi, qual a diferença entre ser enviado pelo HttpClient e pelo Http ?

HttpClient e Http são duas formas que o Angular possui para trabalhar com operações Http para fazer AJAX. O HttpClient é a mais moderna e varia um pouco como trabalhar com ela :)

Na documentação você consegue ver mais a fundo as diferenças do Http pro HttpClient: https://angular.io/api/common/http/HttpClient

Para fazer o upload, esse vídeo tem um passo a passo bem bacana também:

Obrigado Mario.

Vou ver o vídeo e obrigado.