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.

zone.js:2935 POST http://localhost:8080/des-if-web/admin/arquivoImportadoRecurso/salvar 415 (Unsupported Media Type)
scheduleTask @ zone.js:2935
ZoneDelegate.scheduleTask @ zone.js:407
onScheduleTask @ zone.js:297
ZoneDelegate.scheduleTask @ zone.js:401
Zone.scheduleTask @ zone.js:232
Zone.scheduleMacroTask @ zone.js:255
scheduleMacroTaskWithCurrentZone @ zone.js:1092
(anonymous) @ zone.js:2967
proto.(anonymous function) @ zone.js:1372
(anonymous) @ http.js:1640
Observable._trySubscribe @ Observable.js:172
Observable.subscribe @ Observable.js:160
MapOperator.call @ map.js:57
Observable.subscribe @ Observable.js:157
CatchOperator.call @ catchError.js:80
Observable.subscribe @ Observable.js:157
MapOperator.call @ map.js:57
Observable.subscribe @ Observable.js:157
ArquivoFormComponent.onSubmit @ arquivo-form.component.ts:80
(anonymous) @ ArquivoFormComponent.html:1
handleEvent @ core.js:13547
callWithDebugContext @ core.js:15056
debugHandleEvent @ core.js:14643
dispatchEvent @ core.js:9962
(anonymous) @ core.js:12301
schedulerFn @ core.js:4343
SafeSubscriber.__tryOrUnsub @ Subscriber.js:243
SafeSubscriber.next @ Subscriber.js:190
Subscriber._next @ Subscriber.js:131
Subscriber.next @ Subscriber.js:95
Subject.next @ Subject.js:56
EventEmitter.emit @ core.js:4311
NgForm.onSubmit @ forms.js:5762
(anonymous) @ ArquivoFormComponent.html:1
handleEvent @ core.js:13547
callWithDebugContext @ core.js:15056
debugHandleEvent @ core.js:14643
dispatchEvent @ core.js:9962
(anonymous) @ core.js:10587
(anonymous) @ platform-browser.js:2628
ZoneDelegate.invokeTask @ zone.js:421
onInvokeTask @ core.js:4740
ZoneDelegate.invokeTask @ zone.js:420
Zone.runTask @ zone.js:188
ZoneTask.invokeTask @ zone.js:496
invokeTask @ zone.js:1517
globalZoneAwareCallback @ zone.js:1543
:4200/#/arquivo/novo:1 Failed to load http://localhost:8080/des-if-web/admin/arquivoImportadoRecurso/salvar: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 415.

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 ?

Ola,

Se não estou engando isso não funciona.

Você esta falando que ele deve consumir um json, mais o post é do tipo multi-part.

Uma solução seria:

Salvar o file dentro do temporário do servidor
retornar para o front o nome do arquivo
fazer o post dos dados junto com o nome do arquivo.
no back você busca o arquivo salvo no temporário e faz oque tem que fazer.

@campelo.m , entendi mais ou menos o que quis dizer.

O que você está dizendo, é para enviar o arquivo primeiro, deixar no server, em uma sessão.
Depois enviar os dois parâmetros.
Pegar o arquivo que está na sessão e assim salvar no banco de dados.

Isto ?

so a parte da sessão que nao.

Voce vai salvar o arquivo primeiro no temporary file com um nome hash. voce vai retorno esse nome hash para o front.

voce vai fazer o post dos dados que voce precisa mais o hash retornado pelo back.

no back voce vai de novo no temporary file e pesquisar pelo hash e fazer oque tem que fazer.

Pelo que entendi, deu o mesmo erro:

Fiz assim:

selectedFile, é o arquivo

Angular

getSalvar(arquivo : Arquivo, selectedFile: File) {
    return this.http.post(this.userUrl + "/salvar", selectedFile, 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))
      );
  }

Servidor

@CrossOrigin(origins = "*")
	@PostMapping(value = "/salvar", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
	public RetornoJackson gravarBanco(@RequestParam("files") MultipartFile files) {
}

e assim:

@CrossOrigin(origins = “*”)
@PostMapping(value = “/salvar”, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public RetornoJackson gravarBanco(@RequestParam(“files”) MultipartFile files) {
}

e assim:

@CrossOrigin(origins = “*”)
@PostMapping(value = “/salvar”)
public RetornoJackson gravarBanco(@RequestParam(“files”) MultipartFile files) {
}

headers no angular.

  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',
    'Content-Type': 'multipart/form-data',
    //'enctype': 'application/json; multipart/form-data',
    'Authorization': 'Bearer ' +  localStorage.getItem('token')
  });

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

Mas também não sei se fiz correto.

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 ?

OI tudo bom?

Guilherme estou precisando de sua ajuda, será que poderia me ajudar no meu projeto? Pois estou com dificuldade de implementar fileupload, por favor

@wladyband, posso sim.

O que necessita ?

poderia me adicionar no whatzap por favor 81 98 201 94 46.

por favor me adicione para conversamos