Alterar nome do arquivo MultipartFile - resolvido

Recebo um arquivo via MultipartFile.

resource

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

service

@Transactional(propagation = NEVER)
public void salvar(
  final Biblioteca entidade, 
  final Collection<MultipartFile> files, 
  final SimNaoEnum principal, 
  final SimNaoEnum normal
) {
  files.forEach(file -> {
    try {
      final ImageIcon imageIcon = validarImagem(file, "Imagem da biblioteca", "5", 
        TAMANHO, true, HEIGHT_VALIDAR, WIDTH_VALIDAR, false);
      
      excluir(entidade, BibliotecaTipoArquivoEnum.IMAGEM, principal, normal);
      
      final BibliotecaArquivo entidadeArquivo = BibliotecaArquivo
        .builder()
        .biblioteca(entidade)
        .tipo(BibliotecaTipoArquivoEnum.IMAGEM)
        .principal(principal)
        .normal(normal)
        .build();
      
      preencher.model(entidadeArquivo, arquivoService.salvar(file, BIBLIOTECA, imageIcon.getIconHeight(), imageIcon.getIconWidth()));
      repository.save(entidadeArquivo);
    } catch (final IOException e) {
      throw new GeralException("Erro ao salvar imagem !");
    }
  });
}

Como altero nome dele antes de enviar para um servidor de arquivos?

Normalmente vc apenas irá usar MultipartFile para receber os dados do arquivo (nome e conteúdo). Depois disso, é melhor vc apenas manipular os bytes (conteúdo) e o nome do arquivo, ou seja, não usar mais a classe que chega no endpoint (MultipartFile).

O ideal é não repassar a classe MultipartFile para além da sua camada onde estão seus controllers, para não criar um alto acoplamento.

1 curtida

Sim pelo que entendi o MultipartFile, só lê as informações.

1 curtida

Isso. use ele apenas para receber os dados do arquivo mesmo. Não é bom ficar misturando as camadas. Quanto menos acoplado, melhor.

Por exemplo, vc pode ter uma classe chamada ArquivoBiblioteca com as propriedades nome (String) e conteudo (byte[]), e repassar ela para sua classe de serviço. Isso deixará seu código melhor para fazer manutenção e evolução.

E, dependendo da complexidade, vc ainda poderia ter ainda uma classe utilitaria que seria responsável por receber o MultipartFile e criar a instância de ArquivoBiblioteca, ex.: ArquivoBibliotecaFactory.

Enfim, há mais de uma forma de tratar isso, vc tem que analisar o que fica melhor no seu cenário.

1 curtida

Entendi

Para alterar o nome fiz assim, mas não funcionou

log.info(System.getProperty(“java.io.tmpdir”));
log.info(file.getName());
final File file = new File(System.getProperty(“java.io.tmpdir”) + “/” + multipartFile.getOriginalFilename() );

boolean bool = file.renameTo(new File(System.getProperty(“java.io.tmpdir”) + “/” + entidadeArquivo.getId() + “.” + multipartFile.getContentType()));
log.info(file.getName());
log.info("File renamed? " + bool);

A impressão do bool é sempre false

A impressão dos dois file.getName() são os mesmos

2021-12-11 12:20:32 - b.c.g.g.c.s.ProdutoArquivoService - cadeira galo.png
2021-12-11 12:20:32 - b.c.g.g.c.s.ProdutoArquivoService - cadeira galo.png
2021-12-11 12:20:32 - b.c.g.g.c.s.ProdutoArquivoService - File renamed? false

Em vez de renomear o arquivo, tenta criar um novo arquivo temporário (método createTempFile da classe File) e escreve os bytes do MultipartFile nesse arquivo temporario criado.

1 curtida

Tentei assim

mas dá o seguinte erro java.io.IOException: O sistema não pode encontrar o caminho especificado

try {
  final File file = new File(System.getProperty(SYSTEM).concat("/").concat(multipartFile.getOriginalFilename()));
  
  log.info(System.getProperty(SYSTEM));
  log.info(file.getName());
  
  final String nome = entidadeArquivo.getId().concat(".");
  final File novoArquivo = File.createTempFile("tmp", ".png", new File(System.getProperty(SYSTEM).concat("/").concat(nome)));
  log.info(novoArquivo.getName());
  
  salvar(arquivo, nome, publico);
  file.deleteOnExit();
} catch (final IOException e) {
  log.error(e.getMessage(), e);
  throw new GeralException("Erro ao salvar arquivo !");
}

Deixa entender melhor esse upload. O objetivo é vc salvar ele temporariamente para poder executar algo depois, ou vc já quer salvar ele no lugar definitivo?

Esse código, por exemplo:

File.createTempFile("teste", ".teste", null);`

vai criar um arquivo na pasta padrão de arquivos temporários na maquina onde o sistema estiver rodando. Na minha maquina, por exemplo, ele criou o arquivo teste8175458386483770293.teste na pasta /tmp/ (eu uso linux).

Porém, a pasta temporaria do sistema operacional é deletada a cada X dias (depende do sistema).

1 curtida

O objetivo é trocar o nome e inserir em um servidor de arquivo.

Não tem problema apagar a pasta temporária,

Como é o código que, de fato, grava o arquivo no servidor de arquivos?

1 curtida

Via SSH